-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[lldb] Use correct path for lldb-server executable #131519
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] Use correct path for lldb-server executable #131519
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-lldb Author: Yuval Deutscher (yuvald-sweet-security) ChangesHey, This solves an issue where running lldb-server-20 with a non-absolute path (for example, when it's installed into I haven't previously contributed to this project; if you want me to change anything in the code please don't hesitate to let me know. Full diff: https://github.com/llvm/llvm-project/pull/131519.diff 1 Files Affected:
diff --git a/lldb/tools/lldb-server/lldb-platform.cpp b/lldb/tools/lldb-server/lldb-platform.cpp
index 880b45b989b9c..103e1ac02843d 100644
--- a/lldb/tools/lldb-server/lldb-platform.cpp
+++ b/lldb/tools/lldb-server/lldb-platform.cpp
@@ -545,13 +545,28 @@ int main_platform(int argc, char *argv[]) {
MainLoop main_loop;
{
+ char progpath[1024];
+#if defined(_WIN32)
+ if (GetModuleFileName(NULL, progpath, sizeof(progpath)) == 0) {
+ printf("Error retrieving executable path.\n");
+ return 1;
+ }
+#else
+ ssize_t len = readlink("/proc/self/exe", progpath, sizeof(progpath) - 1);
+ if (len == -1) {
+ perror("readlink");
+ return 1;
+ }
+ path[len] = '\0';
+#endif
+
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> platform_handles =
platform_sock->Accept(
main_loop, [progname, gdbserver_port, &inferior_arguments, log_file,
log_channels, &main_loop,
&platform_handles](std::unique_ptr<Socket> sock_up) {
printf("Connection established.\n");
- Status error = spawn_process(progname, sock_up.get(),
+ Status error = spawn_process(progpath, sock_up.get(),
gdbserver_port, inferior_arguments,
log_file, log_channels, main_loop);
if (error.Fail()) {
|
bbfae10
to
0af05f3
Compare
I'm wondering if the right fix isn't to call |
Perhaps, but note that technically argv[0] doesn't really have to be related to the name of the executable at all - the user can pretty much pass whatever value they want as argv[0] when calling execve (although I agree that it would be a very peculiar workflow for someone to run lldb-server with an argv[0] that isn't the name of the binary). On another note, I am currently debugging a few other regressions introduced in LLDB 20 that relate to the way the platform mode server executes another server internally. For example, while this patch makes
(This is an important workflow because that is precisely the way that lldb-server gets installed in distro packaging, e.g. EDIT: I'll make a separate PR for this issue |
Ah, turns out there's a |
bf755da
to
df4b4e2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, turns out there's a HostInfo::GetProgramFileSpec() function which solves both these issues.
I am aware of that function. The reason I did not suggest it is because GetProgramFileSpec
(on linux) returns the canonical path (with all symlinks resolved). That's something I am generally trying to avoid because it can break some instalation types -- where the installation consists of a symlink farm and the expected installation layout is given by the symlink tree. (It can also fix some installations which expect exactly the opposite -- the debian use case in one of them).
It's very hard to come up with a solution which makes everyone happy, which is why e.g. gcc/clang have a flag (-no-canonical-prefixes
) to control this kind of behavior. I'm not thrilled by the idea of adding that to lldb, nor I think it would be practical for an interactive tool.
Whatever we do, I think it is better to resolve the symlink as late as possible as that gives us more options down the line. What I don't understand is why doesn't this work for your use case already -- GetModuleFileSpecForHostAddress
calls FileSystem::Resolve
, which should give you the canonical path for the library. Does that fail for some reason? It is it because the (relative) path returned by GetModuleFileSpecForHostAddress
is resolved relative to CWD (but in reality we've executed it by finding the executable on the path)?
I understand, but I think that for lldb-server this isn't much of an issue as it seems relatively stand-alone. I'd be more worried if this code attempted to execute a binary that isn't
I'm assuming this is referring to the other issue, which I discuss in #131609? Because the issue in the current PR is not related to |
Not exactly. I my use case, And the lldb-server binary is not completely standalone as it needs to execute the gdbserver binary (which on linux is actually still the same binary, but the code kind of doesn't know that), which is why you have #131609. In this scenario, there's no way to find the lldb-server binary (or anything else) because the CAS tree contains only a bunch of hex files. That said, I'm slightly warming up towards using GetProgramFileSpec because I realized it is (mostly) possible (I'm not saying you have to do that) to implement it to return a non-canonical path by looking at auxiliary vector (AT_EXECFN). One tricky aspect of that is that if you execute the binary using a relative path (
Kind of yes, but the two issues are related. The issue with symlinks is that once you resolve them, there's no way to go back. I'm asking why (in the scenario you describe in that PR) does |
So, regarding that issue - first of all, Now, what you said about resolving relative to cwd instead of relative to $PATH also happens there, but that's actually the reason the entire thing works in the first place - the fact that this resolves relative to cwd causes |
Then maybe we should just execute the path given by |
I'm sorry, my bad. I saw the tilde resolution code and somehow assumed that canonicalization must follow. I think the lack of symlink resolution is intentional.
.. because of this check, presumably
Got it. And I think I finally understand what those checks in ComputeSupportExeDirectory are doing.
I think that'd be fine, given that I know how to get GetProgramFileSpec to return the non-canonical path if that becomes necessary. And it matches what the code was doing originally. Process(Launch)Info has a [GS]etArg0 method, but it looks like ProcessLauncherPosixFork doesn't actually make use of it. It shouldn't be too hard to change that though. Would you like to try that? (If not, I can do it, probably next week) |
df4b4e2
to
ea0a08e
Compare
I wrote something, lets see if it works
EDIT: nevermind, I see what you mean. But now it's kind of awkard that we have a redundancy of information between the argv vector and the arg0 field. It seems that the intention of whoever designed |
I think this #63468 is the same sort of issue. Not sure if it's the same though. As you can tell from me saying "I will get back to this" 2 years ago, the knowledge of any of that has left my head by now, but thank you for looking into this. I know it's not easy to unpick. |
Sorry about the delay. I wasn't quite happy with the hedging in the implementation, and I also wanted to write a test for it, but I figured it would be easier if I did it myself. I now have #133093. You can rebase your patch on top of that when it lands. |
The issue you linked is probably the other issue which I encountered and fixed recently (#131609). The issue fixed in the PR we're currently writing in is a regression introduced in LLVM 20 due to a fundamental change in how lldb-server platform mode works, and so it doesn't make sense to me that it existed 2 years ago. |
dc67b57
to
9519119
Compare
@labath I rebased it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome. Thanks for your patience.
@JDevlieghere @labath how do I get this PR merged? I don't think I have access to merge on my own; will one of you merge it, or am I missing something here? |
@yuvald-sweet-security Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues. How to do this, and the rest of the post-merge process, is covered in detail here. If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! |
/cherry-pick 945c494 |
/pull-request #134072 |
Hey,
This solves an issue where running lldb-server-20 with a non-absolute path (for example, when it's installed into
/usr/bin
and the user runs it aslldb-server-20 ...
and not/usr/bin/lldb-server-20 ...
) fails witherror: spawn_process failed: execve failed: No such file or directory
. The underlying issue is that when run that way, it attempts to execute a binary namedlldb-server-20
from its current directory. This is also a mild security hazard because lldb-server is often being run as root in the directory /tmp, meaning that an unprivileged user can create the file /tmp/lldb-server-20 and lldb-server will execute it as root. (although, well, it's a debugging server we're talking about, so that may not be a real concern)I haven't previously contributed to this project; if you want me to change anything in the code please don't hesitate to let me know.