Skip to content

PermissionError when attaching to a remote process despite elevated privileges (file permission) #143511

Open

Description

@RafaelWO

Documentation

Description

According to the documentation of the permission requirements for remote debugging (via sys.remote_exec), the tracer process must have elevated privileges (or CAP_SYS_PTRACE).

But I get a PermissionError in the "remote" process when it tries to open the "debugger script" after I execute the tracer program with sudo on Linux. It works if I also run the app with elevated privileges.

Reproducible example

  1. Create a virtual environment with Python 3.14.2 and activate it
  2. Create the following script app.py
# app.py
import os
import time


print("PID:", os.getpid())
print("Waiting for interrupt", end="")
while True:
    print(".", end="", flush=True)
    time.sleep(1)
  1. Run the script above via python app.py
  2. Create the debugger script debug.py
# debug.py
import sys
import textwrap
from tempfile import NamedTemporaryFile

assert len(sys.argv) >= 2, "Pass PID as first argument"

pid = int(sys.argv[1])
script = 'print("Injected!")'

with NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
    script_path = f.name
    f.write(script)

print("Injecting...")
sys.remote_exec(pid, script_path)
print("Done :)")
  1. Run the debug script (in a new shell) via sudo .venv/bin/python debug.py <pid-from-other-process>

Output of debug.py

Injecting...
Done :)

Output of app.py

PID: 27796
Waiting for interrupt.........Can't open debugger script /tmp/tmpsjqnnjw6.py:
Traceback (most recent call last):
  File "/home/rafael/repos/rafaelwo/python-remote-exec-sudo/app.py", line 9, in <module>
    time.sleep(1)
PermissionError: [Errno 13] Permission denied: '/tmp/tmpsjqnnjw6.py'

Expected output of app.py

PID: 27796
Waiting for interrupt............Injected!
....

What confuses me is that sudo .venv/bin/python -m pdb -p works when running the app as non-root. Doesn't pdb also create a temporary file and use sys.remote_exec to let the app run the debug attachment script?

Or is this a documentation issue, i.e. the app-to-be-traced also needs elevated privileges?

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Linked PRs

