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: