[lkml]   [2002]   [Feb]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    SubjectPATCH: Re: BUG: PTRACE_POKETEXT modifies memory in related processes
    > > I believe I have found a bug in recent 2.4 linux kernels (at least 2.4.17)
    > > running on x86 related to using ptrace to modify a processes memory. From
    [snip incorrect guess at cause of problem]
    > I don't think you're correctly understanding the circumstances. Are
    > you setting the breakpoint after they fork (seems unlikely, given this
    > test case - not much time to do so)? Otherwise, the breakpoint is
    > simply being carried over by your forking. Why you see it now and did
    > not before I don't know.
    Actually I do understand the circumstances. I am setting the
    breakpoint _AFTER_ the fork, when the parent and the child should exist in
    different memory spaces.

    > Basically, GDB on Linux does not support fork very well. It doesn't
    > show up terribly often, because exec() clears breakpoints.
    You are right on that, GDB sucks when debugging forks, which is
    why I have written my own debugger that can correctly handle forks. This
    is why I've come across this problem. Basically I detect a fork, do some
    magic, catch the child process before it continues to run and attach to
    it. Then I remove all the breakpoints from the child that were in the
    parent. The problem is that in 2.4.17 when I remove the breakpoints from
    the child they are also removed from the parent. I do know what I'm
    talking about here, I'm not trying to remove the breakpoints before the
    fork system call, it is after the fork system call (I actually remove the
    breakpoints after the fork library call has returned), and the bug is
    related to COW because I figured out exactly what's wrong and here's a
    patch that fixes it:

    --- ptrace.c.orig Fri Feb 1 20:17:18 2002
    +++ ptrace.c Fri Feb 1 19:54:58 2002
    @@ -148,16 +148,16 @@
    int bytes, ret, offset;
    void *maddr;

    - ret = get_user_pages(current, mm, addr, 1,
    - write, 1, &page, &vma);
    - if (ret <= 0)
    - break;
    bytes = len;
    offset = addr & (PAGE_SIZE-1);
    if (bytes > PAGE_SIZE-offset)
    bytes = PAGE_SIZE-offset;

    + ret = get_user_pages(current, mm, addr, 1,
    + write, 1, &page, &vma);
    + if (ret <= 0)
    + break;
    flush_cache_page(vma, addr);

    maddr = kmap(page);
    @@ -173,6 +173,7 @@
    len -= bytes;
    buf += bytes;
    + addr += bytes;

    Basically the kernel was calling get_user_pages on the same address, even
    as it moved through different addresses in memory. I have tested this
    change on my own 2.4.17 kernel and it now works correctly.


    Nathan Field Root is not something to be shared with strangers.
    "The nice thing about standards is that there's so many to choose from."
    -- Andrew S. Tanenbaum

    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    More majordomo info at
    Please read the FAQ at

     \ /
      Last update: 2005-03-22 13:23    [W:0.030 / U:63.008 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site