1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
#!/usr/bin/env bats
load helpers
function setup() {
setup_busybox
}
function teardown() {
teardown_bundle
}
@test "runc run [redundant default /dev/tty]" {
update_config ' .linux.devices += [{"path": "/dev/tty", "type": "c", "major": 5, "minor": 0}]
| .process.args |= ["ls", "-lLn", "/dev/tty"]'
runc run test_dev
[ "$status" -eq 0 ]
if [ $EUID -ne 0 ]; then
[[ "${lines[0]}" =~ "crw-rw-rw".+"1".+"65534".+"65534".+"5,".+"0".+"/dev/tty" ]]
else
[[ "${lines[0]}" =~ "crw-rw-rw".+"1".+"0".+"0".+"5,".+"0".+"/dev/tty" ]]
fi
}
@test "runc run [redundant default /dev/ptmx]" {
update_config ' .linux.devices += [{"path": "/dev/ptmx", "type": "c", "major": 5, "minor": 2}]
| .process.args |= ["ls", "-lLn", "/dev/ptmx"]'
runc run test_dev
[ "$status" -eq 0 ]
[[ "${lines[0]}" =~ "crw-rw-rw".+"1".+"0".+"0".+"5,".+"2".+"/dev/ptmx" ]]
}
@test "runc run/update [device cgroup deny]" {
requires root
update_config ' .linux.resources.devices = [{"allow": false, "access": "rwm"}]
| .linux.devices = [{"path": "/dev/kmsg", "type": "c", "major": 1, "minor": 11}]
| .process.capabilities.bounding += ["CAP_SYSLOG"]
| .process.capabilities.effective += ["CAP_SYSLOG"]
| .process.capabilities.permitted += ["CAP_SYSLOG"]
| .process.args |= ["sh"]'
runc run -d --console-socket "$CONSOLE_SOCKET" test_deny
[ "$status" -eq 0 ]
# test write
runc exec test_deny sh -c 'hostname | tee /dev/kmsg'
[ "$status" -eq 1 ]
[[ "${output}" == *'Operation not permitted'* ]]
# test read
runc exec test_deny sh -c 'head -n 1 /dev/kmsg'
[ "$status" -eq 1 ]
[[ "${output}" == *'Operation not permitted'* ]]
runc update test_deny --pids-limit 42
# test write
runc exec test_deny sh -c 'hostname | tee /dev/kmsg'
[ "$status" -eq 1 ]
[[ "${output}" == *'Operation not permitted'* ]]
# test read
runc exec test_deny sh -c 'head -n 1 /dev/kmsg'
[ "$status" -eq 1 ]
[[ "${output}" == *'Operation not permitted'* ]]
}
@test "runc run [device cgroup allow rw char device]" {
requires root
if [[ ! -c /dev/kmsg ]]; then
skip "no /dev/kmsg"
fi
update_config ' .linux.resources.devices = [{"allow": false, "access": "rwm"},{"allow": true, "type": "c", "major": 1, "minor": 11, "access": "rw"}]
| .linux.devices = [{"path": "/dev/kmsg", "type": "c", "major": 1, "minor": 11}]
| .process.args |= ["sh"]
| .process.capabilities.bounding += ["CAP_SYSLOG"]
| .process.capabilities.effective += ["CAP_SYSLOG"]
| .process.capabilities.permitted += ["CAP_SYSLOG"]
| .hostname = "myhostname"'
runc run -d --console-socket "$CONSOLE_SOCKET" test_allow_char
[ "$status" -eq 0 ]
# test write
runc exec test_allow_char sh -c 'hostname | tee /dev/kmsg'
[ "$status" -eq 0 ]
[[ "${lines[0]}" == *'myhostname'* ]]
# test read
runc exec test_allow_char sh -c 'head -n 1 /dev/kmsg'
[ "$status" -eq 0 ]
# test access
TEST_NAME="dev_access_test"
gcc -static -o "rootfs/bin/${TEST_NAME}" "${TESTDATA}/${TEST_NAME}.c"
runc exec test_allow_char sh -c "${TEST_NAME} /dev/kmsg"
[ "$status" -eq 0 ]
}
@test "runc run [device cgroup allow rm block device]" {
requires root
# Get the first block device.
IFS=$' \t:' read -r device major minor <<<"$(lsblk -nd -o NAME,MAJ:MIN)"
# Could have used -o PATH but lsblk from CentOS 7 does not have it.
device="/dev/$device"
update_config ' .linux.resources.devices = [{"allow": false, "access": "rwm"},{"allow": true, "type": "b", "major": '"$major"', "minor": '"$minor"', "access": "rwm"}]
| .linux.devices = [{"path": "'"$device"'", "type": "b", "major": '"$major"', "minor": '"$minor"'}]
| .process.args |= ["sh"]
| .process.capabilities.bounding += ["CAP_MKNOD"]
| .process.capabilities.effective += ["CAP_MKNOD"]
| .process.capabilities.permitted += ["CAP_MKNOD"]'
runc run -d --console-socket "$CONSOLE_SOCKET" test_allow_block
[ "$status" -eq 0 ]
# test mknod
runc exec test_allow_block sh -c 'mknod /dev/fooblock b '"$major"' '"$minor"''
[ "$status" -eq 0 ]
# test read
runc exec test_allow_block sh -c 'fdisk -l '"$device"''
[ "$status" -eq 0 ]
}
# https://github.com/opencontainers/runc/issues/3551
@test "runc exec vs systemctl daemon-reload" {
requires systemd root
runc run -d --console-socket "$CONSOLE_SOCKET" test_exec
[ "$status" -eq 0 ]
runc exec -t test_exec sh -c "ls -l /proc/self/fd/0; echo 123"
[ "$status" -eq 0 ]
systemctl daemon-reload
runc exec -t test_exec sh -c "ls -l /proc/self/fd/0; echo 123"
[ "$status" -eq 0 ]
}
# https://github.com/opencontainers/runc/issues/4568
@test "runc run [devices vs systemd NeedDaemonReload]" {
# The systemd bug is there since v230, see
# https://github.com/systemd/systemd/pull/3170/commits/ab932a622d57fd327ef95992c343fd4425324088
# and https://github.com/systemd/systemd/issues/35710.
requires systemd_v230
set_cgroups_path
runc run -d --console-socket "$CONSOLE_SOCKET" test_need_reload
check_systemd_value "NeedDaemonReload" "no"
}
|