Subject: strace on ARM: bad syscall at first SIGTRAP after execve
Package: strace
Version: 4.5.14-2
Severity: important
Tags: patch

*** Please type your report below this line ***
On ARM, strace attempts to decode a system call number for the first
SIGTRAP which follows a successful execve().  There isn't any system
call number, so strace tries to fetch garbage and digest it.
If the number is out of range, then strace gives up immediately.

There are two errors.  Register 12 has no role at all in
the system call interface, yet get_scno() decides what to do based on
regs.ARM_ip.  Also, for the first SIGTRAP after execve, the target address
(void *)(regs.ARM_pc - 4) need not be valid [it points to a hole if the
entry point is the first instruction on the lowest page of a PT_LOAD],
and the contents of the word before the entry point are unrestricted.

Here is a standalone testcase:
----- bogon.S
#include <asm/unistd.h>

        .long 0x55555555
_start: .globl _start
        mov r0,#0
        swi __NR_exit
-----
$ gcc -o bogon -nostdlib -nostartfiles bogon.S
$ strace ./bogon
execve("./bogon", ["./bogon"], [/* 19 vars */]) = 0
syscall: unknown syscall trap 0x55555555
$

Here is a patch to fix the problem:
--- ./syscall.c.orig    2006-01-12 02:18:53.000000000 -0800
+++ ./syscall.c 2007-09-05 14:23:38.000000000 -0700
@@ -1082,10 +1082,19 @@
        if (ptrace(PTRACE_GETREGS, pid, NULL, (void *)&regs) == -1)
                return -1;

+       if (tcp->flags & TCB_WAITEXECVE) {
+               if (tcp->flags & TCB_INSYSCALL)
+                       return 1;
+               /*
+                * This is the SIGTRAP after execve.
+                */
+               tcp->flags &= ~TCB_WAITEXECVE;
+               return 0;
+       }
        /*
         * We only need to grab the syscall number on syscall entry.
         */
-       if (regs.ARM_ip == 0) {
+       if (!(tcp->flags & TCB_INSYSCALL)) {
                /*
                 * Note: we only deal with only 32-bit CPUs here.
                 */
@@ -1103,10 +1112,6 @@
                        if (errno)
                                return -1;

-                       if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
-                               tcp->flags &= ~TCB_WAITEXECVE;
-                               return 0;
-                       }

                        if ((scno & 0x0ff00000) != 0x0f900000) {
                                fprintf(stderr, "syscall: unknown syscall trap 
0x%08lx\n",

-- System Information:
Debian Release: 4.0
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'stable')
Architecture: arm (armv5tel)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-3-ixp4xx
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages strace depends on:
ii  libc6                       2.3.6.ds1-13 GNU C Library: Shared libraries

strace recommends no packages.

-- no debconf information

-- 
John Reiser, [EMAIL PROTECTED]



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

Reply via email to