@@ -289,18 +289,20 @@ privileged_ok(no_new_privileges) {
289289}
290290
291291noNewPrivileges_ok (no_new_privileges) {
292- is_linux
293292 no_new_privileges
294293 input.noNewPrivileges
295294}
296295
297296noNewPrivileges_ok (no_new_privileges) {
297+ not no_new_privileges
298+ }
299+
300+ noNewPrivileges_ok_check (obj) {
298301 is_linux
299- no_new_privileges == false
302+ noNewPrivileges_ok (obj. no_new_privileges)
300303}
301304
302- noNewPrivileges_ok (no_new_privileges) {
303- # no-op for windows
305+ noNewPrivileges_ok_check (obj) {
304306 is_windows
305307}
306308
@@ -353,6 +355,7 @@ container_started {
353355default container_privileged := false
354356
355357container_privileged {
358+ is_linux
356359 data.metadata.started[input.containerID].privileged
357360}
358361
@@ -472,12 +475,6 @@ valid_caps_for_all(containers, privileged) := caps {
472475 caps := input.capabilities
473476}
474477
475- valid_caps_for_all (containers, privileged) := caps {
476- # no-op for windows
477- is_windows
478- caps := input.capabilities
479- }
480-
481478caps_ok (allowed_caps, requested_caps) {
482479 is_linux
483480 capsList_ok (allowed_caps.bounding, requested_caps.bounding)
@@ -552,13 +549,10 @@ create_container := {"metadata": [updateMatches, addStarted],
552549 # NB any change to these narrowing conditions should be reflected in
553550 # the error handling, such that error messaging correctly reflects
554551 # the narrowing process.
555- noNewPrivileges_ok (container.no_new_privileges )
552+ security_ok (container)
556553 user_ok (container.user)
557- privileged_ok (container.allow_elevated)
558554 workingDirectory_ok (container.working_dir)
559555 command_ok (container.command)
560- mountList_ok (container.mounts, container.allow_elevated)
561- seccomp_ok (container.seccomp_profile_sha256)
562556 ]
563557
564558 count (possible_after_initial_containers) > 0
@@ -575,7 +569,8 @@ create_container := {"metadata": [updateMatches, addStarted],
575569
576570 # check to see if the capabilities variables match, dropping
577571 # them if allowed (and necessary)
578- caps_result := possible_container_after_caps (possible_after_env_containers, input.privileged)
572+ is_exec_eval := false
573+ caps_result := possible_container_after_caps (possible_after_env_containers, is_exec_eval)
579574
580575 possible_after_caps_containers := caps_result.containers
581576 caps_list := caps_result.caps_list
@@ -601,34 +596,72 @@ create_container := {"metadata": [updateMatches, addStarted],
601596 " value" : containers,
602597 }
603598
604- addStarted := {
605- " name" : " started" ,
606- " action" : " add" ,
607- " key" : input.containerID,
608- " value" : {
609- " privileged" : input.privileged,
610- },
611- }
599+ addStarted := addStarted_filter
612600}
613- possible_container_after_caps (env_containers, privileged) := {
601+
602+ addStarted_filter := {
603+ " name" : " started" ,
604+ " action" : " add" ,
605+ " key" : input.containerID,
606+ " value" : {
607+ " privileged" : false ,
608+ },
609+ } {
610+ is_windows
611+ }
612+
613+ addStarted_filter := {
614+ " name" : " started" ,
615+ " action" : " add" ,
616+ " key" : input.containerID,
617+ " value" : {
618+ " privileged" : input.privileged,
619+ },
620+ } {
621+ is_linux
622+ }
623+
624+ security_ok (current_container) {
625+ is_linux
626+ noNewPrivileges_ok (current_container.no_new_privileges)
627+ privileged_ok (current_container.allow_elevated)
628+ seccomp_ok (current_container.seccomp_profile_sha256)
629+ mountList_ok (current_container.mounts, current_container.allow_elevated)
630+ }
631+
632+ security_ok (current_container) {
633+ is_windows
634+ }
635+
636+ possible_container_after_caps (env_containers, is_exec) := {
614637 " containers" : env_containers,
615638 " caps_list" : []
616639} {
617640 is_windows
618641}
619642
620- possible_container_after_caps (env_containers, privileged ) := {
643+ possible_container_after_caps (env_containers, is_exec ) := {
621644 " containers" : filtered,
622645 " caps_list" : caps_list
623646} {
624647 is_linux
625- caps_list := valid_caps_for_all (env_containers, privileged)
648+ is_privileged := get_privileged_value (is_exec)
649+
650+ caps_list := valid_caps_for_all (env_containers, is_privileged)
626651 filtered := [container |
627652 container := env_containers[_]
628- caps_ok (get_capabilities (container, privileged), caps_list)
653+ caps_ok (get_capabilities (container, input. privileged), caps_list)
629654 ]
630655}
631656
657+ get_privileged_value (is_exec) := container_privileged {
658+ is_exec
659+ }
660+
661+ get_privileged_value (is_exec) := input.privileged {
662+ not is_exec
663+ }
664+
632665mountSource_ok (constraint, source) {
633666 startswith (constraint, data.sandboxPrefix)
634667 newConstraint := replace (constraint, data.sandboxPrefix, input.sandboxDir)
@@ -723,7 +756,7 @@ exec_in_container := {"metadata": [updateMatches],
723756 # the error handling, such that error messaging correctly reflects
724757 # the narrowing process.
725758 workingDirectory_ok (container.working_dir)
726- noNewPrivileges_ok (container.no_new_privileges)
759+ # noNewPrivileges_ok(container.no_new_privileges)
727760 user_ok (container.user)
728761 some process in container.exec_processes
729762 command_ok (process.command)
@@ -743,7 +776,8 @@ exec_in_container := {"metadata": [updateMatches],
743776
744777 # check to see if the capabilities variables match, dropping
745778 # them if allowed (and necessary)
746- caps_result := possible_container_after_caps (possible_after_env_containers, container_privileged)
779+ is_exec_eval := true
780+ caps_result := possible_container_after_caps (possible_after_env_containers, is_exec_eval)
747781
748782 possible_after_caps_containers := caps_result.containers
749783 caps_list := caps_result.caps_list
@@ -761,6 +795,16 @@ exec_in_container := {"metadata": [updateMatches],
761795 }
762796}
763797
798+ noNewPrivileges (current_container) {
799+ is_linux
800+ current_container.no_new_privileges
801+ input.noNewPrivileges
802+ }
803+
804+ noNewPrivileges (current_container) {
805+ is_windows
806+ }
807+
764808default shutdown_container := {" allowed" : false }
765809
766810shutdown_container := {" started" : remove, " metadata" : [remove], " allowed" : true } {
@@ -1271,7 +1315,7 @@ errors["missing required environment variable"] {
12711315 not container_started
12721316 possible_containers := [container |
12731317 container := data.metadata.matches[input.containerID][_]
1274- noNewPrivileges_ok (container.no_new_privileges )
1318+ noNewPrivileges_ok_check (container)
12751319 user_ok (container.user)
12761320 privileged_ok (container.allow_elevated)
12771321 workingDirectory_ok (container.working_dir)
@@ -1303,7 +1347,7 @@ errors["missing required environment variable"] {
13031347 container_started
13041348 possible_containers := [container |
13051349 container := data.metadata.matches[input.containerID][_]
1306- noNewPrivileges_ok (container.no_new_privileges )
1350+ noNewPrivileges_ok_check (container)
13071351 user_ok (container.user)
13081352 workingDirectory_ok (container.working_dir)
13091353 some process in container.exec_processes
@@ -1529,19 +1573,21 @@ errors[fragment_framework_version_error] {
15291573}
15301574
15311575errors[" containers only distinguishable by allow_stdio_access" ] {
1532- is_linux
15331576 input.rule == " create_container"
15341577
1535- not container_started
1578+ not container_started
1579+
1580+ # narrow the matches based upon command, working directory, and
1581+ # mount list
15361582 possible_after_initial_containers := [container |
15371583 container := data.metadata.matches[input.containerID][_]
1538- noNewPrivileges_ok (container.no_new_privileges)
1584+ # NB any change to these narrowing conditions should be reflected in
1585+ # the error handling, such that error messaging correctly reflects
1586+ # the narrowing process.
1587+ security_ok (container)
15391588 user_ok (container.user)
1540- privileged_ok (container.allow_elevated)
15411589 workingDirectory_ok (container.working_dir)
15421590 command_ok (container.command)
1543- mountList_ok (container.mounts, container.allow_elevated)
1544- seccomp_ok (container.seccomp_profile_sha256)
15451591 ]
15461592
15471593 count (possible_after_initial_containers) > 0
@@ -1558,11 +1604,11 @@ errors["containers only distinguishable by allow_stdio_access"] {
15581604
15591605 # check to see if the capabilities variables match, dropping
15601606 # them if allowed (and necessary)
1561- caps_list := valid_caps_for_all (possible_after_env_containers, input.privileged)
1562- possible_after_caps_containers := [container |
1563- container := possible_after_env_containers[_]
1564- caps_ok ( get_capabilities (container, input.privileged), caps_list)
1565- ]
1607+ is_exec_eval := false
1608+ caps_result := possible_container_after_caps (possible_after_env_containers, is_exec_eval)
1609+
1610+ possible_after_caps_containers := caps_result.containers
1611+ caps_list := caps_result.caps_list
15661612
15671613 count (possible_after_caps_containers) > 0
15681614
@@ -1606,7 +1652,7 @@ default noNewPrivileges_matches := false
16061652noNewPrivileges_matches {
16071653 input.rule == " create_container"
16081654 some container in data.metadata.matches[input.containerID]
1609- noNewPrivileges_ok (container.no_new_privileges )
1655+ noNewPrivileges_ok_check (container)
16101656}
16111657
16121658noNewPrivileges_matches {
@@ -1615,7 +1661,7 @@ noNewPrivileges_matches {
16151661 some process in container.exec_processes
16161662 command_ok (process.command)
16171663 workingDirectory_ok (process.working_dir)
1618- noNewPrivileges_ok (process.no_new_privileges )
1664+ noNewPrivileges_ok_check (process)
16191665}
16201666
16211667errors[" invalid noNewPrivileges" ] {
0 commit comments