at 25.11-pre 6.1 kB view raw
1import ./make-test-python.nix ( 2 { pkgs, ... }: 3 let 4 userUid = 1000; 5 usersGid = 100; 6 busybox = 7 pkgs: 8 pkgs.busybox.override { 9 # Without this, the busybox binary drops euid to ruid for most applets, including id. 10 # See https://bugs.busybox.net/show_bug.cgi?id=15101 11 extraConfig = "CONFIG_FEATURE_SUID n"; 12 }; 13 in 14 { 15 name = "wrappers"; 16 17 nodes.machine = 18 { config, pkgs, ... }: 19 { 20 ids.gids.users = usersGid; 21 22 users.users = { 23 regular = { 24 uid = userUid; 25 isNormalUser = true; 26 }; 27 }; 28 29 security.apparmor.enable = true; 30 31 security.wrappers = { 32 disabled = { 33 enable = false; 34 owner = "root"; 35 group = "root"; 36 setuid = true; 37 source = "${busybox pkgs}/bin/busybox"; 38 program = "disabled_busybox"; 39 }; 40 suidRoot = { 41 owner = "root"; 42 group = "root"; 43 setuid = true; 44 source = "${busybox pkgs}/bin/busybox"; 45 program = "suid_root_busybox"; 46 }; 47 sgidRoot = { 48 owner = "root"; 49 group = "root"; 50 setgid = true; 51 source = "${busybox pkgs}/bin/busybox"; 52 program = "sgid_root_busybox"; 53 }; 54 withChown = { 55 owner = "root"; 56 group = "root"; 57 source = "${pkgs.libcap}/bin/capsh"; 58 program = "capsh_with_chown"; 59 capabilities = "cap_chown+ep"; 60 }; 61 }; 62 }; 63 64 testScript = '' 65 def cmd_as_regular(cmd): 66 return "su -l regular -c '{0}'".format(cmd) 67 68 def test_as_regular(cmd, expected): 69 out = machine.succeed(cmd_as_regular(cmd)).strip() 70 assert out == expected, "Expected {0} to output {1}, but got {2}".format(cmd, expected, out) 71 72 def test_as_regular_in_userns_mapped_as_root(cmd, expected): 73 out = machine.succeed(f"su -l regular -c '${pkgs.util-linux}/bin/unshare -rm {cmd}'").strip() 74 assert out == expected, "Expected {0} to output {1}, but got {2}".format(cmd, expected, out) 75 76 test_as_regular('${busybox pkgs}/bin/busybox id -u', '${toString userUid}') 77 test_as_regular('${busybox pkgs}/bin/busybox id -ru', '${toString userUid}') 78 test_as_regular('${busybox pkgs}/bin/busybox id -g', '${toString usersGid}') 79 test_as_regular('${busybox pkgs}/bin/busybox id -rg', '${toString usersGid}') 80 81 test_as_regular('/run/wrappers/bin/suid_root_busybox id -u', '0') 82 test_as_regular('/run/wrappers/bin/suid_root_busybox id -ru', '${toString userUid}') 83 test_as_regular('/run/wrappers/bin/suid_root_busybox id -g', '${toString usersGid}') 84 test_as_regular('/run/wrappers/bin/suid_root_busybox id -rg', '${toString usersGid}') 85 86 test_as_regular('/run/wrappers/bin/sgid_root_busybox id -u', '${toString userUid}') 87 test_as_regular('/run/wrappers/bin/sgid_root_busybox id -ru', '${toString userUid}') 88 test_as_regular('/run/wrappers/bin/sgid_root_busybox id -g', '0') 89 test_as_regular('/run/wrappers/bin/sgid_root_busybox id -rg', '${toString usersGid}') 90 91 test_as_regular_in_userns_mapped_as_root('/run/wrappers/bin/suid_root_busybox id -u', '0') 92 test_as_regular_in_userns_mapped_as_root('/run/wrappers/bin/suid_root_busybox id -ru', '0') 93 test_as_regular_in_userns_mapped_as_root('/run/wrappers/bin/suid_root_busybox id -g', '0') 94 test_as_regular_in_userns_mapped_as_root('/run/wrappers/bin/suid_root_busybox id -rg', '0') 95 96 test_as_regular_in_userns_mapped_as_root('/run/wrappers/bin/sgid_root_busybox id -u', '0') 97 test_as_regular_in_userns_mapped_as_root('/run/wrappers/bin/sgid_root_busybox id -ru', '0') 98 test_as_regular_in_userns_mapped_as_root('/run/wrappers/bin/sgid_root_busybox id -g', '0') 99 test_as_regular_in_userns_mapped_as_root('/run/wrappers/bin/sgid_root_busybox id -rg', '0') 100 101 # Test that in nonewprivs environment the wrappers simply exec their target. 102 test_as_regular('${pkgs.util-linux}/bin/setpriv --no-new-privs /run/wrappers/bin/suid_root_busybox id -u', '${toString userUid}') 103 test_as_regular('${pkgs.util-linux}/bin/setpriv --no-new-privs /run/wrappers/bin/suid_root_busybox id -ru', '${toString userUid}') 104 test_as_regular('${pkgs.util-linux}/bin/setpriv --no-new-privs /run/wrappers/bin/suid_root_busybox id -g', '${toString usersGid}') 105 test_as_regular('${pkgs.util-linux}/bin/setpriv --no-new-privs /run/wrappers/bin/suid_root_busybox id -rg', '${toString usersGid}') 106 107 test_as_regular('${pkgs.util-linux}/bin/setpriv --no-new-privs /run/wrappers/bin/sgid_root_busybox id -u', '${toString userUid}') 108 test_as_regular('${pkgs.util-linux}/bin/setpriv --no-new-privs /run/wrappers/bin/sgid_root_busybox id -ru', '${toString userUid}') 109 test_as_regular('${pkgs.util-linux}/bin/setpriv --no-new-privs /run/wrappers/bin/sgid_root_busybox id -g', '${toString usersGid}') 110 test_as_regular('${pkgs.util-linux}/bin/setpriv --no-new-privs /run/wrappers/bin/sgid_root_busybox id -rg', '${toString usersGid}') 111 112 # We are only testing the permitted set, because it's easiest to look at with capsh. 113 machine.fail(cmd_as_regular('${pkgs.libcap}/bin/capsh --has-p=CAP_CHOWN')) 114 machine.fail(cmd_as_regular('${pkgs.libcap}/bin/capsh --has-p=CAP_SYS_ADMIN')) 115 machine.succeed(cmd_as_regular('/run/wrappers/bin/capsh_with_chown --has-p=CAP_CHOWN')) 116 machine.fail(cmd_as_regular('/run/wrappers/bin/capsh_with_chown --has-p=CAP_SYS_ADMIN')) 117 118 # Test that the only user of apparmor policy includes generated by 119 # wrappers works. Ideally this'd be located in a test for the module that 120 # actually makes the apparmor policy for ping, but there's no convenient 121 # test for that one. 122 machine.succeed("ping -c 1 127.0.0.1") 123 124 # Test that the disabled wrapper is not present. 125 machine.fail("test -e /run/wrappers/bin/disabled_busybox") 126 ''; 127 } 128)