[GH-ISSUE #3727] Allow external debuggers with --noroot? #2347

Open
opened 2026-05-05 09:01:58 -06:00 by gitea-mirror · 2 comments
Owner

Originally created by @cbs228 on GitHub (Nov 5, 2020).
Original GitHub issue: https://github.com/netblue30/firejail/issues/3727

When --noroot is specified, firejail creates a user namespace with an effective UID of 0, making it owned by the root user.

Because the user namespace is owned by root, it is not possible to ptrace(2) or attach debuggers which are outside of the sandbox to processes which are inside of the sandbox. Doing so requires the CAP_SYS_PTRACE capability on the whole system.

Normally, I think this is desired behavior, and user_namespaces(7) tell us why:

A process that resides in the parent of the user namespace and whose effective user ID matches the owner of the namespace has all capabilities in the namespace.

This means that any other process running under the same user account has all the capability superpowers, including to attach debuggers. This bypasses the default Yama restriction on Ubuntu and other systems, which denies ptrace without an existing parent/ancestor relationship between processes.

Sometimes we do want to attach external debuggers. mumble-voip/mumble/issues/4506 is a good example of this: we want to allow an unprivileged process to reach in and issue ptrace and memory-reading calls to the process(es) running in the sandbox.

Does it make sense to offer an --allow-external-debuggers option? This option might create the user namespace under the real UID of the invoking user—and not root. Would this have other, potentially nasty side-effects? Does it even make sense to use --noroot like this?

If I misunderstand how this stuff works, please feel free to enlighten me.

Originally created by @cbs228 on GitHub (Nov 5, 2020). Original GitHub issue: https://github.com/netblue30/firejail/issues/3727 When `--noroot` is specified, firejail creates a user namespace with an effective UID of 0, making it owned by the root user. Because the user namespace is owned by root, it is not possible to [`ptrace(2)`](https://man7.org/linux/man-pages/man2/ptrace.2.html) or attach debuggers which are *outside* of the sandbox to processes which are inside of the sandbox. Doing so requires the `CAP_SYS_PTRACE` capability on the whole system. Normally, I think this is desired behavior, and [`user_namespaces(7)`](https://www.man7.org/linux/man-pages/man7/user_namespaces.7.html) tell us why: > A process that resides in the parent of the user namespace and whose effective user ID matches the owner of the namespace has all capabilities in the namespace. This means that any other process running under the same user account has all the capability superpowers, including to attach debuggers. This bypasses the default [Yama](https://www.kernel.org/doc/html/v4.14/admin-guide/LSM/Yama.html) restriction on Ubuntu and other systems, which denies ptrace without an existing parent/ancestor relationship between processes. Sometimes we do want to attach external debuggers. mumble-voip/mumble/issues/4506 is a good example of this: we want to allow an unprivileged process to reach in and issue ptrace and memory-reading calls to the process(es) running in the sandbox. Does it make sense to offer an `--allow-external-debuggers` option? This option might create the user namespace under the real UID of the invoking user—and not root. Would this have other, potentially nasty side-effects? Does it even make sense to use `--noroot` like this? If I misunderstand how this stuff works, please feel free to enlighten me.
Author
Owner

@smitsohu commented on GitHub (Mar 20, 2022):

I think your observations and conclusions are correct, and I can reproduce a Yama bypass in unprivileged user namespaces.

IMHO this is a bug in the kernel. Or at least it should be documented somewhere that unprivileged user namespaces break Yama's promises.

<!-- gh-comment-id:1073263397 --> @smitsohu commented on GitHub (Mar 20, 2022): I think your observations and conclusions are correct, and I can reproduce a Yama bypass in unprivileged user namespaces. IMHO this is a bug in the kernel. Or at least it should be documented somewhere that unprivileged user namespaces break Yama's promises.
Author
Owner

@smitsohu commented on GitHub (Mar 20, 2022):

IMHO this is a bug in the kernel. Or at least it should be documented somewhere that unprivileged user namespaces break Yama's promises.

In fact it is documented in ptrace(2)

With respect to values 1 and 2, note that creating a new user namespace effectively removes the protection offered by Yama. This is because a process in the parent user namespace whose effective UID matches the UID of the creator of a child namespace has all capabilities (including CAP_SYS_PTRACE) when performing operations within the child user namespace (and further-removed descendants of that namespace). Consequently, when a process tries to use user namespaces to sandbox itself, it inadvertently weakens the protections offered by the Yama LSM.

Interesting!

<!-- gh-comment-id:1073272192 --> @smitsohu commented on GitHub (Mar 20, 2022): > IMHO this is a bug in the kernel. Or at least it should be documented somewhere that unprivileged user namespaces break Yama's promises. In fact it is documented in `ptrace(2)` > With respect to values 1 and 2, note that creating a new user namespace effectively removes the protection offered by Yama. This is because a process in the parent user namespace whose effective UID matches the UID of the creator of a child namespace has all capabilities (including CAP_SYS_PTRACE) when performing operations within the child user namespace (and further-removed descendants of that namespace). Consequently, when a process tries to use user namespaces to sandbox itself, it inadvertently weakens the protections offered by the Yama LSM. Interesting!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#2347
No description provided.