Activity

  1. Yashp002 commented on Jan 7, 2026

    @Yashp002
    Contributor

    @RafaelWO This looks like a filesystem permission issue rather than a bug in sys.remote_exec.

    Since you ran debug.py with sudo, NamedTemporaryFile created the script owned by root, likely with restricted permissions. The target process (running as a normal user) tries to open this file but gets PermissionError because it doesn't have read access to the root-owned file.

    you can prolly jus fix this by making temp world-readable before injection right?

    If that works, maybe the documentation for remote_exec should be updated to mention ensuring the script path is readable by the target process.

  2. Koshin-S-Hegde commented on Jan 7, 2026

    @Koshin-S-Hegde

    I was able to reproduce the error and it was indeed fixed by running app.py in super user mode. Shouldn't remote_exec, which is running in supper user mode be able to use the correct file permissions as it creates the temporary file? If that is the case, I would like to work on that.

  3. Yashp002 commented on Jan 7, 2026

    @Yashp002
    Contributor

    I was able to reproduce the error and it was indeed fixed by running app.py in super user mode. Shouldn't remote_exec, which is running in supper user mode be able to use the correct file permissions as it creates the temporary file? If that is the case, I would like to work on that.

    Glad you were able to reproduce it. I'm actually already working on the patch for this since I dug into the permission logic earlier. I'll push the PR in a bit :)

  4. Yashp002 commented on Jan 7, 2026

    @Yashp002
    Contributor

    Yeah, got it. Since debug.py creates the file as root (0600 by default with NamedTemporaryFile), the target process naturally hits a PermissionError.

    While we could just document this, sys.remote_exec running as root should arguably handle the hand-off better—either by chown/chmod-ing the file it's about to inject, or (if the IPC channel allows) passing the script content directly rather than a path (though that's a larger protocol change).

    I'll take a look at Python/sysmodule.c (or wherever the injection logic lives) to see if we can safely relax permissions on the target file automatically before the target process tries to open it.

  5. RafaelWO commented on Jan 7, 2026

    @RafaelWO
    ContributorAuthor

    Since you ran debug.py with sudo, NamedTemporaryFile created the script owned by root, likely with restricted permissions. The target process (running as a normal user) tries to open this file but gets PermissionError because it doesn't have read access to the root-owned file.

    Yes, that is also what I suspected.

    But as mentioned: I did not understand why it works with pdb -p because it is also writing a temporary file and passing it to sys.remote_exec.

    I checked the source code of pdb again and I think I found the missing piece: before calling remote_exec, the file permissions are updated to allow reads (see here).

    Hence, my ticket is rather a documentation ticket. Except if it makes sense to change file permissions in sys.remote_exec - as you suggested, @Yashp002

  6. RafaelWO commented on Jan 7, 2026

    @RafaelWO
    ContributorAuthor

    FYI: I added the lines to change the file permissions to debug.py

    +import os
    +import stat
    
    (...)
    
     with NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
         script_path = f.name
         f.write(script)
    
    +orig_mode = os.stat(script_path).st_mode
    +os.chmod(script_path, orig_mode | stat.S_IROTH | stat.S_IRGRP)
    
     print("Injecting...")
     sys.remote_exec(pid, script_path)

    Now it works as expected if the app is ran as a normal user and the debug script via sudo.

  7. Yashp002 commented on Jan 7, 2026

    @Yashp002
    Contributor

    yeah i figured you'd confirm it.

    I think relying on the caller to manually chmod is a bit of a leaky abstraction, especially since sys.remote_exec is already a privileged operation. If we can safely handle this inside the function, it would prevent this class of error entirely for future tool builders.

    I'll dig into sysmodule.c this weekend. If the auto-chmod approach turns out to be too invasive or complex for the standard library, I'll fall back to submitting the documentation patch. Will keep you posted here.

  8. picnixz commented on Jan 7, 2026

    @picnixz
    Member

    For new contributors, I would recommend that you also ask the opinion of module's maintainers to know whether this was intended at all. In this case, I think it's @pablogsal. IMO this should be documented but not added by default.

  9. added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    docsDocumentation in the Doc dir
    and removed
    type-bugAn unexpected behavior, bug, or error
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    on Jan 7, 2026
  10. Yashp002 commented on Jan 7, 2026

    @Yashp002
    Contributor

    Sounds good. I'll check with @pablogsal to get his thoughts on whether this was intended.

  11. pablogsal commented on Jan 8, 2026

    @pablogsal
    Member

    Thanks for raising this issue and looking into this.

    I am not fully against doing this but I am cautiously negative. The reason is that the attaching protocol is designed so it knows nothing on how the file was created. Regarding the permissions it needs permissions to attach and read (which in Linux is PTRACE capabilities) and sudo is just one way to obtain those permissions but most of the time you don't need sudo.

    As this is a problem that happens only when you need sudo it seems like the attaching protocol should not try to be smart and fix things.

    Also, what permissions would you change this to? This can be potentially an attack vector if the permissions are not carefully chosen as a malign actor could change the file if it can be read or modify.

    Also you cannot just make it read only because if the attaching protocol changes it we would be undoing any specific permissioning that the caller may have prepared and since the attaching is the last thing that runs then there is no way to stop it.

  12. changed the title [-]PermissionError when attaching to a remote process despite elevated privileges[/-] [+]PermissionError when attaching to a remote process despite elevated privileges (file permission)[/+] on Jan 8, 2026
  13. RafaelWO commented on Jan 8, 2026

    @RafaelWO
    ContributorAuthor

    Thanks for your answer!

    You are right that you don't need sudo to get permissions for remote debugging. If the debug process has PTRACE (on Linux), the debug program can run under the user context, and thus the observed PermissionError will not be raised.

    Nevertheless, I think it might be helpful to add this info to the remote debugging docs. Also, the documentation only mentions sudo to get elevated privileges on MacOS. Will you get the same error if you don't change file permissions there? 🤔

    If you agree, I am happy to take care of this - or you go ahead as you were first, @Yashp002.

  14. Yashp002 commented on Jan 8, 2026

    @Yashp002
    Contributor

    @RafaelWO Oh yeah I'd be glad to take care of it, I'll have a PR ready at the earliest.

  15. shreyadesai4002-sys commented on Jan 18, 2026

    @shreyadesai4002-sys

    I’d like to improve the documentation of sys.remote_exec permissions requirements and help clarify the expected behavior.

  16. Yashp002 commented on Jan 18, 2026

    @Yashp002
    Contributor

    @RafaelWO Could you please clarify if I need to further alter my PR?

  17. picnixz commented on Jan 18, 2026

    @picnixz
    Member

    @shreyadesai4002-sys someone is already working on it

  18. RafaelWO commented on Jan 19, 2026

    @RafaelWO
    ContributorAuthor

    @RafaelWO Could you please clarify if I need to further alter my PR?

    @Yashp002 Although I am not in a position to decide if the PR can be accepted (I am just a tiny contributor), I made some additional comments that could help move it forward 🙂

  19. Yashp002 commented on Jan 19, 2026

    @Yashp002
    Contributor

    @RafaelWO Could you please clarify if I need to further alter my PR?

    @Yashp002 Although I am not in a position to decide if the PR can be accepted (I am just a tiny contributor), I made some additional comments that could help move it forward 🙂

    Oh right right okay ok thanks anyways:D

  20. added a commit that references this issue on Jan 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsDocumentation in the Doc dir

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions