-
Notifications
You must be signed in to change notification settings - Fork 11
/
storage-disks-vm
executable file
·211 lines (175 loc) · 7.15 KB
/
storage-disks-vm
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#!/bin/sh
set -eu
# Install LXD
install_lxd
IMAGE="${TEST_IMG:-ubuntu-minimal-daily:24.04}"
# Test
set -x
echo "==> Setup share directory"
# Create directory for use as basis for restricted disk source tests.
testRoot="/opt/lxd-test-restricted"
[ -d "${testRoot}" ] && rm -rf "${testRoot}"
mkdir "${testRoot}"
# Create directory for use as allowed disk source path prefix in project.
mkdir "${testRoot}/allowed1"
mkdir "${testRoot}/allowed2"
mkdir "${testRoot}/allowed1/foo1"
mkdir "${testRoot}/allowed1/foo2"
chown 1000:1000 "${testRoot}/allowed1/foo1"
chown 1001:1001 "${testRoot}/allowed1/foo2"
mkdir "${testRoot}/not-allowed1"
ln -s "${testRoot}/not-allowed1" "${testRoot}/allowed1/not-allowed1"
ln -s "${testRoot}/allowed2" "${testRoot}/allowed1/not-allowed2"
(cd "${testRoot}/allowed1" || false; ln -s foo1 foolink)
# Create loop device to use as NVMe disk
loopimg="$(mktemp)"
truncate -s 100M "${loopimg}"
loopdev="$(losetup --show --find "${loopimg}")"
# Configure LXD
lxc project switch default
lxc network create lxdbr0
lxc storage create default zfs size=20GB volume.size=5GB
lxc profile device add default root disk path="/" pool=default
lxc profile device add default eth0 nic network=lxdbr0
lxc profile show default
lxc init "${IMAGE}" v1 --vm
lxc config device add v1 d1 disk source="${testRoot}/allowed1" path=/mnt
# tests to prevent regressions like:
# https://github.com/canonical/lxd/issues/13325
lxc config set v1 raw.idmap - << EOF
uid 0 0
gid 0 1
EOF
lxc start v1
lxc stop -f v1
lxc config set v1 raw.idmap - << EOF
uid 0 0
gid 0 0
EOF
lxc start v1
lxc stop -f v1
lxc config set v1 raw.idmap - << EOF
both 0 0
EOF
lxc start v1
lxc stop -f v1
lxc delete -f v1
lxc profile device remove default root
lxc profile device remove default eth0
# Create project with restricted disk source path.
lxc project create restricted \
-c features.images=false \
-c restricted=true \
-c restricted.devices.disk=allow \
-c restricted.devices.disk.paths="${testRoot}/allowed1,${testRoot}/allowed2"
lxc project switch restricted
lxc profile device add default root disk path="/" pool=default
lxc profile device add default eth0 nic network=lxdbr0
lxc profile show default
# Create instance and add check relative source paths are not allowed.
lxc init "${IMAGE}" v1 --vm
! lxc config device add v1 d1 disk source=foo path=/mnt || false
# Check adding a disk with a source path above the restricted parent source path isn't allowed.
! lxc config device add v1 d1 disk source="${testRoot}/not-allowed1" path=/mnt || false
# Check adding a disk with a source path that is a symlink above the restricted parent source path isn't allowed
# at start time (check that openat2 restrictions are doing their job).
lxc config device add v1 d1 disk source="${testRoot}/allowed1/not-allowed1" path=/mnt
! lxc start v1 || false
# Check some rudimentary work arounds to allowed path checks don't work.
! lxc config device set v1 d1 source="${testRoot}/../not-allowed1" || false
# Check adding a disk from a restricted source path cannot use shifting at start time. This is not safe as we
# cannot prevent creation of files with setuid, which would allow a root executable to be created.
lxc config device set v1 d1 source="${testRoot}/allowed1" shift=true
! lxc start v1 || false
# Check adding a disk with a source path that is allowed.
lxc config device set v1 d1 source="${testRoot}/allowed1" shift=false
lxc start v1
waitInstanceReady v1
lxc exec v1 -- ls -l /mnt/foo1
lxc stop -f v1
# Check adding a disk to a vm with a long name to test possible problems with long socket paths or long qemu device tags
LONG_DEVICE_NAME="device-with-very-long-name-for-long-qemu-property-handling-test"
lxc init "${IMAGE}" v2 --vm
lxc config device add v2 "${LONG_DEVICE_NAME}" disk source="${testRoot}/allowed1" path="/mnt/bar1"
lxc start v2
waitInstanceReady v2
lxc exec v2 -- mountpoint /mnt/bar
lxc config device remove v2 "${LONG_DEVICE_NAME}"
lxc config device add v2 "${LONG_DEVICE_NAME}" disk source="${testRoot}/allowed1" path="/mnt/bar2" # Test hotplugging as well
lxc exec v2 -- mountpoint /mnt/bar
lxc delete -f v2
# Check adding a disk with a source path that is allowed that symlinks to another allowed source path isn't
# allowed at start time.
lxc config device set v1 d1 source="${testRoot}/allowed1/not-allowed2"
! lxc start v1 || false
# Check relative symlink inside allowed parent path is allowed.
lxc config device set v1 d1 source="${testRoot}/allowed1/foolink" path=/mnt/foolink
lxc start v1
waitInstanceReady v1
[ "$(lxc exec v1 -- stat /mnt/foolink -c '%u:%g')" = "65534:65534" ] || false
lxc stop -f v1
# Check usage of raw.idmap is restricted.
! lxc config set v1 raw.idmap="both 1000 1000" || false
# Allow specific raw.idmap host UID/GID.
lxc project set restricted restricted.idmap.uid=1000
! lxc config set v1 raw.idmap="both 1000 1000" || false
! lxc config set v1 raw.idmap="gid 1000 1000" || false
lxc config set v1 raw.idmap="uid 1000 1000"
lxc project set restricted restricted.idmap.gid=1000
lxc config set v1 raw.idmap="gid 1000 1000"
lxc config set v1 raw.idmap="both 1000 1000"
# Check conflict detection works.
! lxc project unset restricted restricted.idmap.uid || false
! lxc project unset restricted restricted.idmap.gid || false
# Check single entry raw.idmap has taken effect on disk share.
lxc config device set v1 d1 source="${testRoot}/allowed1" path=/mnt
lxc start v1 || (lxc info --show-log c1 ; false)
waitInstanceReady v1
[ "$(lxc exec v1 -- stat /mnt/foo1 -c '%u:%g')" = "1000:1000" ] || false
[ "$(lxc exec v1 -- stat /mnt/foo2 -c '%u:%g')" = "65534:65534" ] || false
# Check security.secureboot setting is applied to running VM at next start up.
if lxc exec v1 -- mount | grep -qwF /boot/efi; then
lxc exec v1 -- mokutil --sb-state | grep -Fx "SecureBoot enabled"
lxc profile set default security.secureboot=false
lxc restart -f v1
waitInstanceReady v1
lxc exec v1 -- mokutil --sb-state | grep -Fx "SecureBoot disabled"
fi
if hasNeededAPIExtension disk_io_bus; then
# Remove disk device restrictions and add a NVMe disk
lxc stop -f v1
lxc config device remove v1 d1
lxc project unset restricted restricted.devices.disk
lxc project unset restricted restricted.devices.disk.paths
lxc project unset restricted restricted
# Add a NVMe disk and check if a NVMe controller is added to the VM
lxc config device add v1 nvme-ssd disk source="${loopdev}" io.bus=nvme
lxc start v1
waitInstanceReady v1
if ! lxc exec v1 -- sh -c 'command -v lspci'; then
lxc exec v1 -- apt-get update
lxc exec v1 -- apt-get install --no-install-recommends -y pciutils
fi
lxc exec v1 -- lspci | grep -F "QEMU NVM Express Controller"
else
echo 'Skipping NVME test due to missing extension: "disk_io_bus"'
fi
echo "==> Cleanup"
lxc delete -f v1
lxc project switch default
lxc project delete restricted
lxc storage delete default
lxc network delete lxdbr0
rm "${testRoot}/allowed1/not-allowed1"
rm "${testRoot}/allowed1/not-allowed2"
rmdir "${testRoot}/allowed1/foo1"
rmdir "${testRoot}/allowed1/foo2"
rm "${testRoot}/allowed1/foolink"
rmdir "${testRoot}/allowed1"
rmdir "${testRoot}/allowed2"
rmdir "${testRoot}/not-allowed1"
rmdir "${testRoot}"
losetup --detach "${loopdev}"
rm "${loopimg}"
# shellcheck disable=SC2034
FAIL=0