-
Notifications
You must be signed in to change notification settings - Fork 66
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
Detect the agent running in a non-root PID namespace #1993
Detect the agent running in a non-root PID namespace #1993
Conversation
@@ -283,6 +287,12 @@ func main() { | |||
os.Exit(1) | |||
} | |||
|
|||
bpf.SetLoggerCbs(bpf.Callbacks{ |
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.
Moved the libbpf logger setter here to ensure that we do this before loading any BPF program
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
b246f67
to
d7198b6
Compare
In Linux resources such as users, processes, mounts, time, etc. can be isolated with namespaces [0]. They are used in tamden with cgroups to implement resource control in containers. Both namespaces and cgroups are conceptually a hierarchy, where the first namespace is the root of the tree and the common ancestor for all the other slices of the machine. The Agent requires to be run in the 'root' (this has nothing to do with permissions or users, necessarily) PID namespace, where all the other processes for every single namespace can be queried. While the kernel does not provide a facility for this check, this commit aims to bring a reliable check to see whether we are inside of a PID namespace or not. It does it with a BPF program that retrieves the pid of the Agent and then we compare it with the pid that the OS gives us in userspace via `getpid(2)`. As the BPF program always gives the PID from the PoV of the root PID namespace, we can tell if we are in the root namespace or not. This uses code from this PoC [1]. Test Plan ========= **running the Agent normally, in the root PID namespace** ``` [root@fedora parca-agent]# dist/parca-agent [works] ``` **under a non-root PID namespace** ``` [javierhonduco@fedora parca-agent]$ sudo unshare --fork --pid --mount-proc [root@fedora parca-agent]# dist/parca-agent ooooooooo. .o. . `888 `Y88. .888. .o8 888 .d88' .oooo. oooo d8b .ooooo. .oooo. .8"888. .oooooooo .ooooo. ooo. .oo. .o888oo 888ooo88P' `P )88b `888""8P d88' `"Y8 `P )88b .8' `888. 888' `88b d88' `88b `888P"Y88b 888 888 .oP"888 888 888 .oP"888 .88ooo8888. 888 888 888ooo888 888 888 888 888 d8( 888 888 888 .o8 d8( 888 .8' `888. `88bod8P' 888 .o 888 888 888 . o888o `Y888""8o d888b `Y8bod8P' `Y888""8o o88o o8888o `8oooooo. `Y8bod8P' o888o o888o "888" d" YD "Y88888P' level=info name=parca-agent ts=2023-09-07T10:42:25.892675407Z caller=main.go:345 msg="maxprocs: Leaving GOMAXPROCS=12: CPU quota undefined" level=error name=parca-agent ts=2023-09-07T10:42:25.925707031Z caller=main.go:374 msg="the agent must be run in the 'root' PID namespace" ``` [0]: https://man7.org/linux/man-pages/man7/namespaces.7.html [1]: https://github.com/javierhonduco/am-i-contained/tree/main
ccbca80
to
82e36d0
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.
it!
In Linux resources such as users, processes, mounts, time, etc. can be isolated with namespaces 0. They are used in tamden with cgroups to implement resource control in containers.
Both namespaces and cgroups are conceptually a hierarchy, where the first namespace is the root of the tree and the common ancestor for all the other slices of the machine.
The Agent requires to be run in the 'root' (this has nothing to do with permissions or users, necessarily) PID namespace, where all the other processes for every single namespace can be queried.
While the kernel does not provide a facility for this check, this commit aims to bring a reliable check to see whether we are inside of a PID namespace or not. It does it with a BPF program that retrieves the pid of the Agent and then we compare it with the pid that the OS gives us in userspace via
getpid(2)
. As the BPF program always gives the PID from the PoV of the root PID namespace, we can tell if we are in the root namespace or not.This uses code from this PoC 1.
Test Plan
running the Agent normally, in the root PID namespace
under a non-root PID namespace