Skip to content

Conversation

DavidSpickett
Copy link
Collaborator

@DavidSpickett DavidSpickett commented Oct 2, 2025

Relates to #161510

Fixes 6db44e5

(it's not fixing it, it's just making the error not be an unhandled error)

When we fail to attach to a process we see if we can add more information about why it happened:

  if (status.GetError() == EPERM) {
    // Depending on the value of ptrace_scope, we can return a different
    // error that suggests how to fix it.
    return AddPtraceScopeNote(status.ToError());
  }

ToError creates a new error value and leaves the one in status unchecked. status's error is ok because it will be checked by Status' destructor.

The problem happens in AddPtraceScopeNote. If we take certain return paths, this new error, or the one we get when trying to find the ptrace scope, may be unchecked on destruction when the function returns.

To fix this, in AddPtraceScopeNote, consume any errors that we are not going to return. Anything returned will be checked by some caller.

Reproducing this failure mode is difficult but it can be faked by calling AddPtraceScopeNote earlier. Which is what I did to prove the concept of the problem.

Relates to llvm#161510

(it's not fixing it, it's just making the error not be an
unhandled error)

When we fail to attach to a process we see if we can add more
information about why it happpened:
```
  if (status.GetError() == EPERM) {
    // Depending on the value of ptrace_scope, we can return a different
    // error that suggests how to fix it.
    return AddPtraceScopeNote(status.ToError());
  }
```
ToError creates a new error value and leaves the one in `status`
unchecked. `status`'s error is ok because it will be checked
by Status' destructor.

The problem happens in `AddPtraceScopeNote`. If we take certain
return paths, this new error, or the one we get when trying to
find the ptrace scope, may be unchecked on destruction when the
function returns.

To fix this, in AddPtraceScopeNote, consume any errors that
we are not going to return. Anything returned will be checked
by some caller.

Reproducing this failure mode is difficult but it can be faked
by calling AddPtraceScopeNote earlier. Which is what I did to
prove the concept of the problem.
@llvmbot
Copy link
Member

llvmbot commented Oct 2, 2025

@llvm/pr-subscribers-lldb

Author: David Spickett (DavidSpickett)

Changes

Relates to #161510

(it's not fixing it, it's just making the error not be an unhandled error)

When we fail to attach to a process we see if we can add more information about why it happened:

  if (status.GetError() == EPERM) {
    // Depending on the value of ptrace_scope, we can return a different
    // error that suggests how to fix it.
    return AddPtraceScopeNote(status.ToError());
  }

ToError creates a new error value and leaves the one in status unchecked. status's error is ok because it will be checked by Status' destructor.

The problem happens in AddPtraceScopeNote. If we take certain return paths, this new error, or the one we get when trying to find the ptrace scope, may be unchecked on destruction when the function returns.

To fix this, in AddPtraceScopeNote, consume any errors that we are not going to return. Anything returned will be checked by some caller.

Reproducing this failure mode is difficult but it can be faked by calling AddPtraceScopeNote earlier. Which is what I did to prove the concept of the problem.


Full diff: https://github.com/llvm/llvm-project/pull/161673.diff

1 Files Affected:

  • (modified) lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp (+4-1)
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 9c798cb1cc8f2..7d0bca738e2e5 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -219,7 +219,8 @@ static llvm::Error AddPtraceScopeNote(llvm::Error original_error) {
   Expected<int> ptrace_scope = GetPtraceScope();
   if (auto E = ptrace_scope.takeError()) {
     Log *log = GetLog(POSIXLog::Process);
-    LLDB_LOG(log, "error reading value of ptrace_scope: {0}", E);
+    LLDB_LOG(log, "error reading value of ptrace_scope: {0}",
+             llvm::toString(std::move(E)));
 
     // The original error is probably more interesting than not being able to
     // read or interpret ptrace_scope.
@@ -230,6 +231,7 @@ static llvm::Error AddPtraceScopeNote(llvm::Error original_error) {
   switch (*ptrace_scope) {
   case 1:
   case 2:
+    llvm::consumeError(std::move(original_error));
     return llvm::createStringError(
         std::error_code(errno, std::generic_category()),
         "The current value of ptrace_scope is %d, which can cause ptrace to "
@@ -239,6 +241,7 @@ static llvm::Error AddPtraceScopeNote(llvm::Error original_error) {
         "https://www.kernel.org/doc/Documentation/security/Yama.txt.",
         *ptrace_scope);
   case 3:
+    llvm::consumeError(std::move(original_error));
     return llvm::createStringError(
         std::error_code(errno, std::generic_category()),
         "The current value of ptrace_scope is 3, which will cause ptrace to "

@DavidSpickett
Copy link
Collaborator Author

The Yama error now looks like:

UNSUPPORTED: LLDB (/home/davspi01/work/open_source/build-llvm/bin/clang-x86_64) :: test_qThreadInfo_contains_thread_attach_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) 
failed to attach to process 327017: The current value of ptrace_scope is 1, which can cause ptrace to fail to attach to a running process. To fix this, run:
	sudo sysctl -w kernel.yama.ptrace_scope=0
For more information, see: https://www.kernel.org/doc/Documentation/security/Yama.txt.
error: failed to attach to pid 327017: The current value of ptrace_scope is 1, which can cause ptrace to fail to attach to a running process. To fix this, run:
	sudo sysctl -w kernel.yama.ptrace_scope=0
For more information, see: https://www.kernel.org/doc/Documentation/security/Yama.txt.
FAIL: LLDB (/home/davspi01/work/open_source/build-llvm/bin/clang-x86_64) :: test_qThreadInfo_contains_thread_attach_llgs (TestLldbGdbServer.LldbGdbServerTestCase)

@DavidSpickett DavidSpickett merged commit fb17bc7 into llvm:main Oct 7, 2025
9 checks passed
@DavidSpickett DavidSpickett deleted the lldb-ptrace-status branch October 7, 2025 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants