Skip to content

Commit

Permalink
runc exec --cap: do not add capabilities to ambient
Browse files Browse the repository at this point in the history
Commit 98fe566 removed setting inheritable capabilities from runc exec
--cap, but neglected to also remove ambient capabilities.

An ambient capability could only be set if the same inheritable
capability is set, so as a result of the above change ambient
capabilities were not set (but due to a bug in gocapability package,
those errors are never reported).

Once we start using a library with the fix [1], that bug will become
apparent. Alas, we do not have any tests for runc exec --cap, so add
one.

Yet, if some inheritable bits are already set from spec, let's set
ambient to avoid a possible regression. Add a test case for that, too.

[1]: kolyshkin/capability#3

Fixes: 98fe566 ("runc: do not set inheritable capabilities")
Co-authored-by: lifubang <lifubang@acmcoder.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
  • Loading branch information
kolyshkin and lifubang committed Sep 26, 2024
1 parent 8e03054 commit 3e3f960
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
7 changes: 6 additions & 1 deletion exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,12 @@ func getProcess(context *cli.Context, bundle string) (*specs.Process, error) {
p.Capabilities.Bounding = append(p.Capabilities.Bounding, c)
p.Capabilities.Effective = append(p.Capabilities.Effective, c)
p.Capabilities.Permitted = append(p.Capabilities.Permitted, c)
p.Capabilities.Ambient = append(p.Capabilities.Ambient, c)
// Since ambient capabilities can't be set without inherritable,
// and runc exec --cap don't set inheritable, let's only set
// ambient if we already have some inheritable bits set from spec.
if p.Capabilities.Inheritable != nil {
p.Capabilities.Ambient = append(p.Capabilities.Ambient, c)
}
}
}
// append the passed env variables
Expand Down
63 changes: 63 additions & 0 deletions tests/integration/capabilities.bats
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,66 @@ function teardown() {
[[ "${output}" == *"CapPrm: 0000000000200000"* ]]
[[ "${output}" == *"NoNewPrivs: 1"* ]]
}

@test "runc exec --cap" {
update_config ' .process.args = ["/bin/sh"]
| .process.capabilities = {}'
runc run -d --console-socket "$CONSOLE_SOCKET" test_exec_cap
[ "$status" -eq 0 ]

runc exec test_exec_cap cat /proc/self/status
[ "$status" -eq 0 ]
# Check no capabilities are set.
[[ "${output}" == *"CapInh: 0000000000000000"* ]]
[[ "${output}" == *"CapPrm: 0000000000000000"* ]]
[[ "${output}" == *"CapEff: 0000000000000000"* ]]
[[ "${output}" == *"CapBnd: 0000000000000000"* ]]
[[ "${output}" == *"CapAmb: 0000000000000000"* ]]

runc exec --cap CAP_KILL --cap CAP_AUDIT_WRITE test_exec_cap cat /proc/self/status
[ "$status" -eq 0 ]
# Check capabilities are added into bounding/effective/permitted only,
# but not to inheritable or ambient.
#
# CAP_KILL is 5, the bit mask is 0x20 (1 << 5).
# CAP_AUDIT_WRITE is 26, the bit mask is 0x20000000 (1 << 26).
[[ "${output}" == *"CapInh: 0000000000000000"* ]]
[[ "${output}" == *"CapPrm: 0000000020000020"* ]]
[[ "${output}" == *"CapEff: 0000000020000020"* ]]
[[ "${output}" == *"CapBnd: 0000000020000020"* ]]
[[ "${output}" == *"CapAmb: 0000000000000000"* ]]
}

@test "runc exec --cap [ambient is set from spec]" {
update_config ' .process.args = ["/bin/sh"]
| .process.capabilities.inheritable = ["CAP_CHOWN", "CAP_SYSLOG"]
| .process.capabilities.permitted = ["CAP_KILL", "CAP_CHOWN"]
| .process.capabilities.effective = ["CAP_KILL"]
| .process.capabilities.bounding = ["CAP_KILL", "CAP_CHOWN", "CAP_SYSLOG"]
| .process.capabilities.ambient = ["CAP_CHOWN"]'
runc run -d --console-socket "$CONSOLE_SOCKET" test_some_caps
[ "$status" -eq 0 ]

runc exec test_some_caps cat /proc/self/status
[ "$status" -eq 0 ]
# Check that capabilities are as set in spec.
#
# CAP_CHOWN is 0, the bit mask is 0x1 (1 << 0)
# CAP_KILL is 5, the bit mask is 0x20 (1 << 5).
# CAP_SYSLOG is 34, the bit mask is 0x400000000 (1 << 34).
[[ "${output}" == *"CapInh: 0000000400000001"* ]]
[[ "${output}" == *"CapPrm: 0000000000000021"* ]]
[[ "${output}" == *"CapEff: 0000000000000021"* ]]
[[ "${output}" == *"CapBnd: 0000000400000021"* ]]
[[ "${output}" == *"CapAmb: 0000000000000001"* ]]

# Check that if config.json has an inheritable capability set,
# runc exec --cap adds ambient capabilities.
runc exec --cap CAP_SYSLOG test_some_caps cat /proc/self/status
[ "$status" -eq 0 ]
[[ "${output}" == *"CapInh: 0000000400000001"* ]]
[[ "${output}" == *"CapPrm: 0000000400000021"* ]]
[[ "${output}" == *"CapEff: 0000000400000021"* ]]
[[ "${output}" == *"CapBnd: 0000000400000021"* ]]
[[ "${output}" == *"CapAmb: 0000000400000001"* ]]
}

0 comments on commit 3e3f960

Please sign in to comment.