github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/tests/integration/idmap.bats (about) 1 #!/usr/bin/env bats 2 3 load helpers 4 5 function setup() { 6 OVERFLOW_UID="$(cat /proc/sys/kernel/overflowuid)" 7 OVERFLOW_GID="$(cat /proc/sys/kernel/overflowgid)" 8 requires root 9 requires_kernel 5.12 10 11 setup_debian 12 requires_idmap_fs . 13 14 # Prepare source folders for mounts. 15 mkdir -p source-{1,2,multi{1,2,3}}/ 16 touch source-{1,2,multi{1,2,3}}/foo.txt 17 touch source-multi{1,2,3}/{bar,baz}.txt 18 19 # Change the owners for everything other than source-1. 20 chown 1:1 source-2/foo.txt 21 22 # A source with multiple users owning files. 23 chown 100:211 source-multi1/foo.txt 24 chown 101:222 source-multi1/bar.txt 25 chown 102:233 source-multi1/baz.txt 26 27 # Same gids as multi1, different uids. 28 chown 200:211 source-multi2/foo.txt 29 chown 201:222 source-multi2/bar.txt 30 chown 202:233 source-multi2/baz.txt 31 32 # Even more users -- 1000 uids, 500 gids. 33 chown 5000528:6000491 source-multi3/foo.txt 34 chown 5000133:6000337 source-multi3/bar.txt 35 chown 5000999:6000444 source-multi3/baz.txt 36 37 # Add a symlink-containing source. 38 ln -s source-multi1 source-multi1-symlink 39 40 # Add some top-level files in the mount tree. 41 mkdir -p mnt-subtree/multi{1,2} 42 touch mnt-subtree/{foo,bar,baz}.txt 43 chown 100:211 mnt-subtree/foo.txt 44 chown 200:222 mnt-subtree/bar.txt 45 chown 300:233 mnt-subtree/baz.txt 46 47 mounts_file="$PWD/.all-mounts" 48 echo -n >"$mounts_file" 49 } 50 51 function teardown() { 52 if [ -v mounts_file ]; then 53 xargs -n 1 -a "$mounts_file" -- umount -l 54 rm -f "$mounts_file" 55 fi 56 teardown_bundle 57 } 58 59 function setup_host_bind_mount() { 60 src="$1" 61 dst="$2" 62 63 mount --bind "$src" "$dst" 64 echo "$dst" >>"$mounts_file" 65 } 66 67 function setup_idmap_userns() { 68 update_config '.linux.namespaces += [{"type": "user"}] 69 | .linux.uidMappings += [{"containerID": 0, "hostID": 100000, "size": 65536}] 70 | .linux.gidMappings += [{"containerID": 0, "hostID": 100000, "size": 65536}]' 71 remap_rootfs 72 } 73 74 function setup_bind_mount() { 75 mountname="${1:-1}" 76 update_config '.mounts += [ 77 { 78 "source": "source-'"$mountname"'/", 79 "destination": "/tmp/bind-mount-'"$mountname"'", 80 "options": ["bind"] 81 } 82 ]' 83 } 84 85 function setup_idmap_single_mount() { 86 uidmap="$1" # ctr:host:size 87 gidmap="$2" # ctr:host:size 88 mountname="$3" 89 destname="${4:-$mountname}" 90 91 read -r uid_containerID uid_hostID uid_size <<<"$(tr : ' ' <<<"$uidmap")" 92 read -r gid_containerID gid_hostID gid_size <<<"$(tr : ' ' <<<"$gidmap")" 93 94 update_config '.mounts += [ 95 { 96 "source": "source-'"$mountname"'/", 97 "destination": "/tmp/mount-'"$destname"'", 98 "options": ["bind"], 99 "uidMappings": [{"containerID": '"$uid_containerID"', "hostID": '"$uid_hostID"', "size": '"$uid_size"'}], 100 "gidMappings": [{"containerID": '"$gid_containerID"', "hostID": '"$gid_hostID"', "size": '"$gid_size"'}] 101 } 102 ]' 103 } 104 105 function setup_idmap_basic_mount() { 106 mountname="${1:-1}" 107 setup_idmap_single_mount 0:100000:65536 0:100000:65536 "$mountname" 108 } 109 110 @test "simple idmap mount [userns]" { 111 setup_idmap_userns 112 setup_idmap_basic_mount 113 114 update_config '.process.args = ["sh", "-c", "stat -c =%u=%g= /tmp/mount-1/foo.txt"]' 115 116 runc run test_debian 117 [ "$status" -eq 0 ] 118 [[ "$output" == *"=0=0="* ]] 119 } 120 121 @test "simple idmap mount [no userns]" { 122 setup_idmap_basic_mount 123 124 update_config '.process.args = ["sh", "-c", "stat -c =%u=%g= /tmp/mount-1/foo.txt"]' 125 126 runc run test_debian 127 [ "$status" -eq 0 ] 128 [[ "$output" == *"=100000=100000="* ]] 129 } 130 131 @test "write to an idmap mount [userns]" { 132 setup_idmap_userns 133 setup_idmap_basic_mount 134 135 update_config '.process.args = ["sh", "-c", "touch /tmp/mount-1/bar && stat -c =%u=%g= /tmp/mount-1/bar"]' 136 137 runc run test_debian 138 [ "$status" -eq 0 ] 139 [[ "$output" == *"=0=0="* ]] 140 } 141 142 @test "write to an idmap mount [no userns]" { 143 setup_idmap_basic_mount 144 145 update_config '.process.args = ["sh", "-c", "touch /tmp/mount-1/bar && stat -c =%u=%g= /tmp/mount-1/bar"]' 146 147 runc run test_debian 148 # The write must fail because the user is unmapped. 149 [ "$status" -ne 0 ] 150 [[ "$output" == *"Value too large for defined data type"* ]] # ERANGE 151 } 152 153 @test "idmap mount with propagation flag [userns]" { 154 setup_idmap_userns 155 setup_idmap_basic_mount 156 157 update_config '.process.args = ["sh", "-c", "findmnt -o PROPAGATION /tmp/mount-1"]' 158 # Add the shared option to the idmap mount. 159 update_config '.mounts |= map((select(.source == "source-1/") | .options += ["shared"]) // .)' 160 161 runc run test_debian 162 [ "$status" -eq 0 ] 163 [[ "$output" == *"shared"* ]] 164 } 165 166 @test "idmap mount with relative path [userns]" { 167 setup_idmap_userns 168 setup_idmap_basic_mount 169 170 update_config '.process.args = ["sh", "-c", "stat -c =%u=%g= /tmp/mount-1/foo.txt"]' 171 # Switch the mount to have a relative mount destination. 172 update_config '.mounts |= map((select(.source == "source-1/") | .destination = "tmp/mount-1") // .)' 173 174 runc run test_debian 175 [ "$status" -eq 0 ] 176 [[ "$output" == *"=0=0="* ]] 177 } 178 179 @test "idmap mount with bind mount [userns]" { 180 setup_idmap_userns 181 setup_idmap_basic_mount 182 setup_bind_mount 183 184 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/{,bind-}mount-1/foo.txt"]' 185 186 runc run test_debian 187 [ "$status" -eq 0 ] 188 [[ "$output" == *"=/tmp/mount-1/foo.txt:0=0="* ]] 189 [[ "$output" == *"=/tmp/bind-mount-1/foo.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 190 } 191 192 @test "idmap mount with bind mount [no userns]" { 193 setup_idmap_basic_mount 194 setup_bind_mount 195 196 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/{,bind-}mount-1/foo.txt"]' 197 198 runc run test_debian 199 [ "$status" -eq 0 ] 200 [[ "$output" == *"=/tmp/mount-1/foo.txt:100000=100000="* ]] 201 [[ "$output" == *"=/tmp/bind-mount-1/foo.txt:0=0="* ]] 202 } 203 204 @test "two idmap mounts (same mapping) with two bind mounts [userns]" { 205 setup_idmap_userns 206 207 setup_idmap_basic_mount 1 208 setup_bind_mount 1 209 setup_bind_mount 2 210 setup_idmap_basic_mount 2 211 212 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-[12]/foo.txt"]' 213 214 runc run test_debian 215 [ "$status" -eq 0 ] 216 [[ "$output" == *"=/tmp/mount-1/foo.txt:0=0="* ]] 217 [[ "$output" == *"=/tmp/mount-2/foo.txt:1=1="* ]] 218 } 219 220 @test "same idmap mount (different mappings) [userns]" { 221 setup_idmap_userns 222 223 # Mount the same directory with different mappings. Make sure we also use 224 # different mappings for uids and gids. 225 setup_idmap_single_mount 100:100000:100 200:100000:100 multi1 226 setup_idmap_single_mount 100:101000:100 200:102000:100 multi1 multi1-alt 227 setup_idmap_single_mount 100:102000:100 200:103000:100 multi1-symlink multi1-alt-sym 228 229 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-multi1{,-alt{,-sym}}/{foo,bar,baz}.txt"]' 230 231 runc run test_debian 232 [ "$status" -eq 0 ] 233 [[ "$output" == *"=/tmp/mount-multi1/foo.txt:0=11="* ]] 234 [[ "$output" == *"=/tmp/mount-multi1/bar.txt:1=22="* ]] 235 [[ "$output" == *"=/tmp/mount-multi1/baz.txt:2=33="* ]] 236 [[ "$output" == *"=/tmp/mount-multi1-alt/foo.txt:1000=2011="* ]] 237 [[ "$output" == *"=/tmp/mount-multi1-alt/bar.txt:1001=2022="* ]] 238 [[ "$output" == *"=/tmp/mount-multi1-alt/baz.txt:1002=2033="* ]] 239 [[ "$output" == *"=/tmp/mount-multi1-alt-sym/foo.txt:2000=3011="* ]] 240 [[ "$output" == *"=/tmp/mount-multi1-alt-sym/bar.txt:2001=3022="* ]] 241 [[ "$output" == *"=/tmp/mount-multi1-alt-sym/baz.txt:2002=3033="* ]] 242 } 243 244 @test "same idmap mount (different mappings) [no userns]" { 245 # Mount the same directory with different mappings. Make sure we also use 246 # different mappings for uids and gids. 247 setup_idmap_single_mount 100:100000:100 200:100000:100 multi1 248 setup_idmap_single_mount 100:101000:100 200:102000:100 multi1 multi1-alt 249 setup_idmap_single_mount 100:102000:100 200:103000:100 multi1-symlink multi1-alt-sym 250 251 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-multi1{,-alt{,-sym}}/{foo,bar,baz}.txt"]' 252 253 runc run test_debian 254 [ "$status" -eq 0 ] 255 [[ "$output" == *"=/tmp/mount-multi1/foo.txt:100000=100011="* ]] 256 [[ "$output" == *"=/tmp/mount-multi1/bar.txt:100001=100022="* ]] 257 [[ "$output" == *"=/tmp/mount-multi1/baz.txt:100002=100033="* ]] 258 [[ "$output" == *"=/tmp/mount-multi1-alt/foo.txt:101000=102011="* ]] 259 [[ "$output" == *"=/tmp/mount-multi1-alt/bar.txt:101001=102022="* ]] 260 [[ "$output" == *"=/tmp/mount-multi1-alt/baz.txt:101002=102033="* ]] 261 [[ "$output" == *"=/tmp/mount-multi1-alt-sym/foo.txt:102000=103011="* ]] 262 [[ "$output" == *"=/tmp/mount-multi1-alt-sym/bar.txt:102001=103022="* ]] 263 [[ "$output" == *"=/tmp/mount-multi1-alt-sym/baz.txt:102002=103033="* ]] 264 } 265 266 @test "multiple idmap mounts (different mappings) [userns]" { 267 setup_idmap_userns 268 269 # Make sure we use different mappings for uids and gids. 270 setup_idmap_single_mount 100:101100:3 200:101900:50 multi1 271 setup_idmap_single_mount 200:102200:3 200:102900:100 multi2 272 setup_idmap_single_mount 5000000:103000:1000 6000000:103000:500 multi3 273 274 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-multi[123]/{foo,bar,baz}.txt"]' 275 276 runc run test_debian 277 [ "$status" -eq 0 ] 278 [[ "$output" == *"=/tmp/mount-multi1/foo.txt:1100=1911="* ]] 279 [[ "$output" == *"=/tmp/mount-multi1/bar.txt:1101=1922="* ]] 280 [[ "$output" == *"=/tmp/mount-multi1/baz.txt:1102=1933="* ]] 281 [[ "$output" == *"=/tmp/mount-multi2/foo.txt:2200=2911="* ]] 282 [[ "$output" == *"=/tmp/mount-multi2/bar.txt:2201=2922="* ]] 283 [[ "$output" == *"=/tmp/mount-multi2/baz.txt:2202=2933="* ]] 284 [[ "$output" == *"=/tmp/mount-multi3/foo.txt:3528=3491="* ]] 285 [[ "$output" == *"=/tmp/mount-multi3/bar.txt:3133=3337="* ]] 286 [[ "$output" == *"=/tmp/mount-multi3/baz.txt:3999=3444="* ]] 287 } 288 289 @test "multiple idmap mounts (different mappings) [no userns]" { 290 # Make sure we use different mappings for uids and gids. 291 setup_idmap_single_mount 100:1100:3 200:1900:50 multi1 292 setup_idmap_single_mount 200:2200:3 200:2900:100 multi2 293 setup_idmap_single_mount 5000000:3000:1000 6000000:3000:500 multi3 294 295 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-multi[123]/{foo,bar,baz}.txt"]' 296 297 runc run test_debian 298 [ "$status" -eq 0 ] 299 [[ "$output" == *"=/tmp/mount-multi1/foo.txt:1100=1911="* ]] 300 [[ "$output" == *"=/tmp/mount-multi1/bar.txt:1101=1922="* ]] 301 [[ "$output" == *"=/tmp/mount-multi1/baz.txt:1102=1933="* ]] 302 [[ "$output" == *"=/tmp/mount-multi2/foo.txt:2200=2911="* ]] 303 [[ "$output" == *"=/tmp/mount-multi2/bar.txt:2201=2922="* ]] 304 [[ "$output" == *"=/tmp/mount-multi2/baz.txt:2202=2933="* ]] 305 [[ "$output" == *"=/tmp/mount-multi3/foo.txt:3528=3491="* ]] 306 [[ "$output" == *"=/tmp/mount-multi3/bar.txt:3133=3337="* ]] 307 [[ "$output" == *"=/tmp/mount-multi3/baz.txt:3999=3444="* ]] 308 } 309 310 @test "idmap mount (complicated mapping) [userns]" { 311 setup_idmap_userns 312 313 update_config '.mounts += [ 314 { 315 "source": "source-multi1/", 316 "destination": "/tmp/mount-multi1", 317 "options": ["bind"], 318 "uidMappings": [ 319 {"containerID": 100, "hostID": 101000, "size": 1}, 320 {"containerID": 101, "hostID": 102000, "size": 1}, 321 {"containerID": 102, "hostID": 103000, "size": 1} 322 ], 323 "gidMappings": [ 324 {"containerID": 210, "hostID": 101100, "size": 10}, 325 {"containerID": 220, "hostID": 102200, "size": 10}, 326 {"containerID": 230, "hostID": 103300, "size": 10} 327 ] 328 } 329 ]' 330 331 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-multi1/{foo,bar,baz}.txt"]' 332 runc run test_debian 333 [ "$status" -eq 0 ] 334 [[ "$output" == *"=/tmp/mount-multi1/foo.txt:1000=1101="* ]] 335 [[ "$output" == *"=/tmp/mount-multi1/bar.txt:2000=2202="* ]] 336 [[ "$output" == *"=/tmp/mount-multi1/baz.txt:3000=3303="* ]] 337 } 338 339 @test "idmap mount (complicated mapping) [no userns]" { 340 update_config '.mounts += [ 341 { 342 "source": "source-multi1/", 343 "destination": "/tmp/mount-multi1", 344 "options": ["bind"], 345 "uidMappings": [ 346 {"containerID": 100, "hostID": 1000, "size": 1}, 347 {"containerID": 101, "hostID": 2000, "size": 1}, 348 {"containerID": 102, "hostID": 3000, "size": 1} 349 ], 350 "gidMappings": [ 351 {"containerID": 210, "hostID": 1100, "size": 10}, 352 {"containerID": 220, "hostID": 2200, "size": 10}, 353 {"containerID": 230, "hostID": 3300, "size": 10} 354 ] 355 } 356 ]' 357 358 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-multi1/{foo,bar,baz}.txt"]' 359 runc run test_debian 360 [ "$status" -eq 0 ] 361 [[ "$output" == *"=/tmp/mount-multi1/foo.txt:1000=1101="* ]] 362 [[ "$output" == *"=/tmp/mount-multi1/bar.txt:2000=2202="* ]] 363 [[ "$output" == *"=/tmp/mount-multi1/baz.txt:3000=3303="* ]] 364 } 365 366 @test "idmap mount (non-recursive idmap) [userns]" { 367 setup_idmap_userns 368 369 setup_host_bind_mount "source-multi1/" "mnt-subtree/multi1" 370 setup_host_bind_mount "source-multi2/" "mnt-subtree/multi2" 371 372 update_config '.mounts += [ 373 { 374 "source": "mnt-subtree/", 375 "destination": "/tmp/mount-tree", 376 "options": ["rbind"], 377 "uidMappings": [ 378 {"containerID": 100, "hostID": 101000, "size": 3}, 379 {"containerID": 200, "hostID": 102000, "size": 3}, 380 {"containerID": 300, "hostID": 103000, "size": 3} 381 ], 382 "gidMappings": [ 383 {"containerID": 210, "hostID": 101100, "size": 10}, 384 {"containerID": 220, "hostID": 102200, "size": 10}, 385 {"containerID": 230, "hostID": 103300, "size": 10} 386 ] 387 } 388 ]' 389 390 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-tree{,/multi1,/multi2}/{foo,bar,baz}.txt"]' 391 runc run test_debian 392 [ "$status" -eq 0 ] 393 [[ "$output" == *"=/tmp/mount-tree/foo.txt:1000=1101="* ]] 394 [[ "$output" == *"=/tmp/mount-tree/bar.txt:2000=2202="* ]] 395 [[ "$output" == *"=/tmp/mount-tree/baz.txt:3000=3303="* ]] 396 # Because we used "idmap", the child mounts were not remapped recursively. 397 [[ "$output" == *"=/tmp/mount-tree/multi1/foo.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 398 [[ "$output" == *"=/tmp/mount-tree/multi1/bar.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 399 [[ "$output" == *"=/tmp/mount-tree/multi1/baz.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 400 [[ "$output" == *"=/tmp/mount-tree/multi2/foo.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 401 [[ "$output" == *"=/tmp/mount-tree/multi2/bar.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 402 [[ "$output" == *"=/tmp/mount-tree/multi2/baz.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 403 } 404 405 @test "idmap mount (non-recursive idmap) [no userns]" { 406 setup_host_bind_mount "source-multi1/" "mnt-subtree/multi1" 407 setup_host_bind_mount "source-multi2/" "mnt-subtree/multi2" 408 409 update_config '.mounts += [ 410 { 411 "source": "mnt-subtree/", 412 "destination": "/tmp/mount-tree", 413 "options": ["rbind"], 414 "uidMappings": [ 415 {"containerID": 100, "hostID": 101000, "size": 3}, 416 {"containerID": 200, "hostID": 102000, "size": 3}, 417 {"containerID": 300, "hostID": 103000, "size": 3} 418 ], 419 "gidMappings": [ 420 {"containerID": 210, "hostID": 101100, "size": 10}, 421 {"containerID": 220, "hostID": 102200, "size": 10}, 422 {"containerID": 230, "hostID": 103300, "size": 10} 423 ] 424 } 425 ]' 426 427 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-tree{,/multi1,/multi2}/{foo,bar,baz}.txt"]' 428 runc run test_debian 429 [ "$status" -eq 0 ] 430 [[ "$output" == *"=/tmp/mount-tree/foo.txt:101000=101101="* ]] 431 [[ "$output" == *"=/tmp/mount-tree/bar.txt:102000=102202="* ]] 432 [[ "$output" == *"=/tmp/mount-tree/baz.txt:103000=103303="* ]] 433 # Because we used "idmap", the child mounts were not remapped recursively. 434 [[ "$output" == *"=/tmp/mount-tree/multi1/foo.txt:100=211="* ]] 435 [[ "$output" == *"=/tmp/mount-tree/multi1/bar.txt:101=222="* ]] 436 [[ "$output" == *"=/tmp/mount-tree/multi1/baz.txt:102=233="* ]] 437 [[ "$output" == *"=/tmp/mount-tree/multi2/foo.txt:200=211="* ]] 438 [[ "$output" == *"=/tmp/mount-tree/multi2/bar.txt:201=222="* ]] 439 [[ "$output" == *"=/tmp/mount-tree/multi2/baz.txt:202=233="* ]] 440 } 441 442 @test "idmap mount (idmap flag) [userns]" { 443 setup_idmap_userns 444 445 setup_host_bind_mount "source-multi1/" "mnt-subtree/multi1" 446 setup_host_bind_mount "source-multi2/" "mnt-subtree/multi2" 447 448 update_config '.mounts += [ 449 { 450 "source": "mnt-subtree/", 451 "destination": "/tmp/mount-tree", 452 "options": ["rbind", "idmap"], 453 "uidMappings": [ 454 {"containerID": 100, "hostID": 101000, "size": 3}, 455 {"containerID": 200, "hostID": 102000, "size": 3}, 456 {"containerID": 300, "hostID": 103000, "size": 3} 457 ], 458 "gidMappings": [ 459 {"containerID": 210, "hostID": 101100, "size": 10}, 460 {"containerID": 220, "hostID": 102200, "size": 10}, 461 {"containerID": 230, "hostID": 103300, "size": 10} 462 ] 463 } 464 ]' 465 466 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-tree{,/multi1,/multi2}/{foo,bar,baz}.txt"]' 467 runc run test_debian 468 [ "$status" -eq 0 ] 469 [[ "$output" == *"=/tmp/mount-tree/foo.txt:1000=1101="* ]] 470 [[ "$output" == *"=/tmp/mount-tree/bar.txt:2000=2202="* ]] 471 [[ "$output" == *"=/tmp/mount-tree/baz.txt:3000=3303="* ]] 472 # Because we used "idmap", the child mounts were not remapped recursively. 473 [[ "$output" == *"=/tmp/mount-tree/multi1/foo.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 474 [[ "$output" == *"=/tmp/mount-tree/multi1/bar.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 475 [[ "$output" == *"=/tmp/mount-tree/multi1/baz.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 476 [[ "$output" == *"=/tmp/mount-tree/multi2/foo.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 477 [[ "$output" == *"=/tmp/mount-tree/multi2/bar.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 478 [[ "$output" == *"=/tmp/mount-tree/multi2/baz.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 479 } 480 481 @test "idmap mount (idmap flag) [no userns]" { 482 setup_host_bind_mount "source-multi1/" "mnt-subtree/multi1" 483 setup_host_bind_mount "source-multi2/" "mnt-subtree/multi2" 484 485 update_config '.mounts += [ 486 { 487 "source": "mnt-subtree/", 488 "destination": "/tmp/mount-tree", 489 "options": ["rbind", "idmap"], 490 "uidMappings": [ 491 {"containerID": 100, "hostID": 101000, "size": 3}, 492 {"containerID": 200, "hostID": 102000, "size": 3}, 493 {"containerID": 300, "hostID": 103000, "size": 3} 494 ], 495 "gidMappings": [ 496 {"containerID": 210, "hostID": 101100, "size": 10}, 497 {"containerID": 220, "hostID": 102200, "size": 10}, 498 {"containerID": 230, "hostID": 103300, "size": 10} 499 ] 500 } 501 ]' 502 503 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-tree{,/multi1,/multi2}/{foo,bar,baz}.txt"]' 504 runc run test_debian 505 [ "$status" -eq 0 ] 506 [[ "$output" == *"=/tmp/mount-tree/foo.txt:101000=101101="* ]] 507 [[ "$output" == *"=/tmp/mount-tree/bar.txt:102000=102202="* ]] 508 [[ "$output" == *"=/tmp/mount-tree/baz.txt:103000=103303="* ]] 509 # Because we used "idmap", the child mounts were not remapped recursively. 510 [[ "$output" == *"=/tmp/mount-tree/multi1/foo.txt:100=211="* ]] 511 [[ "$output" == *"=/tmp/mount-tree/multi1/bar.txt:101=222="* ]] 512 [[ "$output" == *"=/tmp/mount-tree/multi1/baz.txt:102=233="* ]] 513 [[ "$output" == *"=/tmp/mount-tree/multi2/foo.txt:200=211="* ]] 514 [[ "$output" == *"=/tmp/mount-tree/multi2/bar.txt:201=222="* ]] 515 [[ "$output" == *"=/tmp/mount-tree/multi2/baz.txt:202=233="* ]] 516 } 517 518 @test "idmap mount (ridmap flag) [userns]" { 519 setup_idmap_userns 520 521 setup_host_bind_mount "source-multi1/" "mnt-subtree/multi1" 522 setup_host_bind_mount "source-multi2/" "mnt-subtree/multi2" 523 524 update_config '.mounts += [ 525 { 526 "source": "mnt-subtree/", 527 "destination": "/tmp/mount-tree", 528 "options": ["rbind", "ridmap"], 529 "uidMappings": [ 530 {"containerID": 100, "hostID": 101000, "size": 3}, 531 {"containerID": 200, "hostID": 102000, "size": 3}, 532 {"containerID": 300, "hostID": 103000, "size": 3} 533 ], 534 "gidMappings": [ 535 {"containerID": 210, "hostID": 101100, "size": 10}, 536 {"containerID": 220, "hostID": 102200, "size": 10}, 537 {"containerID": 230, "hostID": 103300, "size": 10} 538 ] 539 } 540 ]' 541 542 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-tree{,/multi1,/multi2}/{foo,bar,baz}.txt"]' 543 runc run test_debian 544 [ "$status" -eq 0 ] 545 [[ "$output" == *"=/tmp/mount-tree/foo.txt:1000=1101="* ]] 546 [[ "$output" == *"=/tmp/mount-tree/bar.txt:2000=2202="* ]] 547 [[ "$output" == *"=/tmp/mount-tree/baz.txt:3000=3303="* ]] 548 # The child mounts have the same mapping applied. 549 [[ "$output" == *"=/tmp/mount-tree/multi1/foo.txt:1000=1101="* ]] 550 [[ "$output" == *"=/tmp/mount-tree/multi1/bar.txt:1001=2202="* ]] 551 [[ "$output" == *"=/tmp/mount-tree/multi1/baz.txt:1002=3303="* ]] 552 [[ "$output" == *"=/tmp/mount-tree/multi2/foo.txt:2000=1101="* ]] 553 [[ "$output" == *"=/tmp/mount-tree/multi2/bar.txt:2001=2202="* ]] 554 [[ "$output" == *"=/tmp/mount-tree/multi2/baz.txt:2002=3303="* ]] 555 } 556 557 @test "idmap mount (ridmap flag) [no userns]" { 558 setup_host_bind_mount "source-multi1/" "mnt-subtree/multi1" 559 setup_host_bind_mount "source-multi2/" "mnt-subtree/multi2" 560 561 update_config '.mounts += [ 562 { 563 "source": "mnt-subtree/", 564 "destination": "/tmp/mount-tree", 565 "options": ["rbind", "ridmap"], 566 "uidMappings": [ 567 {"containerID": 100, "hostID": 101000, "size": 3}, 568 {"containerID": 200, "hostID": 102000, "size": 3}, 569 {"containerID": 300, "hostID": 103000, "size": 3} 570 ], 571 "gidMappings": [ 572 {"containerID": 210, "hostID": 101100, "size": 10}, 573 {"containerID": 220, "hostID": 102200, "size": 10}, 574 {"containerID": 230, "hostID": 103300, "size": 10} 575 ] 576 } 577 ]' 578 579 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-tree{,/multi1,/multi2}/{foo,bar,baz}.txt"]' 580 runc run test_debian 581 [ "$status" -eq 0 ] 582 [[ "$output" == *"=/tmp/mount-tree/foo.txt:101000=101101="* ]] 583 [[ "$output" == *"=/tmp/mount-tree/bar.txt:102000=102202="* ]] 584 [[ "$output" == *"=/tmp/mount-tree/baz.txt:103000=103303="* ]] 585 # The child mounts have the same mapping applied. 586 [[ "$output" == *"=/tmp/mount-tree/multi1/foo.txt:101000=101101="* ]] 587 [[ "$output" == *"=/tmp/mount-tree/multi1/bar.txt:101001=102202="* ]] 588 [[ "$output" == *"=/tmp/mount-tree/multi1/baz.txt:101002=103303="* ]] 589 [[ "$output" == *"=/tmp/mount-tree/multi2/foo.txt:102000=101101="* ]] 590 [[ "$output" == *"=/tmp/mount-tree/multi2/bar.txt:102001=102202="* ]] 591 [[ "$output" == *"=/tmp/mount-tree/multi2/baz.txt:102002=103303="* ]] 592 } 593 594 @test "idmap mount (idmap flag, implied mapping) [userns]" { 595 setup_idmap_userns 596 597 setup_host_bind_mount "source-multi1/" "mnt-subtree/multi1" 598 setup_host_bind_mount "source-multi2/" "mnt-subtree/multi2" 599 600 update_config '.mounts += [ 601 { 602 "source": "mnt-subtree/", 603 "destination": "/tmp/mount-tree", 604 "options": ["rbind", "idmap"], 605 } 606 ]' 607 608 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-tree{,/multi1,/multi2}/{foo,bar,baz}.txt"]' 609 runc run test_debian 610 [ "$status" -eq 0 ] 611 [[ "$output" == *"=/tmp/mount-tree/foo.txt:100=211="* ]] 612 [[ "$output" == *"=/tmp/mount-tree/bar.txt:200=222="* ]] 613 [[ "$output" == *"=/tmp/mount-tree/baz.txt:300=233="* ]] 614 # Because we used "idmap", the child mounts were not remapped recursively. 615 [[ "$output" == *"=/tmp/mount-tree/multi1/foo.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 616 [[ "$output" == *"=/tmp/mount-tree/multi1/bar.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 617 [[ "$output" == *"=/tmp/mount-tree/multi1/baz.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 618 [[ "$output" == *"=/tmp/mount-tree/multi2/foo.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 619 [[ "$output" == *"=/tmp/mount-tree/multi2/bar.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 620 [[ "$output" == *"=/tmp/mount-tree/multi2/baz.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 621 } 622 623 @test "idmap mount (ridmap flag, implied mapping) [userns]" { 624 setup_idmap_userns 625 626 setup_host_bind_mount "source-multi1/" "mnt-subtree/multi1" 627 setup_host_bind_mount "source-multi2/" "mnt-subtree/multi2" 628 629 update_config '.mounts += [ 630 { 631 "source": "mnt-subtree/", 632 "destination": "/tmp/mount-tree", 633 "options": ["rbind", "ridmap"], 634 } 635 ]' 636 637 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-tree{,/multi1,/multi2}/{foo,bar,baz}.txt"]' 638 runc run test_debian 639 [ "$status" -eq 0 ] 640 [[ "$output" == *"=/tmp/mount-tree/foo.txt:100=211="* ]] 641 [[ "$output" == *"=/tmp/mount-tree/bar.txt:200=222="* ]] 642 [[ "$output" == *"=/tmp/mount-tree/baz.txt:300=233="* ]] 643 # The child mounts have the same mapping applied. 644 [[ "$output" == *"=/tmp/mount-tree/multi1/foo.txt:100=211="* ]] 645 [[ "$output" == *"=/tmp/mount-tree/multi1/bar.txt:101=222="* ]] 646 [[ "$output" == *"=/tmp/mount-tree/multi1/baz.txt:102=233="* ]] 647 [[ "$output" == *"=/tmp/mount-tree/multi2/foo.txt:200=211="* ]] 648 [[ "$output" == *"=/tmp/mount-tree/multi2/bar.txt:201=222="* ]] 649 [[ "$output" == *"=/tmp/mount-tree/multi2/baz.txt:202=233="* ]] 650 } 651 652 @test "idmap mount (idmap flag, implied mapping, userns join) [userns]" { 653 # Create a detached container with the id-mapping we want. 654 cp config.json config.json.bak 655 update_config '.linux.namespaces += [{"type": "user"}] 656 | .linux.uidMappings += [{"containerID": 0, "hostID": 100000, "size": 65536}] 657 | .linux.gidMappings += [{"containerID": 0, "hostID": 100000, "size": 65536}]' 658 update_config '.process.args = ["sleep", "infinity"]' 659 660 runc run -d --console-socket "$CONSOLE_SOCKET" target_userns 661 [ "$status" -eq 0 ] 662 663 # Configure our container to attach to the first container's userns. 664 target_pid="$(__runc state target_userns | jq .pid)" 665 update_config '.linux.namespaces |= map(if .type == "user" then (.path = "/proc/'"$target_pid"'/ns/" + .type) else . end)' 666 update_config 'del(.linux.uidMappings) | del(.linux.gidMappings)' 667 668 setup_host_bind_mount "source-multi1/" "mnt-subtree/multi1" 669 setup_host_bind_mount "source-multi2/" "mnt-subtree/multi2" 670 671 update_config '.mounts += [ 672 { 673 "source": "mnt-subtree/", 674 "destination": "/tmp/mount-tree", 675 "options": ["rbind", "idmap"], 676 } 677 ]' 678 679 update_config '.process.args = ["bash", "-c", "stat -c =%n:%u=%g= /tmp/mount-tree{,/multi1,/multi2}/{foo,bar,baz}.txt"]' 680 runc run test_debian 681 [ "$status" -eq 0 ] 682 [[ "$output" == *"=/tmp/mount-tree/foo.txt:100=211="* ]] 683 [[ "$output" == *"=/tmp/mount-tree/bar.txt:200=222="* ]] 684 [[ "$output" == *"=/tmp/mount-tree/baz.txt:300=233="* ]] 685 # Because we used "idmap", the child mounts were not remapped recursively. 686 [[ "$output" == *"=/tmp/mount-tree/multi1/foo.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 687 [[ "$output" == *"=/tmp/mount-tree/multi1/bar.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 688 [[ "$output" == *"=/tmp/mount-tree/multi1/baz.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 689 [[ "$output" == *"=/tmp/mount-tree/multi2/foo.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 690 [[ "$output" == *"=/tmp/mount-tree/multi2/bar.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 691 [[ "$output" == *"=/tmp/mount-tree/multi2/baz.txt:$OVERFLOW_UID=$OVERFLOW_GID="* ]] 692 }