Bug#159633: strncpy on alpha/libc broken

2002-09-08 Thread Herbert Xu

On Wed, Sep 04, 2002 at 06:33:18PM +, Adam Heath wrote:
 package: libc6.1
 version: 2.2.5-11.1
 severity: serious
 
 On lully, I have a repeatable segfault being caused by strncpy(which calls
 __stxncpy).

Here is a patch which should solve this problem.  It still needs to be
analysed for scheduling.

I don't buy the serious severity though since all it does is cross
a page boundary in very rare circumstances.  I know it's rare because
this code has been around for at least five years in both Linux and
glibc, yet no one has reported this before.
-- 
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email:  Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


--- stxncpy.S   2001-07-24 03:55:20.0 +1000
+++ /home/gondolin/herbert/stxncpy.S2002-09-08 19:23:45.0 +1000
@@ -192,6 +192,7 @@
cmpbge  zero, t2, t7# e0: find nulls in second partial
addqa0, 8, a0   # .. e1 :
subqa2, 1, a2   # e0:
+   beq a2, $u_late_head_exit
bne t7, $u_late_head_exit   # .. e1 :
 
/* Finally, we've got all the stupid leading edge cases taken care
@@ -200,6 +201,7 @@
extql   t2, a1, t1  # e0: position hi-bits of lo word
ldq_u   t2, 8(a1)   # .. e1 : read next high-order source word
addqa1, 8, a1   # e0:
+   subqa2, 1, a2
cmpbge  zero, t2, t7# e1 (stall)
beq a2, $u_eoc  # e1:
bne t7, $u_eos  # e1:



Bug#159633: strncpy on alpha/libc broken

2002-09-08 Thread Herbert Xu

On Sun, Sep 08, 2002 at 11:57:36AM -0400, Daniel Jacobowitz wrote:
 
 This patch is incorrect, unfortunately:
 
 {standard input}:182: Error: symbol `xdr_bp_whoambp_wh' is already defined
 {standard input}:187: Error: symbol `$xdr_bp_whoambp_wh..ng' is already defined

This error doesn't seem related to stxncpy, but I'm doing a glibc build
now to see if I can reproduce it.
 
 I'm not quite sure why your patch doesn't work but I think that
 $u_late_head_exit is the wrong exit point... and I'm not sure why the

u_late_head_exit is the right exit point for that place since it also
deals with end-of-count by oring t7 with t10.

 extra subtract was needed.  I was testing a branch to $u_eocfin but
 that isn't right either...

Without the extra subtract, the load in the loop may cause a SEGV...
Try strncpy(buf, page + 8169, 20).

I've got a better patch in terms of scheduling now.

As to sending it upstream, I'd simply send it to Richard Henderson
as he is the author of that file which is in both Linux and glibc.
-- 
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email:  Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


--- stxncpy.S   2001-07-24 03:55:20.0 +1000
+++ /home/gondolin/herbert/stxncpy.S2002-09-08 22:22:07.0 +1000
@@ -189,10 +189,11 @@
mskql   t6, a1, t6  # e0:   already seen
stq_u   t0, 0(a0)   # e0: store first output word
or  t6, t2, t2  # .. e1 :
+   addqa0, 8, a0   # e0:
+   subqa2, 1, a2   # .. e1 :
cmpbge  zero, t2, t7# e0: find nulls in second partial
-   addqa0, 8, a0   # .. e1 :
-   subqa2, 1, a2   # e0:
-   bne t7, $u_late_head_exit   # .. e1 :
+   beq a2, $u_late_head_exit   # .. e1 :
+   bne t7, $u_late_head_exit   # e1:
 
/* Finally, we've got all the stupid leading edge cases taken care
   of and we can set up to enter the main loop.  */
@@ -200,8 +201,9 @@
extql   t2, a1, t1  # e0: position hi-bits of lo word
ldq_u   t2, 8(a1)   # .. e1 : read next high-order source word
addqa1, 8, a1   # e0:
-   cmpbge  zero, t2, t7# e1 (stall)
-   beq a2, $u_eoc  # e1:
+   subqa2, 1, a2   # .. e1 :
+   cmpbge  zero, t2, t7# e0:
+   beq a2, $u_eoc  # .. e1 :
bne t7, $u_eos  # e1:
 
/* Unaligned copy main loop.  In order to avoid reading too much,



Bug#159633: strncpy on alpha/libc broken

2002-09-08 Thread Herbert Xu

On Mon, Sep 09, 2002 at 07:34:31AM +1000, herbert wrote:
 On Sun, Sep 08, 2002 at 11:57:36AM -0400, Daniel Jacobowitz wrote:
  
  This patch is incorrect, unfortunately:
  
  {standard input}:182: Error: symbol `xdr_bp_whoambp_wh' is already defined
  {standard input}:187: Error: symbol `$xdr_bp_whoambp_wh..ng' is already defined
 
 This error doesn't seem related to stxncpy, but I'm doing a glibc build
 now to see if I can reproduce it.

I've just built libc6.1 on lully with my new patch and it seems to
work fine.
-- 
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email:  Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Bug#159633: strncpy on alpha/libc broken

2002-09-04 Thread Adam Heath

package: libc6.1
version: 2.2.5-11.1
severity: serious

On lully, I have a repeatable segfault being caused by strncpy(which calls
__stxncpy).

dpkg calls strncpy to copy data from it's mmap'd buffer, into a tmp var, for
moving around.  mmap on alpha aligns the end of the data segment with a page
boundary.  Depending on the alignment of the source address passed to strncpy,
a segfault will occur inside the above function.

My guess is this is due to an optimization, trying to copy ints/words around,
instead of pure bytes.

Substituting memcpy or a for loop, allows the dpkg code to work.  This shows
that the addresses and the length are both valid, and don't step into unknown
memory.

I have dpkg compiled on lully, and it doesn't require root to see the
bug(--admindir is enough).  If you need help reproducing this, then just
respond.

In fact, here's a c program that shows the bug.  Compile with CFLAGS=-g(of
course).

==
#include stdio.h
#include stdlib.h
#include unistd.h
#include sys/mman.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include string.h

#define LENGTH 12
#define TRAILING 2
int main(int argc, char **argv) {
int i, fd, pagesize;
char *data, *buf;
pagesize = getpagesize();
fd = open( /dev/zero, O_RDONLY );
if ( fd == -1 ) {
perror( open );
exit( 1 );
}
data = mmap( NULL, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0 );
if ( data == MAP_FAILED ) {
perror( mmap );
exit( 1 );
}
buf = (char *)malloc( LENGTH );
if ( buf == NULL ) {
perror( malloc );
exit( 1 );
}
for ( i = 0; i  pagesize; i++ )
data[ i ] = i % 256;
for ( i = 0; i  pagesize - LENGTH - TRAILING; i++ )
memcpy( buf, data + i, LENGTH );
for ( i = 0; i  pagesize - LENGTH - TRAILING; i++ )
strncpy( buf, data + i, LENGTH );
return 0;
}
==

The memcpy loop completes as expected.  The strncpy loop segfaults.  Here's
the gdb session info:

==
..
Program terminated with signal 11, Segmentation fault.
..
(gdb) bt
#0  0x20e21e0 in __stxncpy () from /lib/libc.so.6.1
#1  0x12a78 in main (argc=1, argv=0x11c88) at bug.c:36
(gdb) f 1
#1  0x12a78 in main (argc=1, argv=0x11c88) at bug.c:36
36  strncpy( buf, data + i, LENGTH );
(gdb) p i
$1 = 8177
==




-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]