File: dev.bats

package info (click to toggle)
runc 1.3.3%2Bds1-3
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 3,136 kB
  • sloc: sh: 2,298; ansic: 1,125; makefile: 229
file content (159 lines) | stat: -rw-r--r-- 4,956 bytes parent folder | download | duplicates (2)
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"
}