lkml.org 
[lkml]   [2006]   [May]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectFwd: [BUG] 2.6.16 extra ptrace trap on syscall exit
    Date


    ---------- Forwarded Message ----------

    Subject: [BUG] 2.6.16 extra ptrace trap on syscall exit
    Date: Monday 22 May 2006 15:22
    From: Steven James <pyro@linuxlabs.com>
    To: Roland McGrath <roland@redhat.com>
    Cc: User-mode-linux-devel@lists.sourceforge.net, Blaisorblade
    <blaisorblade@yahoo.it>, Jeff Dike <jdike@addtoit.com>

    Greetings,

    While working on a syscall emulator similar in structure to
    user-mode-linux, I found that for many but not all system calls, the
    ptracing parent is notified of the system call exit twice on x86_64 hosts.

    This can be trivially demonstrated by running strace on a test program
    that makes a non-existant system call such as the attached ptrace_test.c
    (see output below)

    Further testing shows that the bug only occurs when ptracing a 64 bit
    process. 32 bit target processes ptrace fine.

    This problem also appears to crash user-mode-linux guest kernels running
    on x86_64.

    From Blaisorblade:
    >I have uml/64-bit (AMD64) not working on 2.6.16/64bit, while uml-32bit
    >works fine on it, and the same uml/64-bit binaries work fine on 2.6.15. I

    haven't

    >tracked it down fully, but could it be related? Possibly yes because I

    now

    >seem to recall you run 64-bit host. So you likely found our bug!

    I confirm the problem does not occur on the 2.6.15.7 kernel.

    strace ./ptrace_test on 2.6.16.16:
    strace ./ptrace_test
    execve("./ptrace_test", ["./ptrace_test"], [/* 24 vars */]) = 0
    uname({sys="Linux", node="prime", ...}) = 0
    brk(0) = 0x501000
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
    0x2b2cf0826000
    access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or
    directory)
    open("/etc/ld.so.cache", O_RDONLY) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=142523, ...}) = 0
    mmap(NULL, 142523, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2b2cf0827000
    close(3) = 0
    open("/lib64/tls/libc.so.6", O_RDONLY) = 3
    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\305\1\356"...,
    640) = 640
    lseek(3, 624, SEEK_SET) = 624
    read(3, "\4\0\0\0\20\0\0\0\1\0\0\0GNU\0\0\0\0\0\2\0\0\0\4\0\0\0"..., 32) =
    32
    fstat(3, {st_mode=S_IFREG|0755, st_size=1613968, ...}) = 0
    mmap(0x33ee000000, 2305992, PROT_READ|PROT_EXEC,
    MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x33ee000000
    mprotect(0x33ee12a000, 1085384, PROT_NONE) = 0
    mmap(0x33ee229000, 24576, PROT_READ|PROT_WRITE,
    MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x129000) = 0x33ee229000
    mmap(0x33ee22f000, 16328, PROT_READ|PROT_WRITE,
    MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x33ee22f000
    close(3) = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
    0x2b2cf084a000
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
    0x2b2cf084b000
    mprotect(0x33ee229000, 16384, PROT_READ) = 0
    mprotect(0x33edd14000, 4096, PROT_READ) = 0
    arch_prctl(0x1002, 0x2b2cf084ab00) = 0
    munmap(0x2b2cf0827000, 142523) = 0
    write(1, "Pyro was here!\n", 15Pyro was here!
    ) = 15
    write(1, "last write returned 15, (errno=0"..., 34last write returned 15,
    (errno=0)
    ) = 34
    syscall_500(0x1, 0x22, 0xffffffffffffffff, 0, 0x1, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = -1 (errno 38)
    syscall_500(0x1, 0x22, 0xffffffffffffffff, 0, 0x1, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = -1 (errno 38)
    inval(1) returned -1, (errno=38)
    exit_group(0, 0, 0x33ee065280, 0x2, 0x3c <unfinished ... exit status 0>
    =============================================================================
    =

    strace ./ptrac_test32 on 2.6.16.16:
    strace ./ptrace_test32
    execve("./ptrace_test32", ["./ptrace_test32"], [/* 24 vars */]) = 0
    [ Process PID=3538 runs in 32 bit mode. ]
    uname({sys="Linux", node="prime", ...}) = 0
    brk(0) = 0x804a000
    access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or
    directory)
    open("/etc/ld.so.cache", O_RDONLY) = 3
    fstat64(0x3, 0xffffbf18) = 0
    old_mmap(0x22cbb00000000, 8589934593, PROT_READ|PROT_WRITE, 0xf /* MAP_???
    */|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE|MAP_POPULATE|MAP_NONBLOCK|MAP_GROWSD
    OWN|MAP_DENYWRITE|MAP_EXECUTABLE|MAP_LOCKED|0xfffe06c0, 64768,
    0x1af3ef00000000) = 0xfffffffff7fcd000
    close(3) = 0
    open("/lib/tls/libc.so.6", O_RDONLY) = 3
    read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20\357"..., 512)
    = 512
    fstat64(0x3, 0xffffbfac) = 0
    old_mmap(0x100000000000, 146028888067,
    PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN|PROT_GROWSUP|0xfcfffff8, 0x4
    /* MAP_???
    */|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE|MAP_NONBLOCK|MAP_GROWSDOWN|MAP_DENYW
    RITE|MAP_LOCKED|0x47dc0680, 1205695736, 0x847dd0435) = 0xfffffffff7fcc000
    old_mmap(0x12acbc47dda000, 8804682956805, PROT_READ|PROT_WRITE, MAP_FILE,
    0, 0) = 0x47dda000
    mprotect(0x47efe000, 27836, PROT_NONE) = 0
    old_mmap(0x400047eff000, 8873402433539, PROT_READ|PROT_WRITE, MAP_FILE, 0,
    0) = 0x47eff000
    old_mmap(0x1cbc47f03000, 214748364803,
    PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN|PROT_GROWSUP|0xfcfffff8,
    MAP_FILE, 0, 0) = 0x47f03000
    close(3) = 0
    old_mmap(0x100000000000, 146028888067,
    PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN|PROT_GROWSUP|0xfcfffff8, 0x4
    /* MAP_???
    */|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE|MAP_NONBLOCK|MAP_GROWSDOWN|MAP_DENYW
    RITE|MAP_LOCKED|0x47dc0680, 2832, 0x2047dce4a2) = 0xfffffffff7fcb000
    mprotect(0x47eff000, 8192, PROT_READ) = 0
    mprotect(0x47dd6000, 4096, PROT_READ) = 0
    set_thread_area(0xffffc724) = 0
    munmap(0xf7fcd000, 142523) = 0
    write(1, "Pyro was here!\n", 15Pyro was here!
    ) = 15
    write(1, "last write returned 15, (errno=0"..., 34last write returned 15,
    (errno=0)
    ) = 34
    syscall_500(0x1, 0xffffc9c8, 0x80484fe, 0x80484fe, 0x1, 0xffffc5b0,
    0xffffc9c8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0) = -1 (errno 38)
    write(1, "inval(1) returned -1, (errno=38)"..., 33inval(1) returned -1,
    (errno=38)
    ) = 33
    exit_group(0) = ?
    =============================================================================

    and strace ./ptrace_test on 2.6.15.7:
    strace ./ptrace_test
    execve("./ptrace_test", ["./ptrace_test"], [/* 24 vars */]) = 0
    uname({sys="Linux", node="prime", ...}) = 0
    brk(0) = 0x501000
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
    0x2aaaaaaab000
    access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or
    directory)
    open("/etc/ld.so.cache", O_RDONLY) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=142523, ...}) = 0
    mmap(NULL, 142523, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2aaaaaaac000
    close(3) = 0
    open("/lib64/tls/libc.so.6", O_RDONLY) = 3
    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\305\1\356"...,
    640) = 640
    lseek(3, 624, SEEK_SET) = 624
    read(3, "\4\0\0\0\20\0\0\0\1\0\0\0GNU\0\0\0\0\0\2\0\0\0\4\0\0\0"..., 32) =
    32
    fstat(3, {st_mode=S_IFREG|0755, st_size=1613968, ...}) = 0
    mmap(0x33ee000000, 2305992, PROT_READ|PROT_EXEC,
    MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x33ee000000
    mprotect(0x33ee12a000, 1085384, PROT_NONE) = 0
    mmap(0x33ee229000, 24576, PROT_READ|PROT_WRITE,
    MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x129000) = 0x33ee229000
    mmap(0x33ee22f000, 16328, PROT_READ|PROT_WRITE,
    MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x33ee22f000
    close(3) = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
    0x2aaaaaacf000
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
    0x2aaaaaad0000
    mprotect(0x33ee229000, 16384, PROT_READ) = 0
    mprotect(0x33edd14000, 4096, PROT_READ) = 0
    arch_prctl(0x1002, 0x2aaaaaacfb00) = 0
    munmap(0x2aaaaaaac000, 142523) = 0
    write(1, "Pyro was here!\n", 15Pyro was here!
    ) = 15
    write(1, "last write returned 15, (errno=0"..., 34last write returned 15,
    (errno=0)
    ) = 34
    syscall_500(0x1, 0x22, 0x33ee0b8642, 0, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = -1 (errno 38)
    write(1, "inval(1) returned -1, (errno=38)"..., 33inval(1) returned -1,
    (errno=38)
    ) = 33
    exit_group(0, 0, 0x33ee065280, 0x2, 0x3c <unfinished ... exit status 0>
    ============================================================================

    G'day,
    sjames



    by Linux Labs International, Inc.
    Steven James, CTO

    55 Marietta Street
    Suite 1830
    Atlanta, Ga 30303
    866 824 9737 support

    -------------------------------------------------------

    --
    Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!".
    Paolo Giarrusso, aka Blaisorblade (Skype ID "PaoloGiarrusso", ICQ 215621894)
    http://www.user-mode-linux.org/~blaisorblade
    #include <stdio.h>
    #include <errno.h>
    #include <unistd.h>

    #include <linux/unistd.h>
    #define __NR_inval 500

    _syscall1(long, inval, long, val);

    int main(int argc, char *argv[]) {
    int ret;
    char *msg = "Pyro was here!\n";
    char buffer[1024];

    ret = write(1, msg, strlen(msg));
    ret = sprintf( buffer, "last write returned %d, (errno=%d)\n", ret, errno);
    write(1, buffer, ret);

    ret = inval(1);
    ret = sprintf( buffer, "inval(1) returned %d, (errno=%d)\n", ret, errno);
    write(1, buffer, ret);

    return 0;
    }
    \
     
     \ /
      Last update: 2006-05-22 16:43    [W:0.040 / U:119.652 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site