r4654 - in glibc-package/trunk/debian: . debhelper.in local local/memcpy-wrapper sysdeps
Author: aurel32
Date: 2011-05-11 21:03:05 +0000 (Wed, 11 May 2011)
New Revision: 4654
Added:
glibc-package/trunk/debian/local/memcpy-wrapper/
glibc-package/trunk/debian/local/memcpy-wrapper/Makefile
glibc-package/trunk/debian/local/memcpy-wrapper/README
glibc-package/trunk/debian/local/memcpy-wrapper/memcpy-preload.c
Modified:
glibc-package/trunk/debian/changelog
glibc-package/trunk/debian/debhelper.in/libc.NEWS
glibc-package/trunk/debian/rules
glibc-package/trunk/debian/sysdeps/amd64.mk
Log:
* debian/local/memcpy-wrapper/*: on amd64, provide and build two wrappers
to workaround and debug memcpy() issues. Explain how to use them in
debian/debhelper.in/libc.NEWS.
Modified: glibc-package/trunk/debian/changelog
===================================================================
--- glibc-package/trunk/debian/changelog 2011-05-11 18:49:54 UTC (rev 4653)
+++ glibc-package/trunk/debian/changelog 2011-05-11 21:03:05 UTC (rev 4654)
@@ -16,6 +16,9 @@
getpagesize() on static binaries. Closes: #626379.
* sysdeps/sparc.mk, sysdeps/sparc64.mk: disable multiarch support.
Workarounds: #625607.
+ * debian/local/memcpy-wrapper/*: on amd64, provide and build two wrappers
+ to workaround and debug memcpy() issues. Explain how to use them in
+ debian/debhelper.in/libc.NEWS.
-- Aurelien Jarno <aurel32@debian.org> Wed, 04 May 2011 19:53:33 +0200
Modified: glibc-package/trunk/debian/debhelper.in/libc.NEWS
===================================================================
--- glibc-package/trunk/debian/debhelper.in/libc.NEWS 2011-05-11 18:49:54 UTC (rev 4653)
+++ glibc-package/trunk/debian/debhelper.in/libc.NEWS 2011-05-11 21:03:05 UTC (rev 4654)
@@ -1,3 +1,33 @@
+eglibc (2.13-3) unstable; urgency=low
+
+ Starting with version 2.13, eglibc provides an SSSE3 optimized version
+ of memcpy() on the amd64 architecture. This version might copy memory
+ backward in some conditions, which causes issues if the source and
+ destination overlap. memmove() should be used in such cases, but some
+ programs still wrongly use memcpy().
+
+ For this reason, on the amd64 architecture the Debian package provides
+ two wrappers which can be use to workaround and/or debug the issue:
+ - /usr/lib/libc/memcpy-preload.so simply replace all calls to memcpy()
+ by a call to memmove()
+ - /usr/lib/libc/memcpy-syslog-preload.so does the same, but in addition
+ logs (with rate limit) the issue to syslog, so that it can be
+ detected and fixed.
+
+ To use these wrapper on a single binary, the easiest way is to use the
+ LD_PRELOAD environment variable:
+ - LD_PRELOAD=/usr/lib/libc/memcpy-preload.so /path/to/binary
+ - LD_PRELOAD=/usr/lib/libc/memcpy-syslog-preload.so /path/to/binary
+
+ For system-wide usage, it is possible to add the path of one of the
+ wrapper to /etc/ld.so.preload.
+
+ For more details about the issue, please see:
+ http://bugs.debian.org/625521
+ http://sourceware.org/bugzilla/show_bug.cgi?id=12518
+
+ -- Aurelien Jarno <aurel32@debian.org> Wed, 11 May 2011 22:15:31 +0200
+
glibc (2.9-8) unstable; urgency=low
Starting with version 2.9-8, unified IPv4/IPv6 lookup have been enabled
Added: glibc-package/trunk/debian/local/memcpy-wrapper/Makefile
===================================================================
--- glibc-package/trunk/debian/local/memcpy-wrapper/Makefile (rev 0)
+++ glibc-package/trunk/debian/local/memcpy-wrapper/Makefile 2011-05-11 21:03:05 UTC (rev 4654)
@@ -0,0 +1,11 @@
+all: memcpy-preload.so memcpy-syslog-preload.so
+
+clean:
+ rm -f memcpy-preload.so memcpy-syslog-preload.so
+
+memcpy-preload.so: memcpy-preload.c
+ $(CC) -D_GNU_SOURCE -DNOLOG -O2 -Wall -fPIC -shared -o memcpy-preload.so memcpy-preload.c
+
+memcpy-syslog-preload.so: memcpy-preload.c
+ $(CC) -D_GNU_SOURCE -O2 -Wall -fPIC -shared -o memcpy-syslog-preload.so memcpy-preload.c
+
Added: glibc-package/trunk/debian/local/memcpy-wrapper/README
===================================================================
--- glibc-package/trunk/debian/local/memcpy-wrapper/README (rev 0)
+++ glibc-package/trunk/debian/local/memcpy-wrapper/README 2011-05-11 21:03:05 UTC (rev 4654)
@@ -0,0 +1,18 @@
+This small wrapper has for goal to workaround issues with some programs
+calling memcpy() with source and destination overlap, causing issues on
+recent GNU libc versions, which might copy memory backward on some
+x86-64 CPU. For more details, see
+ http://sourceware.org/bugzilla/show_bug.cgi?id=12518
+
+The wrapper is built in two versions, memcpy-preload.so for "production"
+usage, which just fix the wrong call by using memmove, and
+memcpy-syslog-preload.so for "debugging" purposes which also logs the
+issue through syslog (rate limited).
+
+To use them for a specific binary, you can use the LD_PRELOAD
+environment variable:
+ LD_PRELOAD=./memcpy-preload.so /path/to/binary
+ LD_PRELOAD=./memcpy-syslog-preload.so /path/to/binary
+
+For system-wide usage, it is possible to add this wrapper in
+/etc/ld.so.preload.
Added: glibc-package/trunk/debian/local/memcpy-wrapper/memcpy-preload.c
===================================================================
--- glibc-package/trunk/debian/local/memcpy-wrapper/memcpy-preload.c (rev 0)
+++ glibc-package/trunk/debian/local/memcpy-wrapper/memcpy-preload.c 2011-05-11 21:03:05 UTC (rev 4654)
@@ -0,0 +1,61 @@
+/* Copyright (C) 2011, Aurelien Jarno <aurelien@aurel32.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dlfcn.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/time.h>
+
+void *memcpy(void *dst, const void *src, size_t n)
+{
+#ifndef NOLOG
+ uintptr_t usrc, udst;
+
+ /* Convert to unsigned as arithmetic on pointer is undefined */
+ udst = (uintptr_t) dst;
+ usrc = (uintptr_t) src;
+
+ /* Check if source and destination overlap */
+ if (((udst < usrc) && ((udst + n) > usrc)) ||
+ ((usrc < udst) && ((usrc + n) > udst))) {
+
+ static time_t lastlog = -1;
+ struct timeval tv;
+
+ /* gettimeofday() is not expensive for the conditions we target in
+ * the Debian package (kernel >= 2.6.26, x86-64 architecture), this
+ * might need to be changed if this wrapper is later needed with
+ * different conditions */
+ gettimeofday(&tv, NULL);
+
+ /* Don't spam syslog, limit to (roughly) one log entry per second. */
+ if (tv.tv_sec > lastlog) {
+ lastlog = tv.tv_sec;
+ syslog(LOG_WARNING | LOG_USER,
+ "source and destination overlap in memcpy() at ip %p",
+ __builtin_return_address(0));
+ }
+ }
+#endif
+
+ /* Call memmove() instead of memcpy() */
+ return memmove(dst, src, n);
+}
+
Modified: glibc-package/trunk/debian/rules
===================================================================
--- glibc-package/trunk/debian/rules 2011-05-11 18:49:54 UTC (rev 4653)
+++ glibc-package/trunk/debian/rules 2011-05-11 21:03:05 UTC (rev 4654)
@@ -158,6 +158,7 @@
clean:: unpatch
make -C $(CURDIR)/linuxthreads/man clean
+ make -C $(CURDIR)/debian/local/memcpy-wrapper clean
rm -f $(CURDIR)/po/*.mo
rm -rf $(patsubst %,debian/tmp-%,$(EGLIBC_PASSES))
rm -rf $(build-tree)
Modified: glibc-package/trunk/debian/sysdeps/amd64.mk
===================================================================
--- glibc-package/trunk/debian/sysdeps/amd64.mk 2011-05-11 18:49:54 UTC (rev 4653)
+++ glibc-package/trunk/debian/sysdeps/amd64.mk 2011-05-11 21:03:05 UTC (rev 4654)
@@ -21,6 +21,17 @@
i386_slibdir = /lib32
i386_libdir = /usr/lib32
+define libc6_extra_pkg_install
+make -C debian/local/memcpy-wrapper
+install -m 755 -o root -g root -d debian/libc6/$(libdir)/libc
+install -m 755 -o root -g root \
+ debian/local/memcpy-wrapper/memcpy-preload.so \
+ debian/libc6/$(libdir)/libc
+install -m 755 -o root -g root \
+ debian/local/memcpy-wrapper/memcpy-syslog-preload.so \
+ debian/libc6/$(libdir)/libc
+endef
+
define libc6-dev-i386_extra_pkg_install
mkdir -p debian/libc6-dev-i386/usr/include/gnu
cp -af debian/tmp-i386/usr/include/i486-linux-gnu/gnu/stubs-32.h \
Reply to: