-
Notifications
You must be signed in to change notification settings - Fork 449
[FEATURE][FIX] New capabilities with rings (replacing old capabilities feature) #2243
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
[FEATURE][FIX] New capabilities with rings (replacing old capabilities feature) #2243
Conversation
There are some opportunistic style/format fixes/improvements together, but I won't split into new commits just because of that (I believe the opportunistic refactoring is a good practice and want to use more in my PRs). |
This comment was marked as outdated.
This comment was marked as outdated.
@yanivagman per our recent discussion, this PR will unblock: which will be capable of mounting/unmounting cgroupv1/cgroupv2 during startup/exit. And then unblock:
|
This comment was marked as outdated.
This comment was marked as outdated.
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.
@rafaeldtinoco Didn't review it yet but took a quick pick, and something popped into my mind, let me know what you think. I really would prefer that moving-in/moving-out from a ring would be done in a block, without the need to remember to run unprivileged again.
Something like:
c.WithCaps(caps.SYSLOG, func() {
//do your thing
})
c.Privileged(func() {
// do your thing
})
Those would execute the code and leave the ring as soon as the func returns. Instead of
// c.Require(cap.SYS_ADMIN)
// do stuff
// c.Unprivileged()
wdyt?
I can give a try, lets see... |
Yep, I like it: I'll make that change @josedonizetti |
Thanks for the review @NDStrahilevitz, I have made the changes. I thought we should merge this only next week (after this week's "special release" we are going to make with changes arriving tomorrow) BUT it occurred to me that, since we are currently broken regarding capabilities, maybe we should merge this together (since this is also a fix). WDYT ? (@grantseltzer FYI since you're coordinating this "special" release) Note, I have also improved debugging:
So it is very clear which capabilities are being enabled each time they are "applied". |
I'll rebase and address comments from @yanivagman tomorrow, so we can merge this before the next release (if others agree). |
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.
@rafaeldtinoco when booting tracee without any capabilities (not using sudo), we get a segmentation error that is misleading:
./dist/tracee-ebpf
TIME UID COMM PID TID RET EVENT ARGS
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0xffffffc0 pc=0x7fb55469455b]
runtime stack:
runtime.throw({0x171a7f5?, 0x0?})
/snap/go/9951/src/runtime/panic.go:1047 +0x5d fp=0x7fb5067fb8c8 sp=0x7fb5067fb898 pc=0x94ce1d
runtime.sigpanic()
/snap/go/9951/src/runtime/signal_unix.go:819 +0x369 fp=0x7fb5067fb918 sp=0x7fb5067fb8c8 pc=0x963e49
...
can we double check tracee is getting called with enough caps, and if not return a nicer error?
or simply:
Trying to reproduce into multiple envs and not able to.... |
Reduce tracee capabilities during its execution. Do it through "protection rings": * Privileged (ring 0): all capabilities are Effective (almost never) * Required (ring 1): only required (by events) capabilities are Effective (during config) * Requested (ring 2): single time requested capabilities are Effective (special needs) * Unprivileged (ring 3): no capabilities are Effective at all (most of the time) This way, tracee will be most of its time (99%) without any Effective capability (Unprivileged ring). The Required() ring will set capabilities needed by Events as Effective until Unprivileged ring is set. This change is needed to allow tracee to raise its capabilities for certain operations (like mounting/umounting cgroupv2 filesystems, for example). Documentation provided at docs/deep-drive/capabilities.md. It also Implements @josedonizetti's idea of executing protected code within an execution block instead of manually changing protection ring back to unprivileged at the end of each needed code.
@josedonizetti and I paired remotely to close this for the release (and tested together in multiple envs). |
Initial Checklist
Description (git log)
Reduce tracee capabilities during its execution. Do it through
"protection rings":
This way, tracee will be most of its time (99%) without any Effective
capability (Unprivileged ring). The Required() ring will set
capabilities needed by Events as Effective until Unprivileged ring is
set.
This change is needed to allow tracee to raise its capabilities for
certain operations (like mounting/umounting cgroupv2 filesystems, for
example).
Documentation provided at docs/deep-drive/capabilities.md.
Fixes: #2242
Type of change
How Has This Been Tested?
Multiple executions, in different environments and kernel versions, with command lines similar to:
You may add, remove or skip capabilities dropping feature. By not enabling the cmdline, tracee successfully drops the capabilities as needed.
Final Checklist:
Pick "Bug Fix" or "Feature", delete the other and mark appropriate checks.
Git Log Checklist:
My commits logs have: