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

Bug#171550: [ia64] [patch] strncpy.S segfault patch



Package: glibc
Version: 2.3.1-5
Severity: important
Tags: patch

This is a slightly modified patch (from the one I forwarded upstream)
for strncpy.S on ia64.  It differs only in that it applies against our
2.3.1 tarball rather than cvs.

Please add to the list.

randolph
-- 
Randolph Chung
Debian GNU/Linux Developer, hppa/ia64 ports
http://www.tausq.org/
#! /bin/sh -e

# DP: Description: Fix recovery code in ia64 strncpy routine
# DP: Author: Kenneth W Chen <kenneth.w.chen@intel.com>
# DP: Upstream status: Pending
# DP: Status Details: Submitted to libc-alpha on Dec 2
# DP: Date: Mon, 02 Dec 2002 23:13:31 -0800

if [ $# -ne 2 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch) patch -d "$2" -f --no-backup-if-mismatch -p1 < $0;;
    -unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p1 < $0;;
    *)
	echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
	exit 1
esac
exit 0

# append the patch here and adjust the -p? flag in the patch calls.

2002-11-19  Kenneth W. Chen <kenneth.w.chen@intel.com>
	* sysdeps/ia64/strncpy.S: (strncpy) initialize ar.ec, 
          ec is not guaranteed to be zero upon function entry; 
          fix segfault in recovery 4 section when src length
          ends exactly at a page boundary, and there are no
          mapping after that page.

2002-12-02  Randolph Chung <tausq@debian.org>
	* string/bug-strncpy.c: test case for strncpy segfault
        * string/Makefile: add bug-strncpy test case

--- glibc/sysdeps/ia64/strncpy.S.orig	2002-09-30 15:02:45.000000000 -0700
+++ glibc/sysdeps/ia64/strncpy.S	2002-12-02 21:55:48.000000000 -0800
@@ -63,6 +63,7 @@
 	mov	saved_pr = pr           // save the predicate registers
 	.save ar.lc, saved_lc
 	mov 	saved_lc = ar.lc	// save the loop counter
+	mov	ar.ec = 0
 	.body
 	cmp.geu p6, p5 = 24, in2
 (p6)	br.cond.spnt .short_len
@@ -217,11 +218,13 @@
 (p5)	mov	r[0] = r0
 	br.cond.sptk .back2
 .recovery3:
-	add	tmp = -MEMLAT * 8, src ;;
+	add	tmp = -(MEMLAT + 1) * 8, src ;;
 	ld8	r[MEMLAT] = [tmp]
 	br.cond.sptk .back3
 .recovery4:
-	add	tmp = -(MEMLAT - 1) * 8, src ;;
-	ld8	r[MEMLAT - 1] = [tmp]
+	cmp.eq	p8,p9=0,len
+	add	tmp = -MEMLAT * 8, src ;;
+(p8)	mov	r[MEMLAT - 1] = r0
+(p9)	ld8	r[MEMLAT - 1] = [tmp]
 	br.cond.sptk .back4
 END(strncpy)

--- glibc/string/Makefile.orig	2002-12-02 22:26:22.000000000 -0800
+++ glibc/string/Makefile	2002-12-02 22:27:46.000000000 -0800
@@ -48,7 +48,7 @@
 tests		:= tester inl-tester noinl-tester testcopy test-ffs	\
 		   tst-strlen stratcliff tst-svc tst-inlcall		\
 		   bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap	\
-		   tst-strtok tst-strxfrm bug-strcoll1
+		   tst-strtok tst-strxfrm bug-strcoll1 bug-strncpy
 distribute	:= memcopy.h pagecopy.h tst-svc.expect
 
 
--- glibc/string/bug-strncpy.c	2002-12-02 22:27:32.000000000 -0800
+++ glibc/string/bug-strncpy.c	2002-12-02 22:27:32.000000000 -0800
@@ -0,0 +1,81 @@
+/* Test case from Kenneth W Chen <kenneth.w.chen@intel.com>; adapted
+ * for glibc by Randolph Chung <tausq@debian.org>
+ *
+ * Tests the case where the src length ends at a page boundary
+ * and the next page is not mapped
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/shm.h>
+#include <signal.h>
+
+#define MCPYSIZE 2048
+#define SHMSIZE (MCPYSIZE * sizeof(long))
+static int shmid = -1;
+static char* shmaddr;
+
+void sighandler(int sig)
+{
+    if (shmid != -1)
+    {
+        shmdt(shmaddr);
+        shmctl(shmid, IPC_RMID, NULL);
+    }
+
+    exit(1);
+}
+
+int main(int argc, char **argv)
+{
+    long buffer[MCPYSIZE];
+    int i, j, k, x;
+    char *src, *dst;
+    size_t len;
+
+    shmid = shmget(1, SHMSIZE, IPC_CREAT|SHM_R|SHM_W);
+    shmaddr = (char*) shmat(shmid, NULL, SHM_RND);
+
+    signal(SIGSEGV, sighandler);
+
+    for (i=0; i<SHMSIZE; i++)
+        shmaddr[i] = i;
+
+    dst = (char*) buffer;
+
+    for (k=1; k<1000; k+=1) {
+        for (i=0; i<8; i++) {
+            for (j=0; j<8; j++) {
+
+                src = (char*) shmaddr + SHMSIZE - k - i;
+                dst = (char*) buffer + j;
+                len  = k;
+
+                //	printf("dst %p src %p n %4d\n", dst, src, len);
+                strncpy(dst, src, len);
+
+                for (x=0; x<len; x++) {
+                    if (src[x] == 0) break;
+                    if ( dst[x] != src[x] ) {
+                        unsigned long * l_src = (unsigned long*) ((unsigned long) &src[x] & -8);
+                        unsigned long * l_dst = (unsigned long*) ((unsigned long) &dst[x] & -8);
+
+                        printf("error\t");
+                        printf("dst %p src %p n %4zd\n", dst, src, len);
+
+                        printf("%d: %x %x\n", x, dst[x], src[x]);
+
+                        printf("%d: %16lx %16lx\n", x, *l_dst, *l_src);
+                        exit(1);
+                    }
+                }
+            } /* for (j=0 ... */
+        } /* for (i=0 ... */
+    } /* for (k=0 ... */
+
+    shmdt(shmaddr);
+    shmctl(shmid, IPC_RMID, NULL);
+
+    return 0;
+}
+

Reply to: