Bug 210613
Summary: | Go: calling cap.Mode.Set with ambient capabilities present makes invalid prctl call | ||
---|---|---|---|
Product: | Tools | Reporter: | lmb |
Component: | libcap | Assignee: | Andrew G. Morgan (morgan) |
Status: | RESOLVED CODE_FIX | ||
Severity: | normal | CC: | morgan |
Priority: | P1 | ||
Hardware: | All | ||
OS: | Linux | ||
Kernel Version: | 5.4 | Subsystem: | |
Regression: | No | Bisected commit-id: | |
Attachments: | Go reproducer |
Interesting. I'll take a closer look. Thanks for the reproducer. I've reproduced the issue. Thanks very much for this bug report. I think it is one of those good old cases of, "if you don't test it, it *is* broken" things. The fix is tagged psx/v0.2.46-rc4: https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=e7e0e1b9e2cf3378d329174ed5b0c716b0539c72 Also, just FYI, with respect to the ambient inheritance thing: sudo progs/capsh --caps="cap_setpcap+eip" --addamb="cap_setpcap" == --print it might surprise you to learn that the ambient cap isn't what is raising privilege in the post-exec binary. To get that mechanism to kick in, you really want to do something like this: sudo progs/capsh --cap-uid=$(id -u) --caps="cap_setpcap=ep" --iab="^cap_setpcap" == --print The former one, because you are going to exec as root, will simply raise all of the capabilities again (plus the ambient one). [FWIW, --user=$(whoami) would be preferred to --cap-uid=$(id -u) above, but there is a glibc bug related to static compilation that causes user lookups to segfault.] I've tested the fix and it works, thank you for the quick turn around again! Thanks also for explaining the capsh invocation, to be perfectly honest I just searched for an invocation that let me trigger the bug. However, trying to run your example against my Ubuntu capsh yields: sudo strace -f capsh --caps="cap_setpcap+eip" --addamb="cap_setpcap" == --print ... execve("capsh", ["capsh", "--print"], 0x7ffd41d9a398 /* 17 vars */) = -1 ENOENT (No such file or directory) write(2, "execve /bin/bash failed!\n", 25execve /bin/bash failed! ) = 25 Seems like an issue around PATH, since using sudo /sbin/capsh works. I keep discovering bugs, sorry :( I think that one is a known issue fixed in October with libcap-2.45: https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=68240b124cc62744a7a412a7afc85b5c56a48e14 Cheers Andrew |
Created attachment 294085 [details] Go reproducer Please run the attached reproducer as follows: $ sudo -E capsh --caps="cap_setpcap+eip" --addamb="cap_setpcap" -- -c "strace -f -e trace=prctl go run cap.go" After a bunch of text, we get the following: [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) = 0 [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) = 0 [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_DAC_OVERRIDE, 0, 0) = 0 [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_DAC_READ_SEARCH, 0, 0) = 0 [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_FOWNER, 0, 0) = 0 [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_FSETID, 0, 0) = 0 [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_KILL, 0, 0) = 0 [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETGID, 0, 0) = 0 [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETUID, 0, 0) = 0 [pid 69617] prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETPCAP, 0, 0) = 1 [pid 69617] prctl(0 /* PR_??? */, 0, 0, 0, 0) = -1 EINVAL (Invalid argument) ... panic: invalid argument As far as I can tell, this is from the call to sc.prctlwcall6 in syscaller.resetAmbient() when using the CGo wrapper.