How gdb disables ASLR in Mac OS X Lion

This isn’t a rocket science post but more like some notes for future reference 🙂
Lion finally introduces full ASLR and gdb has the possibility to disable that feature when analyzing target binaries. A new gdb setting was added, “disable-aslr”, which allows to enable or disable this feature.

By default this feature appears to be enabled (I am just looking at gdb source code) and it’s set by the variable “disable_aslr_flag” configured at gdb/macosx/macosx-tdep.c source file. But this isn’t the place where the magic happens. That is located in gdb/fork-child.c file (well there’s a second version at macosx/macosx-nat-inferior.c).
A very rough draft of gdb workflow is something like this:

  1. Fork
  2. If we are the child process, drop privileges
  3. If we are the child process, use ptrace to “stop” the new process
  4. Exec the target
  5. Use again ptrace to resume the child
  6. Wait for breakpoint events

Step 4 in Apple’s gdb version tries to use posix_spawn instead of exec (or any of its variants) to launch the target. This allows to set some special attributes in the new process. One of the new attributes in Lion is “_POSIX_SPAWN_DISABLE_ASLR”. The name should be explicit about its purpose 🙂

The piece of code that sets it in gdb/fork-child.c is:

            if (disable_aslr_flag)
              ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
            retval = posix_spawnattr_setflags(&attr, ps_flags);

If posix_spawn fails gdb will then try to execvp the target. At the kernel side, this is dealt with in “posix_spawn()” at “bsd/kern/kern_exec.c”:

                 * Disable ASLR for the spawned process.
                if (px_sa.psa_flags & _POSIX_SPAWN_DISABLE_ASLR)
                        OSBitOrAtomic(P_DISABLE_ASLR, &p->p_flag);
                 * Forcibly disallow execution from data pages for the spawned process
                 * even if it would otherwise be permitted by the architecture default.
                if (px_sa.psa_flags & _POSIX_SPAWN_ALLOW_DATA_EXEC)
                        imgp->ip_flags |= IMGPF_ALLOW_DATA_EXEC;
         * Disable ASLR during image activation.  This occurs either if the
         * _POSIX_SPAWN_DISABLE_ASLR attribute was found above or if
         * P_DISABLE_ASLR was inherited from the parent process.
        if (p->p_flag & P_DISABLE_ASLR)
                imgp->ip_flags |= IMGPF_DISABLE_ASLR;

And that’s it! A new flag added, processes spawned with that flag active and bye bye ASLR 😉

8 thoughts on “How gdb disables ASLR in Mac OS X Lion

  1. Hello,

    I’m getting this message:

    This GDB was configured as “x86_64-apple-darwin”./Users/io/.gdbinit:2155: Error in sourced command file:
    This command cannot be used at the top level.

    Any thoughts? Thank you. 😉

      1. I’m getting the same when sourcing gdb with gdbinit on Lion. Looks like it doesn’t like the use of “end” to end the commands followed by the “end” to finish the define at line 2155.

        1. It’s another Apple’s gdb bug. It doesn’t like the “commands” command to be issued inside a define. When it detects the “end” of the “commands” it will immediatly close the definition, so the “define” will never be completed.
          This works perfectly in Linux so the bug was patched somewhere. Time to look at changelogs…

  2. I was getting the error using gdbinit742 upon issuing the ‘gdb’ command from terminal. I switched back to 7.41 and no longer get the error message. I’m using your version of gdb-i386-apple-darwin on a Mac Pro running 10.6.8 [x64], so I’m guessing that I need a different version of gdb-darwin that resides in /Developer/usr/libexec/gdb | or is gdb742 specifically meant to be used with Lion only?

    I realized after I posted my earlier comment that it should have been under your gdb742 release announcement; although I was half asleep at the time (like now), so sorry for any confusion. I’ll check in tomorrow to see what you have to say.

    ~ Regards

Leave a Reply

Your email address will not be published. Required fields are marked *