-
Notifications
You must be signed in to change notification settings - Fork 11.8k
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
Comments
Implementation note: This link shows a response that indicates how to disable via shell execution: 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 |
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). |
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. |
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. |
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: |
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.
|
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? |
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. |
That is, anything else non-Apple. |
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: 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). |
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. |
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. |
Hey Chandler, I put in a fix here: svn commit 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). |
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): (The change, r215996): |
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
frame #0:
Process 7581 stopped
main + 43 at x.cpp:3, name = 'x', stop reason = breakpoint 1.1 frame #​0: 0x000000000040065b x
main + 43 at x.cpp:31 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
frame #0:
Process 15338 stopped
main + 43 at x.cpp:3, name = 'x', stop reason = breakpoint 1.1 frame #​0: 0x000000000040065b x
main + 43 at x.cpp:31 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.
The text was updated successfully, but these errors were encountered: