This is the mail archive of the libc-hacker@cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patches for bugs in ARM code...


I found a nasty bug in sysdeps/unix/sysv/linux/arm/socket.S.  We had a bug with
ping.  It was always printing the error `Socket operation on non-socket.`.  An
strace showed the recvfrom call was failing on restart after the signal was
handled.  Its parameters were garbage.  This is because the socket call never
modifies sp; it moves sp into ip and uses ip to push the args, so it never has
to clean up the stack.

This is nice as it saves one instruction, however the syscall is not an atomic
operation.  It can be interrupted if a signal occurs.  If the signal handler
uses any stack it trashes the socket call args, because according to it the next
available stack slot is pointed at by sp.  

Now for the really bad news.  mmap() suffers from the same bug.  Yuck!

1999-04-14 Scott Bambrough  <scottb@netwinder.org>

        * sysdeps/unix/sysv/linux/arm/socket.S: 
        Socket calls could not be restarted after being interrupted by 
	a signal.  The parameters on the stack were corrupted by the 
	signal handler.

        * sysdeps/unix/sysv/linux/arm/mmap.S: 
        mmap calls could not be restarted after being interrupted by 
	a signal.  The parameters on the stack were corrupted by the 
	signal handler.
Index: mmap.S
===================================================================
RCS file: /glibc/cvsfiles/libc/sysdeps/unix/sysv/linux/arm/mmap.S,v
retrieving revision 1.2
diff -r1.2 mmap.S
29,31c29,43
< 	mov	ip, sp
< 	stmdb	ip!, {a1-a4}
< 	mov	a1, ip
---
> 	/* This code previously moved sp into ip and stored the args using
> 	   stmdb ip!, {a1-a4}.  It did not modify sp, so the stack never had 
> 	   to be restored after the syscall completed.  It saved an 
> 	   instruction and meant no stack cleanup work was required.
> 
> 	   This will not work in the case of a mmap call being interrupted
> 	   by a signal.  If the signal handler uses any stack the arguments
> 	   to mmap will be trashed.  The results of a restart of mmap are
> 	   then unpredictable. */
> 
> 	/* store args on the stack */
> 	stmdb	sp!, {a1-a4}
> 
> 	/* do the syscall */
> 	mov	a1, sp
32a45,48
> 
> 	/* pop args off the stack. */
> 	add	sp, sp, #16
> 
Index: socket.S
===================================================================
RCS file: /glibc/cvsfiles/libc/sysdeps/unix/sysv/linux/arm/socket.S,v
retrieving revision 1.6
diff -r1.6 socket.S
38,43c38,50
< #define PUSHARGS_1	stmfd ip!, {a1}
< #define PUSHARGS_2	stmfd ip!, {a1, a2}
< #define PUSHARGS_3	stmfd ip!, {a1, a2, a3}
< #define PUSHARGS_4	stmfd ip!, {a1, a2, a3, a4}
< #define PUSHARGS_5	stmfd ip!, {a1, a2, a3, a4}	/* Caller has already pushed arg 5 */
< #define PUSHARGS_6	stmfd ip!, {a1, a2, a3, a4}
---
> #define PUSHARGS_1	stmfd sp!, {a1}
> #define PUSHARGS_2	stmfd sp!, {a1, a2}
> #define PUSHARGS_3	stmfd sp!, {a1, a2, a3}
> #define PUSHARGS_4	stmfd sp!, {a1, a2, a3, a4}
> #define PUSHARGS_5	stmfd sp!, {a1, a2, a3, a4}	/* Caller has already pushed arg 5 */
> #define PUSHARGS_6	stmfd sp!, {a1, a2, a3, a4}
> 
> #define POPARGS_1	add sp, sp, #4
> #define POPARGS_2	add sp, sp, #8
> #define POPARGS_3	add sp, sp, #12
> #define POPARGS_4	add sp, sp, #16
> #define POPARGS_5	add sp, sp, #16
> #define POPARGS_6	add sp, sp, #16 
50a58,67
> 	/* This code previously moved sp into ip and stored the args using
> 	   stmdb ip!, {a1-a4}.  It did not modify sp, so the stack never had 
> 	   to be restored after the syscall completed.  It saved an 
> 	   instruction and meant no stack cleanup work was required.
> 
> 	   This will not work in the case of a socket call being interrupted
> 	   by a signal.  If the signal handler uses any stack the arguments
> 	   to socket will be trashed.  The results of a restart of any
> 	   socket call are then unpredictable. */
> 
52d68
< 	mov ip, sp
57c73
< 	mov a2, ip
---
> 	mov a2, sp
58a75,77
> 
> 	/* Pop args off the stack */
> 	P(POPARGS_,NARGS)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]