[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: