Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLDB lies about --disable-aslr and leaves ASLR enabled on Linux #21032

Closed
chandlerc opened this issue Aug 14, 2014 · 15 comments
Closed

LLDB lies about --disable-aslr and leaves ASLR enabled on Linux #21032

chandlerc opened this issue Aug 14, 2014 · 15 comments
Labels
bugzilla Issues migrated from bugzilla lldb

Comments

@chandlerc
Copy link
Member

Bugzilla Link 20658
Resolution FIXED
Resolved on Aug 19, 2014 12:44
Version unspecified
OS Linux
CC @majnemer,@emaste,@jimingham,@rnk

Extended Description

A transcript follows:

% cat x.cpp
int main() {
int *ip = new int(42);
return *ip;
}
% nl x.cpp
1 int main() {
2 int *ip = new int(42);
3 return *ip;
4 }
% clang++ -g -o x x.cpp
% lldb -- ./x
Current executable set to './x' (x86_64).
(lldb) b x.cpp:3
Breakpoint 1: where = x`main + 43 at x.cpp:3, address = 0x000000000040065b
(lldb) process launch --disable-aslr
Process 7581 launching
Process 7581 launched: './x' (x86_64)
Process 7581 stopped

  • thread #​1: tid = 7581, , name = 'x'
    frame #​0:
    Process 7581 stopped
  • thread #​1: tid = 7581, 0x000000000040065b xmain + 43 at x.cpp:3, name = 'x', stop reason = breakpoint 1.1 frame #​0: 0x000000000040065b xmain + 43 at x.cpp:3
    1 int main() {
    2 int *ip = new int(42);
    -> 3 return *ip;
    4 }
    (lldb) p ip
    (int *) $0 = 0x0000000001ed9010
    (lldb) process launch --disable-aslr
    There is a running process, kill it and restart?: [Y/n] y
    Process 7581 exited with status = 0 (0x00000000)
    Process 15338 launching
    Process 15338 launched: './x' (x86_64)
    Process 15338 stopped
  • thread #​1: tid = 15338, 0x00007ff3b04432d0, name = 'x'
    frame #​0:
    Process 15338 stopped
  • thread #​1: tid = 15338, 0x000000000040065b xmain + 43 at x.cpp:3, name = 'x', stop reason = breakpoint 1.1 frame #​0: 0x000000000040065b xmain + 43 at x.cpp:3
    1 int main() {
    2 int *ip = new int(42);
    -> 3 return *ip;
    4 }
    (lldb) p ip
    (int *) $1 = 0x000000000234e010

Nope! Let's try GDB:

% gdb --args ./x
Reading symbols from ./x...done.
(gdb) b x.cpp:3
Breakpoint 1 at 0x40065b: file x.cpp, line 3.
(gdb) r
Starting program: /usr/local/google/home/chandlerc/tmp/x

Breakpoint 1, main () at x.cpp:3
3 return *ip;
(gdb) p ip
$1 = (int *) 0x403010
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /usr/local/google/home/chandlerc/tmp/x

Breakpoint 1, main () at x.cpp:3
3 return *ip;
(gdb) p ip
$2 = (int *) 0x403010

Yep. That's what I wanted.

Also, please make this the default and make the flag '--enable-aslr'. I really never, ever want my debugger to default to ASLR. I only want that when I'm chasing a bug which manifests in no other way.

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 14, 2014

Implementation note:

This link shows a response that indicates how to disable via shell execution:
https://stackoverflow.com/questions/5194666/disable-randomization-of-memory-addresses

So a shell wrapping the inferior with proper flags set is one way to go about it for per-process-level ASLR setting (rather than the whole-system kernel flag).

I'll look at getting the disable aslr support in after my next task wraps up.

As for making it the default, great thing to discuss on lldb-dev. At the very least I'm good with making it the default on Linux. If everyone else agrees, we can get it working as a global default.

-Todd

@emaste
Copy link
Member

emaste commented Aug 14, 2014

In my opinion it makes sense to universally default to --disable-aslr (or do so for all platforms except Mac, if there are legacy reasons to leave it as is there).

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 14, 2014

I'm fully behind pursuing that course - just want to discuss it to see if we (as you mentioned) might have legacy reasons for leaving it as is in at least some places. We might even be able to flip it wholesale, which would be great.

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 14, 2014

Not sure what's going on - I posted two emails (one from tfiala@google.com at roughly 7:45 AM PDT, and another from todd.fiala@gmail.com at roughly 9:45 AM PDT), and neither has hit the llvm.org archive site for lldb-dev yet. It's a discussion item for seeing if there's any reason not to disable ASLR by default (with possible reasons for why to do it and not do it as a discussion starter). That should show up soon if it hasn't already. I'm just not seeing either of them in the archive.

@rnk
Copy link
Collaborator

rnk commented Aug 14, 2014

FYI, disabling ASLR on Linux does really weird things to PIE binaries. Instead of loading at some random address in the shared library address range, they load at 0x5555..., or 1/3-ish of the userspace address space.

IIRC this affects MSan and TSan binaries, which are PIE by default these days. When you gdb such a binary, you need to disable the disabling of ASLR (blech). If you make this change to LLDB on Linux, you will need to do the same.

@rnk
Copy link
Collaborator

rnk commented Aug 14, 2014

FYI, disabling ASLR on Linux does really weird things to PIE binaries.
Instead of loading at some random address in the shared library address
range, they load at 0x5555..., or 1/3-ish of the userspace address space.

IIRC this affects MSan and TSan binaries, which are PIE by default these
days. When you gdb such a binary, you need to disable the disabling of ASLR
(blech). If you make this change to LLDB on Linux, you will need to do the
same.

I meant to link to the documentation for this:
http://clang.llvm.org/docs/MemorySanitizer.html#limitations

@jimingham
Copy link
Collaborator

Disabling ASLR is the default on the Mac, and has been since the OS X introduced it. I agree with Chandler, you never want ASLR on when debugging unless forced to by some odd circumstance.

In my opinion it makes sense to universally default to --disable-aslr (or do
so for all platforms except Mac, if there are legacy reasons to leave it as
is there).

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 14, 2014

Ah! That's a gotcha. From the limitations page, it looks like the user is expected to enable (disable the disable) of ASLR on gdb. So we're not talking about auto-detecting, simply having the user need to take that step when they initiate debugging with msan. Right?

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 14, 2014

Disabling ASLR is the default on the Mac, and has been since the OS X introduced it.

Okay, thanks Jim. This should be a no-brainer then to disable by default.

It simply looks like it (the lldb handling one way or another of ASLR) was never implemented for Linux (and probably anything else), so if the default was to "shut it off", that mechanism was likely ignored.

In any event, I'll have a look at this as soon as I finish what I'm currently tracking down.

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 14, 2014

(and probably anything else)

That is, anything else non-Apple.

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 15, 2014

More implementation notes:

For the Linux local debugging with llgs (not yet upstream), I'll be calling personality() to do this during a fork/sync/exec-style launch. See here:

https://stackoverflow.com/questions/1455904/how-to-disable-address-space-randomization-for-a-binary-on-linux

That code is not ready-enough yet, so in the meanwhile I'll work on an upstream solution that follows my earlier implementation note (i.e. wrap inferior launch in a shell if not already, call /usr/bin/setarch -R $SHELL to run the shell with ASLR disabled).

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 15, 2014

I'm probably going to do this as two check-ins - first one to just implement it for Linux. Second one, flip the orientation of the flag to --enable-aslr after double checking with the Apple folks.

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 16, 2014

Hah ok so I implemented this with an extra wrapped version of /usr/bin/setarch -R, but that has a few issues I would still need to resolve. But - totally unnecessary and more complicated in TOT than it needs to be. The old Linux ProcessMonitor for local debugging can handle this easily in its fork/exec without adding any such complexity (i.e. this is what I was going to do in llgs-launched as well).

So the personality() call should work and it'll be simpler than what I was implying below.

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 17, 2014

Hey Chandler,

I put in a fix here:

svn commit
Sending lldb.xcodeproj/project.pbxproj
Sending source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
Sending source/Plugins/Process/FreeBSD/ProcessMonitor.h
Sending source/Plugins/Process/Linux/NativeProcessLinux.cpp
Sending source/Plugins/Process/Linux/NativeProcessLinux.h
Sending source/Plugins/Process/Linux/ProcessMonitor.cpp
Sending source/Plugins/Process/Linux/ProcessMonitor.h
Sending source/Plugins/Process/POSIX/ProcessPOSIX.cpp
Transmitting file data ........
Committed revision 215822.

Until I get in the --enable-aslr flag (my next task), I think you'll be stuck in ASLR-disabled mode since I don't actually see a way to say "enable it", and it is disabled by default. (We just weren't paying attention to the flag on Linux until this change here).

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 19, 2014

For a related change, the 'process launch' (aka 'run') --disable-aslr flag now takes an arg of true/false (or other boolean equivalents). For a discussion on this, see these links:

(Where we ultimately do away with the idea of --enable-aslr):
http://lists.cs.uiuc.edu/pipermail/lldb-commits/Week-of-Mon-20140818/012419.html

(The change, r215996):
http://lists.cs.uiuc.edu/pipermail/lldb-commits/Week-of-Mon-20140818/012445.html

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 9, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla lldb
Projects
None yet
Development

No branches or pull requests

5 participants