1#!/usr/bin/env bash 2# SPDX-License-Identifier: LGPL-2.1-or-later 3# shellcheck disable=SC2016 4set -eux 5 6systemd-analyze log-level debug 7export SYSTEMD_LOG_LEVEL=debug 8 9mkdir -p /tmp/img/usr/lib/systemd/system/ 10mkdir -p /tmp/img/opt/ 11 12touch /tmp/img/opt/script0.sh 13chmod +x /tmp/img/opt/script0.sh 14 15cat <<EOF >/tmp/img/usr/lib/systemd/system/testfile.service 16[Service] 17ExecStart = /opt/script0.sh 18EOF 19 20set +e 21# Default behaviour is to recurse through all dependencies when unit is loaded 22systemd-analyze verify --root=/tmp/img/ testfile.service \ 23 && { echo 'unexpected success'; exit 1; } 24 25# As above, recurses through all dependencies when unit is loaded 26systemd-analyze verify --recursive-errors=yes --root=/tmp/img/ testfile.service \ 27 && { echo 'unexpected success'; exit 1; } 28 29# Recurses through unit file and its direct dependencies when unit is loaded 30systemd-analyze verify --recursive-errors=one --root=/tmp/img/ testfile.service \ 31 && { echo 'unexpected success'; exit 1; } 32 33set -e 34 35# zero exit status since dependencies are ignored when unit is loaded 36systemd-analyze verify --recursive-errors=no --root=/tmp/img/ testfile.service 37 38rm /tmp/img/usr/lib/systemd/system/testfile.service 39 40cat <<EOF >/tmp/testfile.service 41[Unit] 42foo = bar 43 44[Service] 45ExecStart = echo hello 46EOF 47 48cat <<EOF >/tmp/testfile2.service 49[Unit] 50Requires = testfile.service 51 52[Service] 53ExecStart = echo hello 54EOF 55 56# Zero exit status since no additional dependencies are recursively loaded when the unit file is loaded 57systemd-analyze verify --recursive-errors=no /tmp/testfile2.service 58 59set +e 60# Non-zero exit status since all associated dependencies are recursively loaded when the unit file is loaded 61systemd-analyze verify --recursive-errors=yes /tmp/testfile2.service \ 62 && { echo 'unexpected success'; exit 1; } 63set -e 64 65rm /tmp/testfile.service 66rm /tmp/testfile2.service 67 68cat <<EOF >/tmp/testfile.service 69[Service] 70ExecStart = echo hello 71DeviceAllow=/dev/sda 72EOF 73 74# Prevent regression from #13380 and #20859 where we can't verify hidden files 75cp /tmp/testfile.service /tmp/.testfile.service 76 77systemd-analyze verify /tmp/.testfile.service 78 79rm /tmp/.testfile.service 80 81# Alias a unit file's name on disk (see #20061) 82cp /tmp/testfile.service /tmp/testsrvc 83 84systemd-analyze verify /tmp/testsrvc \ 85 && { echo 'unexpected success'; exit 1; } 86 87systemd-analyze verify /tmp/testsrvc:alias.service 88 89# Zero exit status since the value used for comparison determine exposure to security threats is by default 100 90systemd-analyze security --offline=true /tmp/testfile.service 91 92set +e 93#The overall exposure level assigned to the unit is greater than the set threshold 94systemd-analyze security --threshold=90 --offline=true /tmp/testfile.service \ 95 && { echo 'unexpected success'; exit 1; } 96set -e 97 98# Ensure we print the list of ACLs, see https://github.com/systemd/systemd/issues/23185 99systemd-analyze security --offline=true /tmp/testfile.service | grep -q -F "/dev/sda" 100 101rm /tmp/testfile.service 102 103cat <<EOF >/tmp/img/usr/lib/systemd/system/testfile.service 104[Service] 105ExecStart = echo hello 106PrivateNetwork = yes 107PrivateDevices = yes 108PrivateUsers = yes 109EOF 110 111# The new overall exposure level assigned to the unit is less than the set thresholds 112# Verifies that the --offline= option works with --root= 113systemd-analyze security --threshold=90 --offline=true --root=/tmp/img/ testfile.service 114 115# Added an additional "INVALID_ID" id to the .json to verify that nothing breaks when input is malformed 116# The PrivateNetwork id description and weight was changed to verify that 'security' is actually reading in 117# values from the .json file when required. The default weight for "PrivateNetwork" is 2500, and the new weight 118# assigned to that id in the .json file is 6000. This increased weight means that when the "PrivateNetwork" key is 119# set to 'yes' (as above in the case of testfile.service) in the content of the unit file, the overall exposure 120# level for the unit file should decrease to account for that increased weight. 121cat <<EOF >/tmp/testfile.json 122{"UserOrDynamicUser": 123 {"description_bad": "Service runs as root user", 124 "weight": 0, 125 "range": 10 126 }, 127"SupplementaryGroups": 128 {"description_good": "Service has no supplementary groups", 129 "description_bad": "Service runs with supplementary groups", 130 "description_na": "Service runs as root, option does not matter", 131 "weight": 200, 132 "range": 1 133 }, 134"PrivateDevices": 135 {"description_good": "Service has no access to hardware devices", 136 "description_bad": "Service potentially has access to hardware devices", 137 "weight": 1000, 138 "range": 1 139 }, 140"PrivateMounts": 141 {"description_good": "Service cannot install system mounts", 142 "description_bad": "Service may install system mounts", 143 "weight": 1000, 144 "range": 1 145 }, 146"PrivateNetwork": 147 {"description_good": "Service doesn't have access to the host's network", 148 "description_bad": "Service has access to the host's network", 149 "weight": 6000, 150 "range": 1 151 }, 152"PrivateTmp": 153 {"description_good": "Service has no access to other software's temporary files", 154 "description_bad": "Service has access to other software's temporary files", 155 "weight": 1000, 156 "range": 1 157 }, 158"PrivateUsers": 159 {"description_good": "Service does not have access to other users", 160 "description_bad": "Service has access to other users", 161 "weight": 1000, 162 "range": 1 163 }, 164"ProtectControlGroups": 165 {"description_good": "Service cannot modify the control group file system", 166 "description_bad": "Service may modify the control group file system", 167 "weight": 1000, 168 "range": 1 169 }, 170"ProtectKernelModules": 171 {"description_good": "Service cannot load or read kernel modules", 172 "description_bad": "Service may load or read kernel modules", 173 "weight": 1000, 174 "range": 1 175 }, 176"ProtectKernelTunables": 177 {"description_good": "Service cannot alter kernel tunables (/proc/sys, …)", 178 "description_bad": "Service may alter kernel tunables", 179 "weight": 1000, 180 "range": 1 181 }, 182"ProtectKernelLogs": 183 {"description_good": "Service cannot read from or write to the kernel log ring buffer", 184 "description_bad": "Service may read from or write to the kernel log ring buffer", 185 "weight": 1000, 186 "range": 1 187 }, 188"ProtectClock": 189 {"description_good": "Service cannot write to the hardware clock or system clock", 190 "description_bad": "Service may write to the hardware clock or system clock", 191 "weight": 1000, 192 "range": 1 193 }, 194"ProtectHome": 195 {"weight": 1000, 196 "range": 10 197 }, 198"ProtectHostname": 199 {"description_good": "Service cannot change system host/domainname", 200 "description_bad": "Service may change system host/domainname", 201 "weight": 50, 202 "range": 1 203 }, 204"ProtectSystem": 205 {"weight": 1000, 206 "range": 10 207 }, 208"RootDirectoryOrRootImage": 209 {"description_good": "Service has its own root directory/image", 210 "description_bad": "Service runs within the host's root directory", 211 "weight": 200, 212 "range": 1 213 }, 214"LockPersonality": 215 {"description_good": "Service cannot change ABI personality", 216 "description_bad": "Service may change ABI personality", 217 "weight": 100, 218 "range": 1 219 }, 220"MemoryDenyWriteExecute": 221 {"description_good": "Service cannot create writable executable memory mappings", 222 "description_bad": "Service may create writable executable memory mappings", 223 "weight": 100, 224 "range": 1 225 }, 226"NoNewPrivileges": 227 {"description_good": "Service processes cannot acquire new privileges", 228 "description_bad": "Service processes may acquire new privileges", 229 "weight": 1000, 230 "range": 1 231 }, 232"CapabilityBoundingSet_CAP_SYS_ADMIN": 233 {"description_good": "Service has no administrator privileges", 234 "description_bad": "Service has administrator privileges", 235 "weight": 1500, 236 "range": 1 237 }, 238"CapabilityBoundingSet_CAP_SET_UID_GID_PCAP": 239 {"description_good": "Service cannot change UID/GID identities/capabilities", 240 "description_bad": "Service may change UID/GID identities/capabilities", 241 "weight": 1500, 242 "range": 1 243 }, 244"CapabilityBoundingSet_CAP_SYS_PTRACE": 245 {"description_good": "Service has no ptrace() debugging abilities", 246 "description_bad": "Service has ptrace() debugging abilities", 247 "weight": 1500, 248 "range": 1 249 }, 250"CapabilityBoundingSet_CAP_SYS_TIME": 251 {"description_good": "Service processes cannot change the system clock", 252 "description_bad": "Service processes may change the system clock", 253 "weight": 1000, 254 "range": 1 255 }, 256"CapabilityBoundingSet_CAP_NET_ADMIN": 257 {"description_good": "Service has no network configuration privileges", 258 "description_bad": "Service has network configuration privileges", 259 "weight": 1000, 260 "range": 1 261 }, 262"CapabilityBoundingSet_CAP_SYS_RAWIO": 263 {"description_good": "Service has no raw I/O access", 264 "description_bad": "Service has raw I/O access", 265 "weight": 1000, 266 "range": 1 267 }, 268"CapabilityBoundingSet_CAP_SYS_MODULE": 269 {"description_good": "Service cannot load kernel modules", 270 "description_bad": "Service may load kernel modules", 271 "weight": 1000, 272 "range": 1 273 }, 274"CapabilityBoundingSet_CAP_AUDIT": 275 {"description_good": "Service has no audit subsystem access", 276 "description_bad": "Service has audit subsystem access", 277 "weight": 500, 278 "range": 1 279 }, 280"CapabilityBoundingSet_CAP_SYSLOG": 281 {"description_good": "Service has no access to kernel logging", 282 "description_bad": "Service has access to kernel logging", 283 "weight": 500, 284 "range": 1 285 }, 286"CapabilityBoundingSet_CAP_SYS_NICE_RESOURCE": 287 {"description_good": "Service has no privileges to change resource use parameters", 288 "description_bad": "Service has privileges to change resource use parameters", 289 "weight": 500, 290 "range": 1 291 }, 292"CapabilityBoundingSet_CAP_MKNOD": 293 {"description_good": "Service cannot create device nodes", 294 "description_bad": "Service may create device nodes", 295 "weight": 500, 296 "range": 1 297 }, 298"CapabilityBoundingSet_CAP_CHOWN_FSETID_SETFCAP": 299 {"description_good": "Service cannot change file ownership/access mode/capabilities", 300 "description_bad": "Service may change file ownership/access mode/capabilities unrestricted", 301 "weight": 1000, 302 "range": 1 303 }, 304"CapabilityBoundingSet_CAP_DAC_FOWNER_IPC_OWNER": 305 {"description_good": "Service cannot override UNIX file/IPC permission checks", 306 "description_bad": "Service may override UNIX file/IPC permission checks", 307 "weight": 1000, 308 "range": 1 309 }, 310"CapabilityBoundingSet_CAP_KILL": 311 {"description_good": "Service cannot send UNIX signals to arbitrary processes", 312 "description_bad": "Service may send UNIX signals to arbitrary processes", 313 "weight": 500, 314 "range": 1 315 }, 316"CapabilityBoundingSet_CAP_NET_BIND_SERVICE_BROADCAST_RAW": 317 {"description_good": "Service has no elevated networking privileges", 318 "description_bad": "Service has elevated networking privileges", 319 "weight": 500, 320 "range": 1 321 }, 322"CapabilityBoundingSet_CAP_SYS_BOOT": 323 {"description_good": "Service cannot issue reboot()", 324 "description_bad": "Service may issue reboot()", 325 "weight": 100, 326 "range": 1 327 }, 328"CapabilityBoundingSet_CAP_MAC": 329 {"description_good": "Service cannot adjust SMACK MAC", 330 "description_bad": "Service may adjust SMACK MAC", 331 "weight": 100, 332 "range": 1 333 }, 334"CapabilityBoundingSet_CAP_LINUX_IMMUTABLE": 335 {"description_good": "Service cannot mark files immutable", 336 "description_bad": "Service may mark files immutable", 337 "weight": 75, 338 "range": 1 339 }, 340"CapabilityBoundingSet_CAP_IPC_LOCK": 341 {"description_good": "Service cannot lock memory into RAM", 342 "description_bad": "Service may lock memory into RAM", 343 "weight": 50, 344 "range": 1 345 }, 346"CapabilityBoundingSet_CAP_SYS_CHROOT": 347 {"description_good": "Service cannot issue chroot()", 348 "description_bad": "Service may issue chroot()", 349 "weight": 50, 350 "range": 1 351 }, 352"CapabilityBoundingSet_CAP_BLOCK_SUSPEND": 353 {"description_good": "Service cannot establish wake locks", 354 "description_bad": "Service may establish wake locks", 355 "weight": 25, 356 "range": 1 357 }, 358"CapabilityBoundingSet_CAP_WAKE_ALARM": 359 {"description_good": "Service cannot program timers that wake up the system", 360 "description_bad": "Service may program timers that wake up the system", 361 "weight": 25, 362 "range": 1 363 }, 364"CapabilityBoundingSet_CAP_LEASE": 365 {"description_good": "Service cannot create file leases", 366 "description_bad": "Service may create file leases", 367 "weight": 25, 368 "range": 1 369 }, 370"CapabilityBoundingSet_CAP_SYS_TTY_CONFIG": 371 {"description_good": "Service cannot issue vhangup()", 372 "description_bad": "Service may issue vhangup()", 373 "weight": 25, 374 "range": 1 375 }, 376"CapabilityBoundingSet_CAP_SYS_PACCT": 377 {"description_good": "Service cannot use acct()", 378 "description_bad": "Service may use acct()", 379 "weight": 25, 380 "range": 1 381 }, 382"UMask": 383 {"weight": 100, 384 "range": 10 385 }, 386"KeyringMode": 387 {"description_good": "Service doesn't share key material with other services", 388 "description_bad": "Service shares key material with other service", 389 "weight": 1000, 390 "range": 1 391 }, 392"ProtectProc": 393 {"description_good": "Service has restricted access to process tree(/proc hidepid=)", 394 "description_bad": "Service has full access to process tree(/proc hidepid=)", 395 "weight": 1000, 396 "range": 3 397 }, 398"ProcSubset": 399 {"description_good": "Service has no access to non-process/proc files(/proc subset=)", 400 "description_bad": "Service has full access to non-process/proc files(/proc subset=)", 401 "weight": 10, 402 "range": 1 403 }, 404"NotifyAccess": 405 {"description_good": "Service child processes cannot alter service state", 406 "description_bad": "Service child processes may alter service state", 407 "weight": 1000, 408 "range": 1 409 }, 410"RemoveIPC": 411 {"description_good": "Service user cannot leave SysV IPC objects around", 412 "description_bad": "Service user may leave SysV IPC objects around", 413 "description_na": "Service runs as root, option does not apply", 414 "weight": 100, 415 "range": 1 416 }, 417"Delegate": 418 {"description_good": "Service does not maintain its own delegated control group subtree", 419 "description_bad": "Service maintains its own delegated control group subtree", 420 "weight": 100, 421 "range": 1 422 }, 423"RestrictRealtime": 424 {"description_good": "Service realtime scheduling access is restricted", 425 "description_bad": "Service may acquire realtime scheduling", 426 "weight": 500, 427 "range": 1 428 }, 429"RestrictSUIDSGID": 430 {"description_good": "SUID/SGIDfilecreationbyserviceisrestricted", 431 "description_bad": "ServicemaycreateSUID/SGIDfiles", 432 "weight": 1000, 433 "range": 1 434 }, 435"RestrictNamespaces_user": 436 {"description_good": "Servicecannotcreateusernamespaces", 437 "description_bad": "Servicemaycreateusernamespaces", 438 "weight": 1500, 439 "range": 1 440 }, 441"RestrictNamespaces_mnt": 442 {"description_good": "Service cannot create file system namespaces", 443 "description_bad": "Service may create file system namespaces", 444 "weight": 500, 445 "range": 1 446 }, 447"RestrictNamespaces_ipc": 448 {"description_good": "Service cannot create IPC namespaces", 449 "description_bad": "Service may create IPC namespaces", 450 "weight": 500, 451 "range": 1 452 }, 453"RestrictNamespaces_pid": 454 {"description_good": "Service cannot create process namespaces", 455 "description_bad": "Service may create process namespaces", 456 "weight": 500, 457 "range": 1 458 }, 459"RestrictNamespaces_cgroup": 460 {"description_good": "Service cannot create cgroup namespaces", 461 "description_bad": "Service may create cgroup namespaces", 462 "weight": 500, 463 "range": 1 464 }, 465"RestrictNamespaces_net": 466 {"description_good": "Service cannot create network namespaces", 467 "description_bad": "Service may create network namespaces", 468 "weight": 500, 469 "range": 1 470 }, 471"RestrictNamespaces_uts": 472 {"description_good": "Service cannot create hostname namespaces", 473 "description_bad": "Service may create hostname namespaces", 474 "weight": 100, 475 "range": 1 476 }, 477"RestrictAddressFamilies_AF_INET_INET6": 478 {"description_good": "Service cannot allocate Internet sockets", 479 "description_bad": "Service may allocate Internet sockets", 480 "weight": 1500, 481 "range": 1 482 }, 483"RestrictAddressFamilies_AF_UNIX": 484 {"description_good": "Service cannot allocate local sockets", 485 "description_bad": "Service may allocate local sockets", 486 "weight": 25, 487 "range": 1 488 }, 489"RestrictAddressFamilies_AF_NETLINK": 490 {"description_good": "Service cannot allocate netlink sockets", 491 "description_bad": "Service may allocate netlink sockets", 492 "weight": 200, 493 "range": 1 494 }, 495"RestrictAddressFamilies_AF_PACKET": 496 {"description_good": "Service cannot allocate packet sockets", 497 "description_bad": "Service may allocate packet sockets", 498 "weight": 1000, 499 "range": 1 500 }, 501"RestrictAddressFamilies_OTHER": 502 {"description_good": "Service cannot allocate exotic sockets", 503 "description_bad": "Service may allocate exotic sockets", 504 "weight": 1250, 505 "range": 1 506 }, 507"SystemCallArchitectures": 508 {"weight": 1000, 509 "range": 10 510 }, 511"SystemCallFilter_swap": 512 {"weight": 1000, 513 "range": 10 514 }, 515"SystemCallFilter_obsolete": 516 {"weight": 250, 517 "range": 10 518 }, 519"SystemCallFilter_clock": 520 {"weight": 1000, 521 "range": 10 522 }, 523"SystemCallFilter_cpu_emulation": 524 {"weight": 250, 525 "range": 10 526 }, 527"SystemCallFilter_debug": 528 {"weight": 1000, 529 "range": 10 530 }, 531"SystemCallFilter_mount": 532 {"weight": 1000, 533 "range": 10 534 }, 535"SystemCallFilter_module": 536 {"weight": 1000, 537 "range": 10 538 }, 539"SystemCallFilter_raw_io": 540 {"weight": 1000, 541 "range": 10 542 }, 543"SystemCallFilter_reboot": 544 {"weight": 1000, 545 "range": 10 546 }, 547"SystemCallFilter_privileged": 548 {"weight": 700, 549 "range": 10 550 }, 551"SystemCallFilter_resources": 552 {"weight": 700, 553 "range": 10 554 }, 555"IPAddressDeny": 556 {"weight": 1000, 557 "range": 10 558 }, 559"DeviceAllow": 560 {"weight": 1000, 561 "range": 10 562 }, 563"AmbientCapabilities": 564 {"description_good": "Service process does not receive ambient capabilities", 565 "description_bad": "Service process receives ambient capabilities", 566 "weight": 500, 567 "range": 1 568 }, 569"INVALID_ID": 570 {"weight": 1000, 571 "range": 10 572 } 573} 574EOF 575 576# Reads in custom security requirements from the parsed .json file and uses these for comparison 577systemd-analyze security --threshold=90 --offline=true \ 578 --security-policy=/tmp/testfile.json \ 579 --root=/tmp/img/ testfile.service 580 581# The strict profile adds a lot of sanboxing options 582systemd-analyze security --threshold=25 --offline=true \ 583 --security-policy=/tmp/testfile.json \ 584 --profile=strict \ 585 --root=/tmp/img/ testfile.service 586 587set +e 588# The trusted profile doesn't add any sanboxing options 589systemd-analyze security --threshold=25 --offline=true \ 590 --security-policy=/tmp/testfile.json \ 591 --profile=/usr/lib/systemd/portable/profile/trusted/service.conf \ 592 --root=/tmp/img/ testfile.service \ 593 && { echo 'unexpected success'; exit 1; } 594 595systemd-analyze security --threshold=50 --offline=true \ 596 --security-policy=/tmp/testfile.json \ 597 --root=/tmp/img/ testfile.service \ 598 && { echo 'unexpected success'; exit 1; } 599set -e 600 601rm /tmp/img/usr/lib/systemd/system/testfile.service 602 603if systemd-analyze --version | grep -q -F "+ELFUTILS"; then 604 systemd-analyze inspect-elf --json=short /lib/systemd/systemd | grep -q -F '"elfType":"executable"' 605fi 606 607systemd-analyze --threshold=90 security systemd-journald.service 608 609systemd-analyze log-level info 610 611echo OK >/testok 612 613exit 0 614