...

Source file src/github.com/Microsoft/hcsshim/pkg/securitypolicy/regopolicy_test.go

Documentation: github.com/Microsoft/hcsshim/pkg/securitypolicy

     1  //go:build linux && rego
     2  // +build linux,rego
     3  
     4  package securitypolicy
     5  
     6  import (
     7  	"context"
     8  	_ "embed"
     9  	"encoding/json"
    10  	"fmt"
    11  	"math/rand"
    12  	"sort"
    13  	"strconv"
    14  	"strings"
    15  	"syscall"
    16  	"testing"
    17  	"testing/quick"
    18  
    19  	"github.com/Microsoft/hcsshim/internal/guestpath"
    20  	rpi "github.com/Microsoft/hcsshim/internal/regopolicyinterpreter"
    21  	"github.com/blang/semver/v4"
    22  	"github.com/open-policy-agent/opa/rego"
    23  	oci "github.com/opencontainers/runtime-spec/specs-go"
    24  	"github.com/pkg/errors"
    25  )
    26  
    27  const (
    28  	// variables that influence generated rego-only test fixtures
    29  	maxDiffLength                              = 64
    30  	maxExternalProcessesInGeneratedConstraints = 16
    31  	maxFragmentsInGeneratedConstraints         = 4
    32  	maxGeneratedExternalProcesses              = 12
    33  	maxGeneratedSandboxIDLength                = 32
    34  	maxGeneratedEnforcementPointLength         = 64
    35  	maxGeneratedPlan9Mounts                    = 8
    36  	maxGeneratedFragmentFeedLength             = 256
    37  	maxGeneratedFragmentIssuerLength           = 16
    38  	maxPlan9MountTargetLength                  = 64
    39  	maxPlan9MountIndex                         = 16
    40  )
    41  
    42  func Test_RegoTemplates(t *testing.T) {
    43  	query := rego.New(
    44  		rego.Query("data.api"),
    45  		rego.Module("api.rego", APICode))
    46  
    47  	ctx := context.Background()
    48  	resultSet, err := query.Eval(ctx)
    49  	if err != nil {
    50  		t.Fatalf("unable to query API enforcement points: %s", err)
    51  	}
    52  
    53  	apiRules := resultSet[0].Expressions[0].Value.(map[string]interface{})
    54  	enforcementPoints := apiRules["enforcement_points"].(map[string]interface{})
    55  
    56  	policyCode := strings.Replace(policyRegoTemplate, "@@OBJECTS@@", "", 1)
    57  	policyCode = strings.Replace(policyCode, "@@API_VERSION@@", apiVersion, 1)
    58  	policyCode = strings.Replace(policyCode, "@@FRAMEWORK_VERSION@@", frameworkVersion, 1)
    59  
    60  	err = verifyPolicyRules(apiVersion, enforcementPoints, policyCode)
    61  	if err != nil {
    62  		t.Errorf("Policy Rego Template is invalid: %s", err)
    63  	}
    64  
    65  	err = verifyPolicyRules(apiVersion, enforcementPoints, openDoorRego)
    66  	if err != nil {
    67  		t.Errorf("Open Door Rego Template is invalid: %s", err)
    68  	}
    69  }
    70  
    71  func Test_MarshalRego_Policy(t *testing.T) {
    72  	f := func(p *generatedConstraints) bool {
    73  		p.externalProcesses = generateExternalProcesses(testRand)
    74  		for _, process := range p.externalProcesses {
    75  			// arbitrary environment variable rules for external
    76  			// processes are not currently handled by the config.
    77  			process.envRules = []EnvRuleConfig{{
    78  				Strategy: "string",
    79  				Rule:     "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    80  				Required: true,
    81  			}}
    82  		}
    83  
    84  		p.fragments = generateFragments(testRand, 1)
    85  
    86  		securityPolicy := p.toPolicy()
    87  		defaultMounts := toOCIMounts(generateMounts(testRand))
    88  		privilegedMounts := toOCIMounts(generateMounts(testRand))
    89  
    90  		expected := securityPolicy.marshalRego()
    91  
    92  		containers := make([]*Container, len(p.containers))
    93  		for i, container := range p.containers {
    94  			containers[i] = container.toContainer()
    95  		}
    96  
    97  		externalProcesses := make([]ExternalProcessConfig, len(p.externalProcesses))
    98  		for i, process := range p.externalProcesses {
    99  			externalProcesses[i] = process.toConfig()
   100  		}
   101  
   102  		fragments := make([]FragmentConfig, len(p.fragments))
   103  		for i, fragment := range p.fragments {
   104  			fragments[i] = fragment.toConfig()
   105  		}
   106  
   107  		actual, err := MarshalPolicy(
   108  			"rego",
   109  			false,
   110  			containers,
   111  			externalProcesses,
   112  			fragments,
   113  			p.allowGetProperties,
   114  			p.allowDumpStacks,
   115  			p.allowRuntimeLogging,
   116  			p.allowEnvironmentVariableDropping,
   117  			p.allowUnencryptedScratch,
   118  			p.allowCapabilityDropping,
   119  		)
   120  		if err != nil {
   121  			t.Error(err)
   122  			return false
   123  		}
   124  
   125  		if actual != expected {
   126  			start := -1
   127  			end := -1
   128  			for i := 0; i < len(actual) && i < len(expected); i++ {
   129  				if actual[i] != expected[i] {
   130  					if start == -1 {
   131  						start = i
   132  					} else if i-start >= maxDiffLength {
   133  						end = i
   134  						break
   135  					}
   136  				} else if start != -1 {
   137  					end = i
   138  					break
   139  				}
   140  			}
   141  			start = start - 512
   142  			if start < 0 {
   143  				start = 0
   144  			}
   145  			t.Errorf(`MarshalPolicy does not create the expected Rego policy [%d-%d]: "%s" != "%s"`, start, end, actual[start:end], expected[start:end])
   146  			return false
   147  		}
   148  
   149  		_, err = newRegoPolicy(expected, defaultMounts, privilegedMounts)
   150  		if err != nil {
   151  			t.Errorf("unable to convert policy to rego: %v", err)
   152  			return false
   153  		}
   154  
   155  		return true
   156  	}
   157  
   158  	if err := quick.Check(f, &quick.Config{MaxCount: 4, Rand: testRand}); err != nil {
   159  		t.Errorf("Test_MarshalRego_Policy failed: %v", err)
   160  	}
   161  }
   162  
   163  func Test_MarshalRego_Fragment(t *testing.T) {
   164  	f := func(p *generatedConstraints) bool {
   165  		p.externalProcesses = generateExternalProcesses(testRand)
   166  		for _, process := range p.externalProcesses {
   167  			// arbitrary environment variable rules for external
   168  			// processes are not currently handled by the config.
   169  			process.envRules = []EnvRuleConfig{{
   170  				Strategy: "string",
   171  				Rule:     "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
   172  				Required: true,
   173  			}}
   174  		}
   175  
   176  		p.fragments = generateFragments(testRand, 1)
   177  
   178  		fragment := p.toFragment()
   179  		expected := fragment.marshalRego()
   180  
   181  		containers := make([]*Container, len(p.containers))
   182  		for i, container := range p.containers {
   183  			containers[i] = container.toContainer()
   184  		}
   185  
   186  		externalProcesses := make([]ExternalProcessConfig, len(p.externalProcesses))
   187  		for i, process := range p.externalProcesses {
   188  			externalProcesses[i] = process.toConfig()
   189  		}
   190  
   191  		fragments := make([]FragmentConfig, len(p.fragments))
   192  		for i, fragment := range p.fragments {
   193  			fragments[i] = fragment.toConfig()
   194  		}
   195  
   196  		actual, err := MarshalFragment(p.namespace, p.svn, containers, externalProcesses, fragments)
   197  		if err != nil {
   198  			t.Error(err)
   199  			return false
   200  		}
   201  
   202  		if actual != expected {
   203  			start := -1
   204  			end := -1
   205  			for i := 0; i < len(actual) && i < len(expected); i++ {
   206  				if actual[i] != expected[i] {
   207  					if start == -1 {
   208  						start = i
   209  					} else if i-start >= maxDiffLength {
   210  						end = i
   211  						break
   212  					}
   213  				} else if start != -1 {
   214  					end = i
   215  					break
   216  				}
   217  			}
   218  			t.Errorf("MarshalFragment does not create the expected Rego fragment [%d-%d]: %s != %s", start, end, actual[start:end], expected[start:end])
   219  			return false
   220  		}
   221  
   222  		return true
   223  	}
   224  
   225  	if err := quick.Check(f, &quick.Config{MaxCount: 4, Rand: testRand}); err != nil {
   226  		t.Errorf("Test_MarshalRego_Fragment failed: %v", err)
   227  	}
   228  }
   229  
   230  // Verify that RegoSecurityPolicyEnforcer.EnforceDeviceMountPolicy will
   231  // return an error when there's no matching root hash in the policy
   232  func Test_Rego_EnforceDeviceMountPolicy_No_Matches(t *testing.T) {
   233  	f := func(p *generatedConstraints) bool {
   234  		securityPolicy := p.toPolicy()
   235  		policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
   236  		if err != nil {
   237  			t.Errorf("unable to convert policy to rego: %v", err)
   238  			return false
   239  		}
   240  
   241  		target := testDataGenerator.uniqueMountTarget()
   242  		rootHash := generateInvalidRootHash(testRand)
   243  
   244  		err = policy.EnforceDeviceMountPolicy(p.ctx, target, rootHash)
   245  
   246  		// we expect an error, not getting one means something is broken
   247  		return assertDecisionJSONContains(t, err, rootHash, "deviceHash not found")
   248  	}
   249  
   250  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   251  		t.Errorf("Test_Rego_EnforceDeviceMountPolicy_No_Matches failed: %v", err)
   252  	}
   253  }
   254  
   255  // Verify that RegoSecurityPolicyEnforcer.EnforceDeviceMountPolicy doesn't
   256  // return an error when there's a matching root hash in the policy
   257  func Test_Rego_EnforceDeviceMountPolicy_Matches(t *testing.T) {
   258  	f := func(p *generatedConstraints) bool {
   259  		securityPolicy := p.toPolicy()
   260  		policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
   261  		if err != nil {
   262  			t.Errorf("unable to convert policy to rego: %v", err)
   263  			return false
   264  		}
   265  
   266  		target := testDataGenerator.uniqueMountTarget()
   267  		rootHash := selectRootHashFromConstraints(p, testRand)
   268  
   269  		err = policy.EnforceDeviceMountPolicy(p.ctx, target, rootHash)
   270  
   271  		// getting an error means something is broken
   272  		return err == nil
   273  	}
   274  
   275  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   276  		t.Errorf("Test_Rego_EnforceDeviceMountPolicy_Matches failed: %v", err)
   277  	}
   278  }
   279  
   280  func Test_Rego_EnforceDeviceUmountPolicy_Removes_Device_Entries(t *testing.T) {
   281  	f := func(p *generatedConstraints) bool {
   282  		securityPolicy := p.toPolicy()
   283  		policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
   284  		if err != nil {
   285  			t.Error(err)
   286  			return false
   287  		}
   288  
   289  		target := testDataGenerator.uniqueMountTarget()
   290  		rootHash := selectRootHashFromConstraints(p, testRand)
   291  
   292  		err = policy.EnforceDeviceMountPolicy(p.ctx, target, rootHash)
   293  		if err != nil {
   294  			t.Errorf("unable to mount device: %v", err)
   295  			return false
   296  		}
   297  
   298  		err = policy.EnforceDeviceUnmountPolicy(p.ctx, target)
   299  		if err != nil {
   300  			t.Errorf("unable to unmount device: %v", err)
   301  			return false
   302  		}
   303  
   304  		err = policy.EnforceDeviceMountPolicy(p.ctx, target, rootHash)
   305  		if err != nil {
   306  			t.Errorf("unable to remount device: %v", err)
   307  			return false
   308  		}
   309  
   310  		return true
   311  	}
   312  
   313  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   314  		t.Errorf("Test_Rego_EnforceDeviceUmountPolicy_Removes_Device_Entries failed: %v", err)
   315  	}
   316  }
   317  
   318  func Test_Rego_EnforceDeviceMountPolicy_Duplicate_Device_Target(t *testing.T) {
   319  	f := func(p *generatedConstraints) bool {
   320  		securityPolicy := p.toPolicy()
   321  		policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
   322  		if err != nil {
   323  			t.Errorf("unable to convert policy to rego: %v", err)
   324  			return false
   325  		}
   326  
   327  		target := testDataGenerator.uniqueMountTarget()
   328  		rootHash := selectRootHashFromConstraints(p, testRand)
   329  		err = policy.EnforceDeviceMountPolicy(p.ctx, target, rootHash)
   330  		if err != nil {
   331  			t.Error("Valid device mount failed. It shouldn't have.")
   332  			return false
   333  		}
   334  
   335  		rootHash = selectRootHashFromConstraints(p, testRand)
   336  		err = policy.EnforceDeviceMountPolicy(p.ctx, target, rootHash)
   337  		if err == nil {
   338  			t.Error("Duplicate device mount target was allowed. It shouldn't have been.")
   339  			return false
   340  		}
   341  
   342  		return assertDecisionJSONContains(t, err, "device already mounted at path")
   343  	}
   344  
   345  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   346  		t.Errorf("Test_Rego_EnforceDeviceMountPolicy_Duplicate_Device_Target failed: %v", err)
   347  	}
   348  }
   349  
   350  // Verify that RegoSecurityPolicyEnforcer.EnforceOverlayMountPolicy will
   351  // return an error when there's no matching overlay targets.
   352  func Test_Rego_EnforceOverlayMountPolicy_No_Matches(t *testing.T) {
   353  	f := func(p *generatedConstraints) bool {
   354  		tc, err := setupRegoOverlayTest(p, false)
   355  		if err != nil {
   356  			t.Error(err)
   357  			return false
   358  		}
   359  
   360  		err = tc.policy.EnforceOverlayMountPolicy(p.ctx, tc.containerID, tc.layers, testDataGenerator.uniqueMountTarget())
   361  
   362  		if err == nil {
   363  			return false
   364  		}
   365  
   366  		toFind := []string{"no matching containers for overlay"}
   367  		if len(tc.layers) > 0 {
   368  			toFind = append(toFind, tc.layers[0])
   369  		}
   370  
   371  		return assertDecisionJSONContains(t, err, toFind...)
   372  	}
   373  
   374  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   375  		t.Errorf("Test_Rego_EnforceOverlayMountPolicy_No_Matches failed: %v", err)
   376  	}
   377  }
   378  
   379  // Verify that RegoSecurityPolicyEnforcer.EnforceOverlayMountPolicy doesn't
   380  // return an error when there's a valid overlay target.
   381  func Test_Rego_EnforceOverlayMountPolicy_Matches(t *testing.T) {
   382  	f := func(p *generatedConstraints) bool {
   383  		tc, err := setupRegoOverlayTest(p, true)
   384  		if err != nil {
   385  			t.Error(err)
   386  			return false
   387  		}
   388  
   389  		err = tc.policy.EnforceOverlayMountPolicy(p.ctx, tc.containerID, tc.layers, testDataGenerator.uniqueMountTarget())
   390  
   391  		// getting an error means something is broken
   392  		return err == nil
   393  	}
   394  
   395  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   396  		t.Errorf("Test_Rego_EnforceOverlayMountPolicy_Matches: %v", err)
   397  	}
   398  }
   399  
   400  // Test that an image that contains layers that share a roothash value can be
   401  // successfully mounted. This was a failure scenario in an earlier policy engine
   402  // implementation.
   403  func Test_Rego_EnforceOverlayMountPolicy_Layers_With_Same_Root_Hash(t *testing.T) {
   404  
   405  	container := generateConstraintsContainer(testRand, 2, maxLayersInGeneratedContainer)
   406  
   407  	// make the last two layers have the same hash value
   408  	numLayers := len(container.Layers)
   409  	container.Layers[numLayers-2] = container.Layers[numLayers-1]
   410  
   411  	constraints := new(generatedConstraints)
   412  	constraints.ctx = context.Background()
   413  	constraints.containers = []*securityPolicyContainer{container}
   414  	constraints.externalProcesses = generateExternalProcesses(testRand)
   415  	securityPolicy := constraints.toPolicy()
   416  	policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
   417  	if err != nil {
   418  		t.Fatal("Unable to create security policy")
   419  	}
   420  
   421  	containerID := testDataGenerator.uniqueContainerID()
   422  
   423  	layers, err := testDataGenerator.createValidOverlayForContainer(policy, container)
   424  	if err != nil {
   425  		t.Fatalf("error creating valid overlay: %v", err)
   426  	}
   427  
   428  	err = policy.EnforceOverlayMountPolicy(constraints.ctx, containerID, layers, testDataGenerator.uniqueMountTarget())
   429  	if err != nil {
   430  		t.Fatalf("Unable to create an overlay where root hashes are the same")
   431  	}
   432  }
   433  
   434  // Test that can we mount overlays across containers where some layers are
   435  // shared and on the same device. A common example of this is a base image that
   436  // is used by many containers.
   437  // The setup for this test is rather complicated
   438  func Test_Rego_EnforceOverlayMountPolicy_Layers_Shared_Layers(t *testing.T) {
   439  	containerOne := generateConstraintsContainer(testRand, 1, 2)
   440  	containerTwo := generateConstraintsContainer(testRand, 1, 10)
   441  
   442  	sharedLayerIndex := 0
   443  
   444  	// Make the two containers have the same base layer
   445  	containerTwo.Layers[sharedLayerIndex] = containerOne.Layers[sharedLayerIndex]
   446  	constraints := new(generatedConstraints)
   447  	constraints.ctx = context.Background()
   448  	constraints.containers = []*securityPolicyContainer{containerOne, containerTwo}
   449  	constraints.externalProcesses = generateExternalProcesses(testRand)
   450  
   451  	securityPolicy := constraints.toPolicy()
   452  	policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
   453  	if err != nil {
   454  		t.Fatal("Unable to create security policy")
   455  	}
   456  
   457  	//
   458  	// Mount our first containers overlay. This should all work.
   459  	//
   460  	containerID := testDataGenerator.uniqueContainerID()
   461  
   462  	// Create overlay
   463  	containerOneOverlay := make([]string, len(containerOne.Layers))
   464  
   465  	sharedMount := ""
   466  	for i := 0; i < len(containerOne.Layers); i++ {
   467  		mount := testDataGenerator.uniqueMountTarget()
   468  		err := policy.EnforceDeviceMountPolicy(constraints.ctx, mount, containerOne.Layers[i])
   469  		if err != nil {
   470  			t.Fatalf("Unexpected error mounting overlay device: %v", err)
   471  		}
   472  		if i == sharedLayerIndex {
   473  			sharedMount = mount
   474  		}
   475  
   476  		containerOneOverlay[len(containerOneOverlay)-i-1] = mount
   477  	}
   478  
   479  	err = policy.EnforceOverlayMountPolicy(constraints.ctx, containerID, containerOneOverlay, testDataGenerator.uniqueMountTarget())
   480  	if err != nil {
   481  		t.Fatalf("Unexpected error mounting overlay: %v", err)
   482  	}
   483  
   484  	//
   485  	// Mount our second contaniers overlay. This should all work.
   486  	//
   487  	containerID = testDataGenerator.uniqueContainerID()
   488  
   489  	// Create overlay
   490  	containerTwoOverlay := make([]string, len(containerTwo.Layers))
   491  
   492  	for i := 0; i < len(containerTwo.Layers); i++ {
   493  		var mount string
   494  		if i != sharedLayerIndex {
   495  			mount = testDataGenerator.uniqueMountTarget()
   496  
   497  			err := policy.EnforceDeviceMountPolicy(constraints.ctx, mount, containerTwo.Layers[i])
   498  			if err != nil {
   499  				t.Fatalf("Unexpected error mounting overlay device: %v", err)
   500  			}
   501  		} else {
   502  			mount = sharedMount
   503  		}
   504  
   505  		containerTwoOverlay[len(containerTwoOverlay)-i-1] = mount
   506  	}
   507  
   508  	err = policy.EnforceOverlayMountPolicy(constraints.ctx, containerID, containerTwoOverlay, testDataGenerator.uniqueMountTarget())
   509  	if err != nil {
   510  		t.Fatalf("Unexpected error mounting overlay: %v", err)
   511  	}
   512  
   513  	// A final sanity check that we really had a shared mount
   514  	if containerOneOverlay[len(containerOneOverlay)-1] != containerTwoOverlay[len(containerTwoOverlay)-1] {
   515  		t.Fatal("Ooops. Looks like we botched our test setup.")
   516  	}
   517  }
   518  
   519  // Tests the specific case of trying to mount the same overlay twice using the
   520  // same container id. This should be disallowed.
   521  func Test_Rego_EnforceOverlayMountPolicy_Overlay_Single_Container_Twice(t *testing.T) {
   522  	f := func(p *generatedConstraints) bool {
   523  		tc, err := setupRegoOverlayTest(p, true)
   524  		if err != nil {
   525  			t.Error(err)
   526  			return false
   527  		}
   528  
   529  		if err := tc.policy.EnforceOverlayMountPolicy(p.ctx, tc.containerID, tc.layers, testDataGenerator.uniqueMountTarget()); err != nil {
   530  			t.Errorf("expected nil error got: %v", err)
   531  			return false
   532  		}
   533  
   534  		if err := tc.policy.EnforceOverlayMountPolicy(p.ctx, tc.containerID, tc.layers, testDataGenerator.uniqueMountTarget()); err == nil {
   535  			t.Errorf("able to create overlay for the same container twice")
   536  			return false
   537  		} else {
   538  			return assertDecisionJSONContains(t, err, "overlay has already been mounted")
   539  		}
   540  	}
   541  
   542  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   543  		t.Errorf("Test_Rego_EnforceOverlayMountPolicy_Overlay_Single_Container_Twice: %v", err)
   544  	}
   545  }
   546  
   547  func Test_Rego_EnforceOverlayMountPolicy_Reusing_ID_Across_Overlays(t *testing.T) {
   548  	constraints := new(generatedConstraints)
   549  	constraints.ctx = context.Background()
   550  	for i := 0; i < 2; i++ {
   551  		constraints.containers = append(constraints.containers, generateConstraintsContainer(testRand, 1, maxLayersInGeneratedContainer))
   552  	}
   553  
   554  	constraints.externalProcesses = generateExternalProcesses(testRand)
   555  
   556  	securityPolicy := constraints.toPolicy()
   557  	defaultMounts := generateMounts(testRand)
   558  	privilegedMounts := generateMounts(testRand)
   559  
   560  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
   561  		toOCIMounts(defaultMounts),
   562  		toOCIMounts(privilegedMounts))
   563  	if err != nil {
   564  		t.Fatal(err)
   565  	}
   566  
   567  	containerID := testDataGenerator.uniqueContainerID()
   568  
   569  	// First usage should work
   570  	layerPaths, err := testDataGenerator.createValidOverlayForContainer(policy, constraints.containers[0])
   571  	if err != nil {
   572  		t.Fatalf("Unexpected error creating valid overlay: %v", err)
   573  	}
   574  
   575  	err = policy.EnforceOverlayMountPolicy(constraints.ctx, containerID, layerPaths, testDataGenerator.uniqueMountTarget())
   576  	if err != nil {
   577  		t.Fatalf("Unexpected error mounting overlay filesystem: %v", err)
   578  	}
   579  
   580  	// Reusing container ID with another overlay should fail
   581  	layerPaths, err = testDataGenerator.createValidOverlayForContainer(policy, constraints.containers[1])
   582  	if err != nil {
   583  		t.Fatalf("Unexpected error creating valid overlay: %v", err)
   584  	}
   585  
   586  	err = policy.EnforceOverlayMountPolicy(constraints.ctx, containerID, layerPaths, testDataGenerator.uniqueMountTarget())
   587  	if err == nil {
   588  		t.Fatalf("Unexpected success mounting overlay filesystem")
   589  	}
   590  }
   591  
   592  // work directly on the internal containers
   593  // Test that if more than 1 instance of the same image is started, that we can
   594  // create all the overlays that are required. So for example, if there are
   595  // 13 instances of image X that all share the same overlay of root hashes,
   596  // all 13 should be allowed.
   597  func Test_Rego_EnforceOverlayMountPolicy_Multiple_Instances_Same_Container(t *testing.T) {
   598  	for containersToCreate := 13; containersToCreate <= maxContainersInGeneratedConstraints; containersToCreate++ {
   599  		constraints := new(generatedConstraints)
   600  		constraints.ctx = context.Background()
   601  		constraints.externalProcesses = generateExternalProcesses(testRand)
   602  
   603  		for i := 1; i <= containersToCreate; i++ {
   604  			arg := "command " + strconv.Itoa(i)
   605  			c := &securityPolicyContainer{
   606  				Command: []string{arg},
   607  				Layers:  []string{"1", "2"},
   608  			}
   609  
   610  			constraints.containers = append(constraints.containers, c)
   611  		}
   612  
   613  		securityPolicy := constraints.toPolicy()
   614  		policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
   615  		if err != nil {
   616  			t.Fatalf("failed create enforcer")
   617  		}
   618  
   619  		for i := 0; i < len(constraints.containers); i++ {
   620  			layerPaths, err := testDataGenerator.createValidOverlayForContainer(policy, constraints.containers[i])
   621  			if err != nil {
   622  				t.Fatal("unexpected error on test setup")
   623  			}
   624  
   625  			id := testDataGenerator.uniqueContainerID()
   626  			err = policy.EnforceOverlayMountPolicy(constraints.ctx, id, layerPaths, testDataGenerator.uniqueMountTarget())
   627  			if err != nil {
   628  				t.Fatalf("failed with %d containers", containersToCreate)
   629  			}
   630  		}
   631  	}
   632  }
   633  
   634  func Test_Rego_EnforceOverlayUnmountPolicy(t *testing.T) {
   635  	f := func(p *generatedConstraints) bool {
   636  		tc, err := setupRegoOverlayTest(p, true)
   637  		if err != nil {
   638  			t.Error(err)
   639  			return false
   640  		}
   641  
   642  		target := testDataGenerator.uniqueMountTarget()
   643  		err = tc.policy.EnforceOverlayMountPolicy(p.ctx, tc.containerID, tc.layers, target)
   644  		if err != nil {
   645  			t.Errorf("Failure setting up overlay for testing: %v", err)
   646  			return false
   647  		}
   648  
   649  		err = tc.policy.EnforceOverlayUnmountPolicy(p.ctx, target)
   650  		if err != nil {
   651  			t.Errorf("Unexpected policy enforcement failure: %v", err)
   652  			return false
   653  		}
   654  
   655  		return true
   656  	}
   657  
   658  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   659  		t.Errorf("Test_Rego_EnforceOverlayUnmountPolicy: %v", err)
   660  	}
   661  }
   662  
   663  func Test_Rego_EnforceOverlayUnmountPolicy_No_Matches(t *testing.T) {
   664  	f := func(p *generatedConstraints) bool {
   665  		tc, err := setupRegoOverlayTest(p, true)
   666  		if err != nil {
   667  			t.Error(err)
   668  			return false
   669  		}
   670  
   671  		target := testDataGenerator.uniqueMountTarget()
   672  		err = tc.policy.EnforceOverlayMountPolicy(p.ctx, tc.containerID, tc.layers, target)
   673  		if err != nil {
   674  			t.Errorf("Failure setting up overlay for testing: %v", err)
   675  			return false
   676  		}
   677  
   678  		badTarget := testDataGenerator.uniqueMountTarget()
   679  		err = tc.policy.EnforceOverlayUnmountPolicy(p.ctx, badTarget)
   680  		if err == nil {
   681  			t.Errorf("Unexpected policy enforcement success: %v", err)
   682  			return false
   683  		}
   684  
   685  		return true
   686  	}
   687  
   688  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   689  		t.Errorf("Test_Rego_EnforceOverlayUnmountPolicy: %v", err)
   690  	}
   691  }
   692  
   693  func Test_Rego_EnforceCommandPolicy_NoMatches(t *testing.T) {
   694  	f := func(p *generatedConstraints) bool {
   695  		tc, err := setupSimpleRegoCreateContainerTest(p)
   696  		if err != nil {
   697  			t.Error(err)
   698  			return false
   699  		}
   700  
   701  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, generateCommand(testRand), tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   702  
   703  		if err == nil {
   704  			return false
   705  		}
   706  
   707  		return assertDecisionJSONContains(t, err, "invalid command")
   708  	}
   709  
   710  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   711  		t.Errorf("Test_EnforceCommandPolicy_NoMatches: %v", err)
   712  	}
   713  }
   714  
   715  func Test_Rego_EnforceEnvironmentVariablePolicy_Re2Match(t *testing.T) {
   716  	testFunc := func(gc *generatedConstraints) bool {
   717  		container := selectContainerFromContainerList(gc.containers, testRand)
   718  		// add a rule to re2 match
   719  		re2MatchRule := EnvRuleConfig{
   720  			Strategy: EnvVarRuleRegex,
   721  			Rule:     "PREFIX_.+=.+",
   722  		}
   723  
   724  		container.EnvRules = append(container.EnvRules, re2MatchRule)
   725  
   726  		tc, err := setupRegoCreateContainerTest(gc, container, false)
   727  		if err != nil {
   728  			t.Error(err)
   729  			return false
   730  		}
   731  
   732  		envList := append(tc.envList, "PREFIX_FOO=BAR")
   733  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(gc.ctx, tc.sandboxID, tc.containerID, tc.argList, envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   734  
   735  		// getting an error means something is broken
   736  		if err != nil {
   737  			t.Errorf("Expected container setup to be allowed. It wasn't: %v", err)
   738  			return false
   739  		}
   740  
   741  		return true
   742  	}
   743  
   744  	if err := quick.Check(testFunc, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   745  		t.Errorf("Test_Rego_EnforceEnvironmentVariablePolicy_Re2Match: %v", err)
   746  	}
   747  }
   748  
   749  func Test_Rego_EnforceEnvironmentVariablePolicy_NotAllMatches(t *testing.T) {
   750  	f := func(p *generatedConstraints) bool {
   751  		tc, err := setupSimpleRegoCreateContainerTest(p)
   752  		if err != nil {
   753  			t.Error(err)
   754  			return false
   755  		}
   756  
   757  		envList := append(tc.envList, generateNeverMatchingEnvironmentVariable(testRand))
   758  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   759  
   760  		// not getting an error means something is broken
   761  		if err == nil {
   762  			return false
   763  		}
   764  
   765  		return assertDecisionJSONContains(t, err, "invalid env list", envList[0])
   766  	}
   767  
   768  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   769  		t.Errorf("Test_Rego_EnforceEnvironmentVariablePolicy_NotAllMatches: %v", err)
   770  	}
   771  }
   772  
   773  func Test_Rego_EnforceEnvironmentVariablePolicy_DropEnvs(t *testing.T) {
   774  	testFunc := func(gc *generatedConstraints) bool {
   775  		gc.allowEnvironmentVariableDropping = true
   776  		container := selectContainerFromContainerList(gc.containers, testRand)
   777  
   778  		tc, err := setupRegoCreateContainerTest(gc, container, false)
   779  		if err != nil {
   780  			t.Error(err)
   781  			return false
   782  		}
   783  
   784  		extraRules := generateEnvironmentVariableRules(testRand)
   785  		extraEnvs := buildEnvironmentVariablesFromEnvRules(extraRules, testRand)
   786  
   787  		envList := append(tc.envList, extraEnvs...)
   788  		actual, _, _, err := tc.policy.EnforceCreateContainerPolicy(gc.ctx, tc.sandboxID, tc.containerID, tc.argList, envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   789  
   790  		// getting an error means something is broken
   791  		if err != nil {
   792  			t.Errorf("Expected container creation to be allowed. It wasn't: %v", err)
   793  			return false
   794  		}
   795  
   796  		if !areStringArraysEqual(actual, tc.envList) {
   797  			t.Errorf("environment variables were not dropped correctly.")
   798  			return false
   799  		}
   800  
   801  		return true
   802  	}
   803  
   804  	if err := quick.Check(testFunc, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   805  		t.Errorf("Test_Rego_EnforceEnvironmentVariablePolicy_DropEnvs: %v", err)
   806  	}
   807  }
   808  
   809  func Test_Rego_EnforceEnvironmentVariablePolicy_DropEnvs_Multiple(t *testing.T) {
   810  	tc, err := setupRegoDropEnvsTest(false)
   811  	if err != nil {
   812  		t.Fatalf("error setting up test: %v", err)
   813  	}
   814  
   815  	extraRules := generateEnvironmentVariableRules(testRand)
   816  	extraEnvs := buildEnvironmentVariablesFromEnvRules(extraRules, testRand)
   817  
   818  	envList := append(tc.envList, extraEnvs...)
   819  	actual, _, _, err := tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   820  
   821  	// getting an error means something is broken
   822  	if err != nil {
   823  		t.Errorf("Expected container creation to be allowed. It wasn't: %v", err)
   824  	}
   825  
   826  	if !areStringArraysEqual(actual, tc.envList) {
   827  		t.Error("environment variables were not dropped correctly.")
   828  	}
   829  }
   830  
   831  func Test_Rego_EnforceEnvironmentVariablePolicy_DropEnvs_Multiple_NoMatch(t *testing.T) {
   832  	tc, err := setupRegoDropEnvsTest(true)
   833  	if err != nil {
   834  		t.Fatalf("error setting up test: %v", err)
   835  	}
   836  
   837  	extraRules := generateEnvironmentVariableRules(testRand)
   838  	extraEnvs := buildEnvironmentVariablesFromEnvRules(extraRules, testRand)
   839  
   840  	envList := append(tc.envList, extraEnvs...)
   841  	actual, _, _, err := tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   842  
   843  	// not getting an error means something is broken
   844  	if err == nil {
   845  		t.Error("expected container creation not to be allowed.")
   846  	}
   847  
   848  	if actual != nil {
   849  		t.Error("envList should be nil")
   850  	}
   851  }
   852  
   853  func Test_Rego_WorkingDirectoryPolicy_NoMatches(t *testing.T) {
   854  	testFunc := func(gc *generatedConstraints) bool {
   855  		tc, err := setupSimpleRegoCreateContainerTest(gc)
   856  		if err != nil {
   857  			t.Error(err)
   858  			return false
   859  		}
   860  
   861  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, randString(testRand, 20), tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   862  		// not getting an error means something is broken
   863  		if err == nil {
   864  			return false
   865  		}
   866  
   867  		return assertDecisionJSONContains(t, err, "invalid working directory")
   868  	}
   869  
   870  	if err := quick.Check(testFunc, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   871  		t.Errorf("Test_Rego_WorkingDirectoryPolicy_NoMatches: %v", err)
   872  	}
   873  }
   874  
   875  func Test_Rego_EnforceCreateContainer(t *testing.T) {
   876  	f := func(p *generatedConstraints) bool {
   877  		tc, err := setupSimpleRegoCreateContainerTest(p)
   878  		if err != nil {
   879  			t.Error(err)
   880  			return false
   881  		}
   882  
   883  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   884  
   885  		// getting an error means something is broken
   886  		return err == nil
   887  	}
   888  
   889  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   890  		t.Errorf("Test_Rego_EnforceCreateContainer: %v", err)
   891  	}
   892  }
   893  
   894  func Test_Rego_EnforceCreateContainer_Start_All_Containers(t *testing.T) {
   895  	f := func(p *generatedConstraints) bool {
   896  		securityPolicy := p.toPolicy()
   897  		defaultMounts := generateMounts(testRand)
   898  		privilegedMounts := generateMounts(testRand)
   899  
   900  		policy, err := newRegoPolicy(securityPolicy.marshalRego(),
   901  			toOCIMounts(defaultMounts),
   902  			toOCIMounts(privilegedMounts))
   903  		if err != nil {
   904  			t.Error(err)
   905  			return false
   906  		}
   907  
   908  		for _, container := range p.containers {
   909  			containerID, err := mountImageForContainer(policy, container)
   910  			if err != nil {
   911  				t.Error(err)
   912  				return false
   913  			}
   914  
   915  			envList := buildEnvironmentVariablesFromEnvRules(container.EnvRules, testRand)
   916  			user := buildIDNameFromConfig(container.User.UserIDName, testRand)
   917  			groups := buildGroupIDNamesFromUser(container.User, testRand)
   918  
   919  			sandboxID := testDataGenerator.uniqueSandboxID()
   920  			mounts := container.Mounts
   921  			mounts = append(mounts, defaultMounts...)
   922  			if container.AllowElevated {
   923  				mounts = append(mounts, privilegedMounts...)
   924  			}
   925  			mountSpec := buildMountSpecFromMountArray(mounts, sandboxID, testRand)
   926  			capabilities := container.Capabilities.toExternal()
   927  			seccomp := container.SeccompProfileSHA256
   928  
   929  			_, _, _, err = policy.EnforceCreateContainerPolicy(p.ctx, sandboxID, containerID, container.Command, envList, container.WorkingDir, mountSpec.Mounts, false, container.NoNewPrivileges, user, groups, container.User.Umask, &capabilities, seccomp)
   930  
   931  			// getting an error means something is broken
   932  			if err != nil {
   933  				t.Error(err)
   934  				return false
   935  			}
   936  		}
   937  
   938  		return true
   939  
   940  	}
   941  
   942  	if err := quick.Check(f, &quick.Config{MaxCount: 10, Rand: testRand}); err != nil {
   943  		t.Errorf("Test_Rego_EnforceCreateContainer_Start_All_Containers: %v", err)
   944  	}
   945  }
   946  
   947  func Test_Rego_EnforceCreateContainer_Invalid_ContainerID(t *testing.T) {
   948  	f := func(p *generatedConstraints) bool {
   949  		tc, err := setupSimpleRegoCreateContainerTest(p)
   950  		if err != nil {
   951  			t.Error(err)
   952  			return false
   953  		}
   954  
   955  		containerID := testDataGenerator.uniqueContainerID()
   956  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   957  
   958  		// not getting an error means something is broken
   959  		return err != nil
   960  	}
   961  
   962  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   963  		t.Errorf("Test_Rego_EnforceCreateContainer_Invalid_ContainerID: %v", err)
   964  	}
   965  }
   966  
   967  func Test_Rego_EnforceCreateContainer_Same_Container_Twice(t *testing.T) {
   968  	f := func(p *generatedConstraints) bool {
   969  		tc, err := setupSimpleRegoCreateContainerTest(p)
   970  		if err != nil {
   971  			t.Error(err)
   972  			return false
   973  		}
   974  
   975  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   976  		if err != nil {
   977  			t.Error("Unable to start valid container.")
   978  			return false
   979  		}
   980  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
   981  		if err == nil {
   982  			t.Error("Able to start a container with already used id.")
   983  			return false
   984  		}
   985  
   986  		return true
   987  	}
   988  
   989  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
   990  		t.Errorf("Test_Rego_EnforceCreateContainer_Same_Container_Twice: %v", err)
   991  	}
   992  }
   993  
   994  func Test_Rego_EnforceCreateContainer_Capabilities_NoMatches(t *testing.T) {
   995  	f := func(p *generatedConstraints) bool {
   996  		tc, err := setupSimpleRegoCreateContainerTest(p)
   997  		if err != nil {
   998  			t.Error(err)
   999  			return false
  1000  		}
  1001  
  1002  		capabilities := tc.capabilities
  1003  		capabilities.Bounding = alterCapabilitySet(testRand, capabilities.Bounding)
  1004  		capabilities.Effective = alterCapabilitySet(testRand, capabilities.Effective)
  1005  		capabilities.Inheritable = alterCapabilitySet(testRand, capabilities.Inheritable)
  1006  		capabilities.Permitted = alterCapabilitySet(testRand, capabilities.Permitted)
  1007  		capabilities.Ambient = alterCapabilitySet(testRand, capabilities.Ambient)
  1008  
  1009  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, capabilities, tc.seccomp)
  1010  
  1011  		if err == nil {
  1012  			t.Error("Unexpected success with incorrect capabilities")
  1013  			return false
  1014  		}
  1015  
  1016  		return true
  1017  	}
  1018  
  1019  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  1020  		t.Errorf("Test_Rego_EnforceCreateContainer_Capabilities_NoMatches: %v", err)
  1021  	}
  1022  }
  1023  
  1024  func Test_Rego_EnforceCreateContainer_Capabilities_SubsetDoesntMatch(t *testing.T) {
  1025  	f := func(p *generatedConstraints) bool {
  1026  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1027  		if err != nil {
  1028  			t.Error(err)
  1029  			return false
  1030  		}
  1031  
  1032  		if len(tc.capabilities.Bounding) > 0 {
  1033  			capabilities := copyLinuxCapabilities(*tc.capabilities)
  1034  			capabilities.Bounding = subsetCapabilitySet(testRand, copyStrings(capabilities.Bounding))
  1035  
  1036  			_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1037  
  1038  			if err == nil {
  1039  				t.Error("Unexpected success with bounding as a subset of allowed capabilities")
  1040  				return false
  1041  			}
  1042  		}
  1043  
  1044  		if len(tc.capabilities.Effective) > 0 {
  1045  			capabilities := copyLinuxCapabilities(*tc.capabilities)
  1046  			capabilities.Effective = subsetCapabilitySet(testRand, copyStrings(capabilities.Effective))
  1047  
  1048  			_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1049  
  1050  			if err == nil {
  1051  				t.Error("Unexpected success with effective as a subset of allowed capabilities")
  1052  				return false
  1053  			}
  1054  		}
  1055  
  1056  		if len(tc.capabilities.Inheritable) > 0 {
  1057  			capabilities := copyLinuxCapabilities(*tc.capabilities)
  1058  			capabilities.Inheritable = subsetCapabilitySet(testRand, copyStrings(capabilities.Inheritable))
  1059  
  1060  			_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1061  
  1062  			if err == nil {
  1063  				t.Error("Unexpected success with inheritable as a subset of allowed capabilities")
  1064  				return false
  1065  			}
  1066  		}
  1067  
  1068  		if len(tc.capabilities.Permitted) > 0 {
  1069  			capabilities := copyLinuxCapabilities(*tc.capabilities)
  1070  			capabilities.Permitted = subsetCapabilitySet(testRand, copyStrings(capabilities.Permitted))
  1071  
  1072  			_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1073  
  1074  			if err == nil {
  1075  				t.Error("Unexpected success with permitted as a subset of allowed capabilities")
  1076  				return false
  1077  			}
  1078  		}
  1079  
  1080  		if len(tc.capabilities.Ambient) > 0 {
  1081  			capabilities := copyLinuxCapabilities(*tc.capabilities)
  1082  			capabilities.Ambient = subsetCapabilitySet(testRand, copyStrings(capabilities.Ambient))
  1083  
  1084  			_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1085  
  1086  			if err == nil {
  1087  				t.Error("Unexpected success with ambient as a subset of allowed capabilities")
  1088  				return false
  1089  			}
  1090  		}
  1091  
  1092  		return true
  1093  	}
  1094  
  1095  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  1096  		t.Errorf("Test_Rego_EnforceCreateContainer_Capabilities_SubsetDoesntMatch: %v", err)
  1097  	}
  1098  }
  1099  
  1100  func Test_Rego_EnforceCreateContainer_Capabilities_SupersetDoesntMatch(t *testing.T) {
  1101  	f := func(p *generatedConstraints) bool {
  1102  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1103  		if err != nil {
  1104  			t.Error(err)
  1105  			return false
  1106  		}
  1107  
  1108  		capabilities := copyLinuxCapabilities(*tc.capabilities)
  1109  		capabilities.Bounding = superCapabilitySet(testRand, copyStrings(capabilities.Bounding))
  1110  
  1111  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1112  
  1113  		if err == nil {
  1114  			t.Error("Unexpected success with bounding as a superset of allowed capabilities")
  1115  			return false
  1116  		}
  1117  
  1118  		capabilities = copyLinuxCapabilities(*tc.capabilities)
  1119  		capabilities.Effective = superCapabilitySet(testRand, copyStrings(capabilities.Effective))
  1120  
  1121  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1122  
  1123  		if err == nil {
  1124  			t.Error("Unexpected success with effective as a superset of allowed capabilities")
  1125  			return false
  1126  		}
  1127  
  1128  		capabilities = copyLinuxCapabilities(*tc.capabilities)
  1129  		capabilities.Inheritable = superCapabilitySet(testRand, copyStrings(capabilities.Inheritable))
  1130  
  1131  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1132  
  1133  		if err == nil {
  1134  			t.Error("Unexpected success with inheritable as a superset of allowed capabilities")
  1135  			return false
  1136  		}
  1137  
  1138  		capabilities = copyLinuxCapabilities(*tc.capabilities)
  1139  		capabilities.Permitted = superCapabilitySet(testRand, copyStrings(capabilities.Permitted))
  1140  
  1141  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1142  
  1143  		if err == nil {
  1144  			t.Error("Unexpected success with permitted as a superset of allowed capabilities")
  1145  			return false
  1146  		}
  1147  
  1148  		capabilities = copyLinuxCapabilities(*tc.capabilities)
  1149  		capabilities.Ambient = superCapabilitySet(testRand, copyStrings(capabilities.Ambient))
  1150  
  1151  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1152  
  1153  		if err == nil {
  1154  			t.Error("Unexpected success with ambient as a superset of allowed capabilities")
  1155  			return false
  1156  		}
  1157  
  1158  		return true
  1159  	}
  1160  
  1161  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  1162  		t.Errorf("Test_Rego_EnforceCreateContainer_Capabilities_SupersetDoesntMatch: %v", err)
  1163  	}
  1164  }
  1165  
  1166  func Test_Rego_EnforceCreateContainer_Capabilities_DenialHasErrorMessage(t *testing.T) {
  1167  	constraints := generateConstraints(testRand, 1)
  1168  	tc, err := setupSimpleRegoCreateContainerTest(constraints)
  1169  	if err != nil {
  1170  		t.Fatal(err)
  1171  	}
  1172  
  1173  	capabilities := tc.capabilities
  1174  	capabilities.Bounding = alterCapabilitySet(testRand, capabilities.Bounding)
  1175  	capabilities.Effective = alterCapabilitySet(testRand, capabilities.Effective)
  1176  	capabilities.Inheritable = alterCapabilitySet(testRand, capabilities.Inheritable)
  1177  	capabilities.Permitted = alterCapabilitySet(testRand, capabilities.Permitted)
  1178  	capabilities.Ambient = alterCapabilitySet(testRand, capabilities.Ambient)
  1179  
  1180  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, capabilities, tc.seccomp)
  1181  
  1182  	if err == nil {
  1183  		t.Error("Unexpected success with incorrect capabilities")
  1184  	}
  1185  
  1186  	if !assertDecisionJSONContains(t, err, "capabilities don't match") {
  1187  		t.Fatal("No error message given for denial by capability mismatch")
  1188  	}
  1189  }
  1190  
  1191  func Test_Rego_EnforceCreateContainer_Capabilities_UndecidableHasErrorMessage(t *testing.T) {
  1192  	constraints := generateConstraints(testRand, 1)
  1193  
  1194  	// Capabilities setup needed to trigger error
  1195  	testCaps := []string{"one", "two", "three"}
  1196  	firstCaps := []string{"one", "three"}
  1197  	secondCaps := []string{"two", "three"}
  1198  
  1199  	incomingCapabilities := &oci.LinuxCapabilities{
  1200  		Bounding:    testCaps,
  1201  		Effective:   testCaps,
  1202  		Inheritable: testCaps,
  1203  		Permitted:   testCaps,
  1204  		Ambient:     testCaps,
  1205  	}
  1206  
  1207  	firstContainerCapabilities := &capabilitiesInternal{
  1208  		Bounding:    firstCaps,
  1209  		Effective:   firstCaps,
  1210  		Inheritable: firstCaps,
  1211  		Permitted:   firstCaps,
  1212  		Ambient:     firstCaps,
  1213  	}
  1214  
  1215  	secondContainerCapabilities := &capabilitiesInternal{
  1216  		Bounding:    secondCaps,
  1217  		Effective:   secondCaps,
  1218  		Inheritable: secondCaps,
  1219  		Permitted:   secondCaps,
  1220  		Ambient:     secondCaps,
  1221  	}
  1222  
  1223  	// setup container one
  1224  	constraints.containers[0].Capabilities = firstContainerCapabilities
  1225  
  1226  	// Add a second container that is the same as first container except it
  1227  	// differs for "initial create" values only in terms of capabilities
  1228  	duplicate := &securityPolicyContainer{
  1229  		Command:              constraints.containers[0].Command,
  1230  		EnvRules:             constraints.containers[0].EnvRules,
  1231  		WorkingDir:           constraints.containers[0].WorkingDir,
  1232  		Mounts:               constraints.containers[0].Mounts,
  1233  		Layers:               constraints.containers[0].Layers,
  1234  		AllowElevated:        constraints.containers[0].AllowElevated,
  1235  		AllowStdioAccess:     constraints.containers[0].AllowStdioAccess,
  1236  		NoNewPrivileges:      constraints.containers[0].NoNewPrivileges,
  1237  		User:                 constraints.containers[0].User,
  1238  		SeccompProfileSHA256: constraints.containers[0].SeccompProfileSHA256,
  1239  		// Difference here is our test case
  1240  		Capabilities: secondContainerCapabilities,
  1241  		// Don't care. Can be different
  1242  		ExecProcesses: generateExecProcesses(testRand),
  1243  		Signals:       generateListOfSignals(testRand, 0, maxSignalNumber),
  1244  	}
  1245  
  1246  	constraints.containers = append(constraints.containers, duplicate)
  1247  
  1248  	// Undecidable is only possible for create container if dropping is on
  1249  	constraints.allowCapabilityDropping = true
  1250  
  1251  	tc, err := setupSimpleRegoCreateContainerTest(constraints)
  1252  	if err != nil {
  1253  		t.Fatal(err)
  1254  	}
  1255  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, incomingCapabilities, tc.seccomp)
  1256  
  1257  	if err == nil {
  1258  		t.Fatal("Unexpected success with undecidable capabilities")
  1259  	}
  1260  
  1261  	if !assertDecisionJSONContains(t, err, "containers only distinguishable by capabilties") {
  1262  		t.Fatal("No error message given for undecidable based on capabilities mismatch")
  1263  	}
  1264  }
  1265  
  1266  func Test_Rego_EnforceCreateContainer_CapabilitiesIsNil(t *testing.T) {
  1267  	constraints := generateConstraints(testRand, 1)
  1268  	tc, err := setupSimpleRegoCreateContainerTest(constraints)
  1269  	if err != nil {
  1270  		t.Fatal(err)
  1271  	}
  1272  
  1273  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, nil, tc.seccomp)
  1274  
  1275  	if err == nil {
  1276  		t.Fatal("Unexpected success with nil capabilities")
  1277  	}
  1278  
  1279  	if err.Error() != capabilitiesNilError {
  1280  		t.Fatal("No error message given for denial by capability being nil")
  1281  	}
  1282  }
  1283  
  1284  func Test_Rego_EnforceCreateContainer_Capabilities_Null_Elevated(t *testing.T) {
  1285  	constraints := generateConstraints(testRand, 1)
  1286  	constraints.containers[0].AllowElevated = true
  1287  	constraints.containers[0].Capabilities = nil
  1288  	tc, err := setupSimpleRegoCreateContainerTest(constraints)
  1289  	if err != nil {
  1290  		t.Fatal(err)
  1291  	}
  1292  
  1293  	capabilities := capabilitiesInternal{
  1294  		Bounding:    DefaultUnprivilegedCapabilities(),
  1295  		Effective:   DefaultUnprivilegedCapabilities(),
  1296  		Inheritable: []string{},
  1297  		Permitted:   DefaultUnprivilegedCapabilities(),
  1298  		Ambient:     []string{},
  1299  	}.toExternal()
  1300  
  1301  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1302  
  1303  	if err != nil {
  1304  		t.Fatal("Unexpected failure with null capabilities and elevated: %w", err)
  1305  	}
  1306  }
  1307  
  1308  func Test_Rego_EnforceCreateContainer_Capabilities_Null(t *testing.T) {
  1309  	constraints := generateConstraints(testRand, 1)
  1310  	constraints.containers[0].AllowElevated = false
  1311  	constraints.containers[0].Capabilities = nil
  1312  	tc, err := setupSimpleRegoCreateContainerTest(constraints)
  1313  	if err != nil {
  1314  		t.Fatal(err)
  1315  	}
  1316  
  1317  	capabilities := capabilitiesInternal{
  1318  		Bounding:    DefaultUnprivilegedCapabilities(),
  1319  		Effective:   DefaultUnprivilegedCapabilities(),
  1320  		Inheritable: []string{},
  1321  		Permitted:   DefaultUnprivilegedCapabilities(),
  1322  		Ambient:     []string{},
  1323  	}.toExternal()
  1324  
  1325  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1326  
  1327  	if err != nil {
  1328  		t.Fatal("Unexpected failure with null capabilities: %w", err)
  1329  	}
  1330  }
  1331  
  1332  func Test_Rego_EnforceCreateContainer_Capabilities_Null_Elevated_Privileged(t *testing.T) {
  1333  	constraints := generateConstraints(testRand, 1)
  1334  	constraints.containers[0].AllowElevated = true
  1335  	constraints.containers[0].Capabilities = nil
  1336  	tc, err := setupSimpleRegoCreateContainerTest(constraints)
  1337  	if err != nil {
  1338  		t.Fatal(err)
  1339  	}
  1340  
  1341  	capabilities := capabilitiesInternal{
  1342  		Bounding:    DefaultPrivilegedCapabilities(),
  1343  		Effective:   DefaultPrivilegedCapabilities(),
  1344  		Inheritable: DefaultPrivilegedCapabilities(),
  1345  		Permitted:   DefaultPrivilegedCapabilities(),
  1346  		Ambient:     []string{},
  1347  	}.toExternal()
  1348  
  1349  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, true, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1350  
  1351  	if err != nil {
  1352  		t.Fatal("Unexpected failure with null capabilities when elevated and privileged: %w", err)
  1353  	}
  1354  }
  1355  
  1356  func Test_Rego_EnforceExecInContainer_Capabilities_Null_Elevated(t *testing.T) {
  1357  	constraints := generateConstraints(testRand, 1)
  1358  	constraints.containers[0].AllowElevated = true
  1359  	constraints.containers[0].Capabilities = nil
  1360  	tc, err := setupRegoRunningContainerTest(constraints, false)
  1361  	if err != nil {
  1362  		t.Fatal(err)
  1363  	}
  1364  
  1365  	capabilities := capabilitiesInternal{
  1366  		Bounding:    DefaultUnprivilegedCapabilities(),
  1367  		Effective:   DefaultUnprivilegedCapabilities(),
  1368  		Inheritable: []string{},
  1369  		Permitted:   DefaultUnprivilegedCapabilities(),
  1370  		Ambient:     []string{},
  1371  	}.toExternal()
  1372  
  1373  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  1374  
  1375  	process := selectExecProcess(container.container.ExecProcesses, testRand)
  1376  	envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  1377  	user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  1378  	groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  1379  	umask := container.container.User.Umask
  1380  
  1381  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(constraints.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  1382  
  1383  	if err != nil {
  1384  		t.Fatal("Unexpected failure with null capabilities and elevated: %w", err)
  1385  	}
  1386  }
  1387  
  1388  func Test_Rego_EnforceExecInContainer_Capabilities_Null(t *testing.T) {
  1389  	constraints := generateConstraints(testRand, 1)
  1390  	constraints.containers[0].Capabilities = nil
  1391  	tc, err := setupRegoRunningContainerTest(constraints, false)
  1392  	if err != nil {
  1393  		t.Fatal(err)
  1394  	}
  1395  
  1396  	capabilities := capabilitiesInternal{
  1397  		Bounding:    DefaultUnprivilegedCapabilities(),
  1398  		Effective:   DefaultUnprivilegedCapabilities(),
  1399  		Inheritable: []string{},
  1400  		Permitted:   DefaultUnprivilegedCapabilities(),
  1401  		Ambient:     []string{},
  1402  	}.toExternal()
  1403  
  1404  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  1405  
  1406  	process := selectExecProcess(container.container.ExecProcesses, testRand)
  1407  	envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  1408  	user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  1409  	groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  1410  	umask := container.container.User.Umask
  1411  
  1412  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(constraints.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  1413  
  1414  	if err != nil {
  1415  		t.Fatal("Unexpected failure with null capabilities: %w", err)
  1416  	}
  1417  }
  1418  
  1419  func Test_Rego_EnforceExecInContainer_Capabilities_Null_Elevated_Privileged(t *testing.T) {
  1420  	constraints := generateConstraints(testRand, 1)
  1421  	constraints.containers[0].AllowElevated = true
  1422  	constraints.containers[0].Capabilities = nil
  1423  	tc, err := setupRegoRunningContainerTest(constraints, true)
  1424  	if err != nil {
  1425  		t.Fatal(err)
  1426  	}
  1427  
  1428  	capabilities := capabilitiesInternal{
  1429  		Bounding:    DefaultPrivilegedCapabilities(),
  1430  		Effective:   DefaultPrivilegedCapabilities(),
  1431  		Inheritable: DefaultPrivilegedCapabilities(),
  1432  		Permitted:   DefaultPrivilegedCapabilities(),
  1433  		Ambient:     []string{},
  1434  	}.toExternal()
  1435  
  1436  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  1437  
  1438  	process := selectExecProcess(container.container.ExecProcesses, testRand)
  1439  	envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  1440  	user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  1441  	groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  1442  	umask := container.container.User.Umask
  1443  
  1444  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(constraints.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  1445  
  1446  	if err != nil {
  1447  		t.Fatal("Unexpected failure with null capabilities when elevated and privileged: %w", err)
  1448  	}
  1449  }
  1450  
  1451  func Test_Rego_EnforceCreateContainer_CapabilitiesAreEmpty(t *testing.T) {
  1452  	constraints := generateConstraints(testRand, 1)
  1453  	constraints.containers[0].Capabilities.Bounding = make([]string, 0)
  1454  	constraints.containers[0].Capabilities.Effective = make([]string, 0)
  1455  	constraints.containers[0].Capabilities.Inheritable = make([]string, 0)
  1456  	constraints.containers[0].Capabilities.Permitted = make([]string, 0)
  1457  	constraints.containers[0].Capabilities.Ambient = make([]string, 0)
  1458  
  1459  	tc, err := setupSimpleRegoCreateContainerTest(constraints)
  1460  	if err != nil {
  1461  		t.Fatal(err)
  1462  	}
  1463  
  1464  	capabilities := oci.LinuxCapabilities{}
  1465  
  1466  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1467  
  1468  	if err != nil {
  1469  		t.Fatal("Unexpected failure")
  1470  	}
  1471  }
  1472  
  1473  func Test_Rego_EnforceCreateContainer_Capabilities_Drop(t *testing.T) {
  1474  	f := func(p *generatedConstraints) bool {
  1475  		p.allowCapabilityDropping = true
  1476  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1477  		if err != nil {
  1478  			t.Error(err)
  1479  			return false
  1480  		}
  1481  
  1482  		capabilities := copyLinuxCapabilities(*tc.capabilities)
  1483  		extraCapabilities := generateCapabilities(testRand)
  1484  		capabilities.Bounding = append(capabilities.Bounding, extraCapabilities.Bounding...)
  1485  		capabilities.Effective = append(capabilities.Effective, extraCapabilities.Effective...)
  1486  		capabilities.Inheritable = append(capabilities.Inheritable, extraCapabilities.Inheritable...)
  1487  		capabilities.Permitted = append(capabilities.Permitted, extraCapabilities.Permitted...)
  1488  		capabilities.Ambient = append(capabilities.Ambient, extraCapabilities.Ambient...)
  1489  
  1490  		_, actual, _, err := tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, &capabilities, tc.seccomp)
  1491  
  1492  		if err != nil {
  1493  			t.Errorf("Expected container creation to be allowed. It wasn't for extra capabilities: %v", err)
  1494  			return false
  1495  		}
  1496  
  1497  		if !areStringArraysEqual(actual.Bounding, tc.capabilities.Bounding) {
  1498  			t.Errorf("bounding capabilities were not dropped correctly.")
  1499  			return false
  1500  		}
  1501  
  1502  		if !areStringArraysEqual(actual.Effective, tc.capabilities.Effective) {
  1503  			t.Errorf("effective capabilities were not dropped correctly.")
  1504  			return false
  1505  		}
  1506  
  1507  		if !areStringArraysEqual(actual.Inheritable, tc.capabilities.Inheritable) {
  1508  			t.Errorf("inheritable capabilities were not dropped correctly.")
  1509  			return false
  1510  		}
  1511  
  1512  		if !areStringArraysEqual(actual.Permitted, tc.capabilities.Permitted) {
  1513  			t.Errorf("permitted capabilities were not dropped correctly.")
  1514  			return false
  1515  		}
  1516  
  1517  		if !areStringArraysEqual(actual.Ambient, tc.capabilities.Ambient) {
  1518  			t.Errorf("ambient capabilities were not dropped correctly.")
  1519  			return false
  1520  		}
  1521  
  1522  		return true
  1523  	}
  1524  
  1525  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  1526  		t.Errorf("Test_Rego_EnforceCreateContainer_Capabilities_Drop: %v", err)
  1527  	}
  1528  }
  1529  
  1530  func Test_Rego_EnforceCreateContainer_Capabilities_Drop_NoMatches(t *testing.T) {
  1531  	f := func(p *generatedConstraints) bool {
  1532  		p.allowCapabilityDropping = true
  1533  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1534  		if err != nil {
  1535  			t.Error(err)
  1536  			return false
  1537  		}
  1538  
  1539  		capabilities := generateCapabilities(testRand)
  1540  
  1541  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, capabilities, tc.seccomp)
  1542  
  1543  		if err == nil {
  1544  			t.Errorf("Unexpected success with non matching capabilities set and dropping")
  1545  			return false
  1546  		}
  1547  
  1548  		return true
  1549  	}
  1550  
  1551  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  1552  		t.Errorf("Test_Rego_EnforceCreateContainer_Capabilities_Drop_NoMatches: %v", err)
  1553  	}
  1554  }
  1555  
  1556  func Test_Rego_ExtendDefaultMounts(t *testing.T) {
  1557  	f := func(p *generatedConstraints) bool {
  1558  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1559  		if err != nil {
  1560  			t.Error(err)
  1561  			return false
  1562  		}
  1563  
  1564  		defaultMounts := generateMounts(testRand)
  1565  		_ = tc.policy.ExtendDefaultMounts(toOCIMounts(defaultMounts))
  1566  
  1567  		additionalMounts := buildMountSpecFromMountArray(defaultMounts, tc.sandboxID, testRand)
  1568  		tc.mounts = append(tc.mounts, additionalMounts.Mounts...)
  1569  
  1570  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  1571  
  1572  		if err != nil {
  1573  			t.Error(err)
  1574  			return false
  1575  		} else {
  1576  			return true
  1577  		}
  1578  	}
  1579  
  1580  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  1581  		t.Errorf("Test_Rego_ExtendDefaultMounts: %v", err)
  1582  	}
  1583  }
  1584  
  1585  func Test_Rego_MountPolicy_NoMatches(t *testing.T) {
  1586  	f := func(p *generatedConstraints) bool {
  1587  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1588  		if err != nil {
  1589  			t.Error(err)
  1590  			return false
  1591  		}
  1592  
  1593  		invalidMounts := generateMounts(testRand)
  1594  		additionalMounts := buildMountSpecFromMountArray(invalidMounts, tc.sandboxID, testRand)
  1595  		tc.mounts = append(tc.mounts, additionalMounts.Mounts...)
  1596  
  1597  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  1598  
  1599  		// not getting an error means something is broken
  1600  		if err == nil {
  1601  			t.Error("We added additional mounts not in policyS and it didn't result in an error")
  1602  			return false
  1603  		}
  1604  
  1605  		return assertDecisionJSONContains(t, err, "invalid mount list")
  1606  	}
  1607  
  1608  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  1609  		t.Errorf("Test_Rego_MountPolicy_NoMatches: %v", err)
  1610  	}
  1611  }
  1612  
  1613  func Test_Rego_MountPolicy_NotAllOptionsFromConstraints(t *testing.T) {
  1614  	f := func(p *generatedConstraints) bool {
  1615  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1616  		if err != nil {
  1617  			t.Error(err)
  1618  			return false
  1619  		}
  1620  
  1621  		inputMounts := tc.mounts
  1622  		mindex := randMinMax(testRand, 0, int32(len(tc.mounts)-1))
  1623  		options := inputMounts[mindex].Options
  1624  		inputMounts[mindex].Options = options[:len(options)-1]
  1625  
  1626  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  1627  
  1628  		// not getting an error means something is broken
  1629  		if err == nil {
  1630  			return false
  1631  		}
  1632  
  1633  		return assertDecisionJSONContains(t, err, "invalid mount list")
  1634  	}
  1635  
  1636  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  1637  		t.Errorf("Test_Rego_MountPolicy_NotAllOptionsFromConstraints: %v", err)
  1638  	}
  1639  }
  1640  
  1641  func Test_Rego_MountPolicy_BadSource(t *testing.T) {
  1642  	f := func(p *generatedConstraints) bool {
  1643  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1644  		if err != nil {
  1645  			t.Error(err)
  1646  			return false
  1647  		}
  1648  
  1649  		index := randMinMax(testRand, 0, int32(len(tc.mounts)-1))
  1650  		tc.mounts[index].Source = randString(testRand, maxGeneratedMountSourceLength)
  1651  
  1652  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  1653  
  1654  		// not getting an error means something is broken
  1655  		if err == nil {
  1656  			return false
  1657  		}
  1658  
  1659  		return assertDecisionJSONContains(t, err, "invalid mount list")
  1660  	}
  1661  
  1662  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  1663  		t.Errorf("Test_Rego_MountPolicy_BadSource: %v", err)
  1664  	}
  1665  }
  1666  
  1667  func Test_Rego_MountPolicy_BadDestination(t *testing.T) {
  1668  	f := func(p *generatedConstraints) bool {
  1669  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1670  		if err != nil {
  1671  			t.Error(err)
  1672  			return false
  1673  		}
  1674  
  1675  		index := randMinMax(testRand, 0, int32(len(tc.mounts)-1))
  1676  		tc.mounts[index].Destination = randString(testRand, maxGeneratedMountDestinationLength)
  1677  
  1678  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  1679  
  1680  		// not getting an error means something is broken
  1681  		if err == nil {
  1682  			return false
  1683  		}
  1684  
  1685  		return assertDecisionJSONContains(t, err, "invalid mount list")
  1686  	}
  1687  
  1688  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  1689  		t.Errorf("Test_Rego_MountPolicy_BadDestination: %v", err)
  1690  	}
  1691  }
  1692  
  1693  func Test_Rego_MountPolicy_BadType(t *testing.T) {
  1694  	f := func(p *generatedConstraints) bool {
  1695  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1696  		if err != nil {
  1697  			t.Error(err)
  1698  			return false
  1699  		}
  1700  
  1701  		index := randMinMax(testRand, 0, int32(len(tc.mounts)-1))
  1702  		tc.mounts[index].Type = randString(testRand, 4)
  1703  
  1704  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  1705  
  1706  		// not getting an error means something is broken
  1707  		if err == nil {
  1708  			return false
  1709  		}
  1710  
  1711  		return assertDecisionJSONContains(t, err, "invalid mount list")
  1712  	}
  1713  
  1714  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  1715  		t.Errorf("Test_Rego_MountPolicy_BadType: %v", err)
  1716  	}
  1717  }
  1718  
  1719  func Test_Rego_MountPolicy_BadOption(t *testing.T) {
  1720  	f := func(p *generatedConstraints) bool {
  1721  		tc, err := setupSimpleRegoCreateContainerTest(p)
  1722  		if err != nil {
  1723  			t.Error(err)
  1724  			return false
  1725  		}
  1726  
  1727  		mindex := randMinMax(testRand, 0, int32(len(tc.mounts)-1))
  1728  		mountToChange := tc.mounts[mindex]
  1729  		oindex := randMinMax(testRand, 0, int32(len(mountToChange.Options)-1))
  1730  		tc.mounts[mindex].Options[oindex] = randString(testRand, maxGeneratedMountOptionLength)
  1731  
  1732  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  1733  
  1734  		// not getting an error means something is broken
  1735  		if err == nil {
  1736  			t.Error("We changed a mount option and it didn't result in an error")
  1737  			return false
  1738  		}
  1739  
  1740  		return assertDecisionJSONContains(t, err, "invalid mount list")
  1741  	}
  1742  
  1743  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  1744  		t.Errorf("Test_Rego_MountPolicy_BadOption: %v", err)
  1745  	}
  1746  }
  1747  
  1748  func Test_Rego_MountPolicy_MountPrivilegedWhenNotAllowed(t *testing.T) {
  1749  	f := func(p *generatedConstraints) bool {
  1750  		tc, err := setupRegoPrivilegedMountTest(p)
  1751  		if err != nil {
  1752  			t.Error(err)
  1753  			return false
  1754  		}
  1755  
  1756  		mindex := randMinMax(testRand, 0, int32(len(tc.mounts)-1))
  1757  		mountToChange := tc.mounts[mindex]
  1758  		oindex := randMinMax(testRand, 0, int32(len(mountToChange.Options)-1))
  1759  		tc.mounts[mindex].Options[oindex] = randString(testRand, maxGeneratedMountOptionLength)
  1760  
  1761  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  1762  
  1763  		// not getting an error means something is broken
  1764  		if err == nil {
  1765  			t.Error("We tried to mount a privileged mount when not allowed and it didn't result in an error")
  1766  			return false
  1767  		}
  1768  
  1769  		return assertDecisionJSONContains(t, err, "invalid mount list")
  1770  	}
  1771  
  1772  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  1773  		t.Errorf("Test_Rego_MountPolicy_BadOption: %v", err)
  1774  	}
  1775  }
  1776  
  1777  // Tests whether an error is raised if support information is requested for
  1778  // an enforcement point which does not have stored version information.
  1779  func Test_Rego_Version_Unregistered_Enforcement_Point(t *testing.T) {
  1780  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  1781  	securityPolicy := gc.toPolicy()
  1782  	policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
  1783  	if err != nil {
  1784  		t.Fatalf("unable to create a new Rego policy: %v", err)
  1785  	}
  1786  
  1787  	enforcementPoint := testDataGenerator.uniqueEnforcementPoint()
  1788  	_, err = policy.queryEnforcementPoint(enforcementPoint)
  1789  
  1790  	// we expect an error, not getting one means something is broken
  1791  	if err == nil {
  1792  		t.Fatal("an error was not thrown when asking whether an unregistered enforcement point was available")
  1793  	}
  1794  }
  1795  
  1796  // Tests whether an error is raised if support information is requested for
  1797  // a version of an enforcement point which is of a later version than the
  1798  // framework. This should not happen, but may occur during development if
  1799  // version numbers have been entered incorrectly.
  1800  func Test_Rego_Version_Future_Enforcement_Point(t *testing.T) {
  1801  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  1802  	securityPolicy := gc.toPolicy()
  1803  	policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
  1804  	if err != nil {
  1805  		t.Fatalf("unable to create a new Rego policy: %v", err)
  1806  	}
  1807  
  1808  	err = policy.injectTestAPI()
  1809  	if err != nil {
  1810  		t.Fatal(err)
  1811  	}
  1812  
  1813  	_, err = policy.queryEnforcementPoint("__fixture_for_future_test__")
  1814  
  1815  	// we expect an error, not getting one means something is broken
  1816  	if err == nil {
  1817  		t.Fatalf("an error was not thrown when asking whether an enforcement point from the future was available")
  1818  	}
  1819  
  1820  	expected_error := "enforcement point rule __fixture_for_future_test__ is invalid"
  1821  	if err.Error() != expected_error {
  1822  		t.Fatalf("error message when asking for a future enforcement point was incorrect.")
  1823  	}
  1824  }
  1825  
  1826  // Tests whether the enforcement point logic returns the default behavior
  1827  // and "unsupported" when the enforcement point was added in a version of the
  1828  // framework that was released after the policy was authored as indicated
  1829  // by their respective version information.
  1830  func Test_Rego_Version_Unavailable_Enforcement_Point(t *testing.T) {
  1831  	code := "package policy\n\napi_version := \"0.0.1\""
  1832  	policy, err := newRegoPolicy(code, []oci.Mount{}, []oci.Mount{})
  1833  	if err != nil {
  1834  		t.Fatalf("unable to create a new Rego policy: %v", err)
  1835  	}
  1836  
  1837  	err = policy.injectTestAPI()
  1838  	if err != nil {
  1839  		t.Fatal(err)
  1840  	}
  1841  
  1842  	info, err := policy.queryEnforcementPoint("__fixture_for_allowed_test_true__")
  1843  	// we do not expect an error, getting one means something is broken
  1844  	if err != nil {
  1845  		t.Fatalf("unable to query whether enforcement point is available: %v", err)
  1846  	}
  1847  
  1848  	if info.availableByPolicyVersion {
  1849  		t.Error("unavailable enforcement incorrectly indicated as available")
  1850  	}
  1851  
  1852  	allowed, err := info.defaultResults.Bool("allowed")
  1853  
  1854  	if err != nil {
  1855  		t.Error(err)
  1856  	}
  1857  
  1858  	if !allowed {
  1859  		t.Error("default behavior was incorrect for unavailable enforcement point")
  1860  	}
  1861  }
  1862  
  1863  func Test_Rego_Enforcement_Point_Allowed(t *testing.T) {
  1864  	code := "package policy\n\napi_version := \"0.0.1\""
  1865  	policy, err := newRegoPolicy(code, []oci.Mount{}, []oci.Mount{})
  1866  	if err != nil {
  1867  		t.Fatalf("unable to create a new Rego policy: %v", err)
  1868  	}
  1869  
  1870  	err = policy.injectTestAPI()
  1871  	if err != nil {
  1872  		t.Fatal(err)
  1873  	}
  1874  
  1875  	input := make(map[string]interface{})
  1876  	results, err := policy.applyDefaults("__fixture_for_allowed_test_false__", input)
  1877  	if err != nil {
  1878  		t.Fatalf("applied defaults for an enforcement point receieved an error: %v", err)
  1879  	}
  1880  
  1881  	allowed, err := results.Bool("allowed")
  1882  
  1883  	if err != nil {
  1884  		t.Error(err)
  1885  	}
  1886  
  1887  	if allowed {
  1888  		t.Fatal("result of allowed for an available enforcement point was not the specified default (false)")
  1889  	}
  1890  
  1891  	input = make(map[string]interface{})
  1892  	results, err = policy.applyDefaults("__fixture_for_allowed_test_true__", input)
  1893  	if err != nil {
  1894  		t.Fatalf("applied defaults for an enforcement point receieved an error: %v", err)
  1895  	}
  1896  
  1897  	allowed, err = results.Bool("allowed")
  1898  
  1899  	if err != nil {
  1900  		t.Error(err)
  1901  	}
  1902  
  1903  	if !allowed {
  1904  		t.Error("result of allowed for an available enforcement point was not the specified default (true)")
  1905  	}
  1906  }
  1907  
  1908  func Test_Rego_Enforcement_Point_Extra(t *testing.T) {
  1909  	ctx := context.Background()
  1910  	code := `package policy
  1911  
  1912  api_version := "0.0.1"
  1913  
  1914  __fixture_for_allowed_extra__ := {"allowed": true}
  1915  `
  1916  	policy, err := newRegoPolicy(code, []oci.Mount{}, []oci.Mount{})
  1917  	if err != nil {
  1918  		t.Fatalf("unable to create a new Rego policy: %v", err)
  1919  	}
  1920  
  1921  	err = policy.injectTestAPI()
  1922  	if err != nil {
  1923  		t.Fatal(err)
  1924  	}
  1925  
  1926  	input := make(map[string]interface{})
  1927  	results, err := policy.enforce(ctx, "__fixture_for_allowed_extra__", input)
  1928  	if err != nil {
  1929  		t.Fatalf("enforcement produced an error: %v", err)
  1930  	}
  1931  
  1932  	allowed, err := results.Bool("allowed")
  1933  
  1934  	if err != nil {
  1935  		t.Error(err)
  1936  	}
  1937  
  1938  	if !allowed {
  1939  		t.Error("result of allowed for an available enforcement point was not the policy value (true)")
  1940  	}
  1941  
  1942  	if extra, ok := results["__test__"]; ok {
  1943  		if extra != "test" {
  1944  			t.Errorf("extra value was not specified default: %s != test", extra)
  1945  		}
  1946  	} else {
  1947  		t.Error("extra value is missing from enforcement result")
  1948  	}
  1949  }
  1950  
  1951  func Test_Rego_No_API_Version(t *testing.T) {
  1952  	code := "package policy"
  1953  	policy, err := newRegoPolicy(code, []oci.Mount{}, []oci.Mount{})
  1954  	if err != nil {
  1955  		t.Fatalf("unable to create a new Rego policy: %v", err)
  1956  	}
  1957  
  1958  	err = policy.injectTestAPI()
  1959  	if err != nil {
  1960  		t.Fatal(err)
  1961  	}
  1962  
  1963  	_, err = policy.queryEnforcementPoint("__fixture_for_allowed_test_true__")
  1964  
  1965  	if err == nil {
  1966  		t.Error("querying an enforcement point without an api_version did not produce an error")
  1967  	}
  1968  
  1969  	if err.Error() != noAPIVersionError {
  1970  		t.Errorf("querying an enforcement point without an api_version produced an incorrect error: %s", err)
  1971  	}
  1972  }
  1973  
  1974  func Test_Rego_ExecInContainerPolicy(t *testing.T) {
  1975  	f := func(p *generatedConstraints) bool {
  1976  		tc, err := setupRegoRunningContainerTest(p, false)
  1977  		if err != nil {
  1978  			t.Error(err)
  1979  			return false
  1980  		}
  1981  
  1982  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  1983  		capabilities := container.container.Capabilities.toExternal()
  1984  
  1985  		process := selectExecProcess(container.container.ExecProcesses, testRand)
  1986  		envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  1987  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  1988  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  1989  		umask := container.container.User.Umask
  1990  
  1991  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  1992  
  1993  		// getting an error means something is broken
  1994  		if err != nil {
  1995  			t.Error(err)
  1996  			return false
  1997  		}
  1998  
  1999  		return true
  2000  	}
  2001  
  2002  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2003  		t.Errorf("Test_Rego_ExecInContainerPolicy: %v", err)
  2004  	}
  2005  }
  2006  
  2007  func Test_Rego_ExecInContainerPolicy_No_Matches(t *testing.T) {
  2008  	f := func(p *generatedConstraints) bool {
  2009  		tc, err := setupRegoRunningContainerTest(p, false)
  2010  		if err != nil {
  2011  			t.Error(err)
  2012  			return false
  2013  		}
  2014  
  2015  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2016  		capabilities := container.container.Capabilities.toExternal()
  2017  
  2018  		process := generateContainerExecProcess(testRand)
  2019  		envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  2020  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  2021  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  2022  		umask := container.container.User.Umask
  2023  
  2024  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2025  		if err == nil {
  2026  			t.Error("Test unexpectedly passed")
  2027  			return false
  2028  		}
  2029  
  2030  		return true
  2031  	}
  2032  
  2033  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2034  		t.Errorf("Test_Rego_ExecInContainerPolicy_No_Matches: %v", err)
  2035  	}
  2036  }
  2037  
  2038  func Test_Rego_ExecInContainerPolicy_Command_No_Match(t *testing.T) {
  2039  	f := func(p *generatedConstraints) bool {
  2040  		tc, err := setupRegoRunningContainerTest(p, false)
  2041  		if err != nil {
  2042  			t.Error(err)
  2043  			return false
  2044  		}
  2045  
  2046  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2047  		envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  2048  
  2049  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  2050  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  2051  		umask := container.container.User.Umask
  2052  		capabilities := container.container.Capabilities.toExternal()
  2053  
  2054  		command := generateCommand(testRand)
  2055  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2056  
  2057  		// not getting an error means something is broken
  2058  		if err == nil {
  2059  			t.Error("Unexpected success when enforcing policy")
  2060  			return false
  2061  		}
  2062  
  2063  		return assertDecisionJSONContains(t, err, "invalid command")
  2064  	}
  2065  
  2066  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2067  		t.Errorf("Test_Rego_ExecInContainerPolicy_Command_No_Match: %v", err)
  2068  	}
  2069  }
  2070  
  2071  func Test_Rego_ExecInContainerPolicy_Some_Env_Not_Allowed(t *testing.T) {
  2072  	f := func(p *generatedConstraints) bool {
  2073  		tc, err := setupRegoRunningContainerTest(p, false)
  2074  		if err != nil {
  2075  			t.Error(err)
  2076  			return false
  2077  		}
  2078  
  2079  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2080  		process := selectExecProcess(container.container.ExecProcesses, testRand)
  2081  		envList := generateEnvironmentVariables(testRand)
  2082  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  2083  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  2084  		umask := container.container.User.Umask
  2085  		capabilities := container.container.Capabilities.toExternal()
  2086  
  2087  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2088  
  2089  		// not getting an error means something is broken
  2090  		if err == nil {
  2091  			t.Error("Unexpected success when enforcing policy")
  2092  			return false
  2093  		}
  2094  
  2095  		return assertDecisionJSONContains(t, err, "invalid env list")
  2096  	}
  2097  
  2098  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2099  		t.Errorf("Test_Rego_ExecInContainerPolicy_Some_Env_Not_Allowed: %v", err)
  2100  	}
  2101  }
  2102  
  2103  func Test_Rego_ExecInContainerPolicy_WorkingDir_No_Match(t *testing.T) {
  2104  	f := func(p *generatedConstraints) bool {
  2105  		tc, err := setupRegoRunningContainerTest(p, false)
  2106  		if err != nil {
  2107  			t.Error(err)
  2108  			return false
  2109  		}
  2110  
  2111  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2112  		process := selectExecProcess(container.container.ExecProcesses, testRand)
  2113  		envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  2114  		workingDir := generateWorkingDir(testRand)
  2115  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  2116  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  2117  		umask := container.container.User.Umask
  2118  		capabilities := container.container.Capabilities.toExternal()
  2119  
  2120  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, workingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2121  
  2122  		// not getting an error means something is broken
  2123  		if err == nil {
  2124  			t.Error("Unexpected success when enforcing policy")
  2125  			return false
  2126  		}
  2127  
  2128  		return assertDecisionJSONContains(t, err, "invalid working directory")
  2129  	}
  2130  
  2131  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2132  		t.Errorf("Test_Rego_ExecInContainerPolicy_WorkingDir_No_Match: %v", err)
  2133  	}
  2134  }
  2135  
  2136  func Test_Rego_ExecInContainerPolicy_Capabilities_No_Match(t *testing.T) {
  2137  	f := func(p *generatedConstraints) bool {
  2138  		tc, err := setupRegoRunningContainerTest(p, false)
  2139  		if err != nil {
  2140  			t.Error(err)
  2141  			return false
  2142  		}
  2143  
  2144  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2145  		process := selectExecProcess(container.container.ExecProcesses, testRand)
  2146  		envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  2147  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  2148  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  2149  		umask := container.container.User.Umask
  2150  
  2151  		capabilities := copyLinuxCapabilities(container.container.Capabilities.toExternal())
  2152  		capabilities.Bounding = superCapabilitySet(testRand, capabilities.Bounding)
  2153  
  2154  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2155  
  2156  		// not getting an error means something is broken
  2157  		if err == nil {
  2158  			t.Error("Unexpected success with bounding as a superset of allowed capabilities")
  2159  			return false
  2160  		}
  2161  
  2162  		if !assertDecisionJSONContains(t, err, "capabilities don't match") {
  2163  			t.Errorf("Didn't find expected error message\n%v\n", err)
  2164  			return false
  2165  		}
  2166  
  2167  		capabilities = copyLinuxCapabilities(container.container.Capabilities.toExternal())
  2168  		capabilities.Effective = superCapabilitySet(testRand, capabilities.Effective)
  2169  
  2170  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2171  
  2172  		// not getting an error means something is broken
  2173  		if err == nil {
  2174  			t.Error("Unexpected success with effective as a superset of allowed capabilities")
  2175  			return false
  2176  		}
  2177  
  2178  		if !assertDecisionJSONContains(t, err, "capabilities don't match") {
  2179  			t.Errorf("Didn't find expected error message\n%v\n", err)
  2180  			return false
  2181  		}
  2182  
  2183  		capabilities = copyLinuxCapabilities(container.container.Capabilities.toExternal())
  2184  		capabilities.Inheritable = superCapabilitySet(testRand, capabilities.Inheritable)
  2185  
  2186  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2187  
  2188  		// not getting an error means something is broken
  2189  		if err == nil {
  2190  			t.Error("Unexpected success with inheritable as a superset of allowed capabilities")
  2191  			return false
  2192  		}
  2193  
  2194  		if !assertDecisionJSONContains(t, err, "capabilities don't match") {
  2195  			t.Errorf("Didn't find expected error message\n%v\n", err)
  2196  			return false
  2197  		}
  2198  
  2199  		capabilities = copyLinuxCapabilities(container.container.Capabilities.toExternal())
  2200  		capabilities.Permitted = superCapabilitySet(testRand, capabilities.Permitted)
  2201  
  2202  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2203  
  2204  		// not getting an error means something is broken
  2205  		if err == nil {
  2206  			t.Error("Unexpected success with permitted as a superset of allowed capabilities")
  2207  			return false
  2208  		}
  2209  
  2210  		if !assertDecisionJSONContains(t, err, "capabilities don't match") {
  2211  			t.Errorf("Didn't find expected error message\n%v\n", err)
  2212  			return false
  2213  		}
  2214  
  2215  		capabilities = copyLinuxCapabilities(container.container.Capabilities.toExternal())
  2216  		capabilities.Ambient = superCapabilitySet(testRand, capabilities.Ambient)
  2217  
  2218  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2219  
  2220  		// not getting an error means something is broken
  2221  		if err == nil {
  2222  			t.Error("Unexpected success with ambient as a superset of allowed capabilities")
  2223  			return false
  2224  		}
  2225  
  2226  		if !assertDecisionJSONContains(t, err, "capabilities don't match") {
  2227  			t.Errorf("Didn't find expected error message\n%v\n", err)
  2228  			return false
  2229  		}
  2230  
  2231  		return true
  2232  	}
  2233  
  2234  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2235  		t.Errorf("Test_Rego_ExecInContainerPolicy_Capabilities_No_Match: %v", err)
  2236  	}
  2237  }
  2238  
  2239  func Test_Rego_ExecInContainerPolicy_CapabilitiesIsNil(t *testing.T) {
  2240  	constraints := generateConstraints(testRand, 1)
  2241  	tc, err := setupRegoRunningContainerTest(constraints, false)
  2242  	if err != nil {
  2243  		t.Fatal(err)
  2244  	}
  2245  
  2246  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2247  	process := selectExecProcess(container.container.ExecProcesses, testRand)
  2248  	envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  2249  	user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  2250  	groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  2251  	umask := container.container.User.Umask
  2252  
  2253  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(constraints.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, nil)
  2254  
  2255  	if err == nil {
  2256  		t.Fatal("Unexpected success with nil capabilities")
  2257  	}
  2258  
  2259  	if err.Error() != capabilitiesNilError {
  2260  		t.Fatal("No error message given for denial by capability being nil")
  2261  	}
  2262  }
  2263  
  2264  func Test_Rego_ExecInContainerPolicy_CapabilitiesAreEmpty(t *testing.T) {
  2265  	constraints := generateConstraints(testRand, 1)
  2266  	constraints.containers[0].Capabilities.Bounding = make([]string, 0)
  2267  	constraints.containers[0].Capabilities.Effective = make([]string, 0)
  2268  	constraints.containers[0].Capabilities.Inheritable = make([]string, 0)
  2269  	constraints.containers[0].Capabilities.Permitted = make([]string, 0)
  2270  	constraints.containers[0].Capabilities.Ambient = make([]string, 0)
  2271  
  2272  	tc, err := setupRegoRunningContainerTest(constraints, false)
  2273  	if err != nil {
  2274  		t.Fatal(err)
  2275  	}
  2276  
  2277  	capabilities := oci.LinuxCapabilities{}
  2278  
  2279  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2280  	process := selectExecProcess(container.container.ExecProcesses, testRand)
  2281  	envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  2282  	user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  2283  	groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  2284  	umask := container.container.User.Umask
  2285  
  2286  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(constraints.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2287  
  2288  	if err != nil {
  2289  		t.Fatal("Unexpected failure")
  2290  	}
  2291  }
  2292  
  2293  func Test_Rego_ExecInContainerPolicy_Capabilities_Drop(t *testing.T) {
  2294  	f := func(p *generatedConstraints) bool {
  2295  		p.allowCapabilityDropping = true
  2296  		tc, err := setupRegoRunningContainerTest(p, false)
  2297  		if err != nil {
  2298  			t.Error(err)
  2299  			return false
  2300  		}
  2301  
  2302  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2303  		process := selectExecProcess(container.container.ExecProcesses, testRand)
  2304  		envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  2305  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  2306  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  2307  		umask := container.container.User.Umask
  2308  
  2309  		capabilities := copyLinuxCapabilities(container.container.Capabilities.toExternal())
  2310  		capabilities.Bounding = superCapabilitySet(testRand, capabilities.Bounding)
  2311  
  2312  		extraCapabilities := generateCapabilities(testRand)
  2313  		capabilities.Bounding = append(capabilities.Bounding, extraCapabilities.Bounding...)
  2314  		capabilities.Effective = append(capabilities.Effective, extraCapabilities.Effective...)
  2315  		capabilities.Inheritable = append(capabilities.Inheritable, extraCapabilities.Inheritable...)
  2316  		capabilities.Permitted = append(capabilities.Permitted, extraCapabilities.Permitted...)
  2317  		capabilities.Ambient = append(capabilities.Ambient, extraCapabilities.Ambient...)
  2318  
  2319  		_, actual, _, err := tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2320  
  2321  		if err != nil {
  2322  			t.Errorf("Expected exec in container to be allowed. It wasn't for extra capabilities: %v", err)
  2323  			return false
  2324  		}
  2325  
  2326  		if !areStringArraysEqual(actual.Bounding, container.container.Capabilities.Bounding) {
  2327  			t.Errorf("bounding capabilities were not dropped correctly.")
  2328  			return false
  2329  		}
  2330  
  2331  		if !areStringArraysEqual(actual.Effective, container.container.Capabilities.Effective) {
  2332  			t.Errorf("effective capabilities were not dropped correctly.")
  2333  			return false
  2334  		}
  2335  
  2336  		if !areStringArraysEqual(actual.Inheritable, container.container.Capabilities.Inheritable) {
  2337  			t.Errorf("inheritable capabilities were not dropped correctly.")
  2338  			return false
  2339  		}
  2340  
  2341  		if !areStringArraysEqual(actual.Permitted, container.container.Capabilities.Permitted) {
  2342  			t.Errorf("permitted capabilities were not dropped correctly.")
  2343  			return false
  2344  		}
  2345  
  2346  		if !areStringArraysEqual(actual.Ambient, container.container.Capabilities.Ambient) {
  2347  			t.Errorf("ambient capabilities were not dropped correctly.")
  2348  			return false
  2349  		}
  2350  
  2351  		return true
  2352  	}
  2353  
  2354  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2355  		t.Errorf("Test_Rego_ExecInContainerPolicy_Capabilities_Drop: %v", err)
  2356  	}
  2357  }
  2358  
  2359  func Test_Rego_ExecInContainerPolicy_DropEnvs(t *testing.T) {
  2360  	testFunc := func(gc *generatedConstraints) bool {
  2361  		gc.allowEnvironmentVariableDropping = true
  2362  		tc, err := setupRegoRunningContainerTest(gc, false)
  2363  		if err != nil {
  2364  			t.Error(err)
  2365  			return false
  2366  		}
  2367  
  2368  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2369  		capabilities := container.container.Capabilities.toExternal()
  2370  
  2371  		process := selectExecProcess(container.container.ExecProcesses, testRand)
  2372  		expected := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  2373  
  2374  		extraRules := generateEnvironmentVariableRules(testRand)
  2375  		extraEnvs := buildEnvironmentVariablesFromEnvRules(extraRules, testRand)
  2376  
  2377  		envList := append(expected, extraEnvs...)
  2378  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  2379  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  2380  		umask := container.container.User.Umask
  2381  
  2382  		actual, _, _, err := tc.policy.EnforceExecInContainerPolicy(gc.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  2383  
  2384  		if err != nil {
  2385  			t.Errorf("expected exec in container process to be allowed. It wasn't: %v", err)
  2386  			return false
  2387  		}
  2388  
  2389  		if !areStringArraysEqual(actual, expected) {
  2390  			t.Errorf("environment variables were not dropped correctly.")
  2391  			return false
  2392  		}
  2393  
  2394  		return true
  2395  	}
  2396  
  2397  	if err := quick.Check(testFunc, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2398  		t.Errorf("Test_Rego_ExecInContainerPolicy_DropEnvs: %v", err)
  2399  	}
  2400  }
  2401  
  2402  func Test_Rego_MaliciousEnvList(t *testing.T) {
  2403  	template := `package policy
  2404  create_container := {
  2405  	"allowed": true,
  2406  	"env_list": ["%s"]
  2407  }
  2408  
  2409  exec_in_container := {
  2410  	"allowed": true,
  2411  	"env_list": ["%s"]
  2412  }
  2413  
  2414  exec_external := {
  2415  	"allowed": true,
  2416  	"env_list": ["%s"]
  2417  }`
  2418  
  2419  	generateEnv := func(r *rand.Rand) string {
  2420  		return randVariableString(r, maxGeneratedEnvironmentVariableRuleLength)
  2421  	}
  2422  
  2423  	generateEnvs := func(envSet stringSet) []string {
  2424  		numVars := atLeastOneAtMost(testRand, maxGeneratedEnvironmentVariableRules)
  2425  		return envSet.randUniqueArray(testRand, generateEnv, numVars)
  2426  	}
  2427  
  2428  	testFunc := func(gc *generatedConstraints) bool {
  2429  		envSet := make(stringSet)
  2430  		rego := fmt.Sprintf(
  2431  			template,
  2432  			strings.Join(generateEnvs(envSet), `","`),
  2433  			strings.Join(generateEnvs(envSet), `","`),
  2434  			strings.Join(generateEnvs(envSet), `","`))
  2435  
  2436  		policy, err := newRegoPolicy(rego, []oci.Mount{}, []oci.Mount{})
  2437  		if err != nil {
  2438  			t.Errorf("error creating policy: %v", err)
  2439  			return false
  2440  		}
  2441  
  2442  		user := generateIDName(testRand)
  2443  		capabilities := &oci.LinuxCapabilities{}
  2444  		seccomp := ""
  2445  
  2446  		envList := generateEnvs(envSet)
  2447  		toKeep, _, _, err := policy.EnforceCreateContainerPolicy(gc.ctx, "", "", []string{}, envList, "", []oci.Mount{}, false, true, user, nil, "", capabilities, seccomp)
  2448  		if len(toKeep) > 0 {
  2449  			t.Error("invalid environment variables not filtered from list returned from create_container")
  2450  			return false
  2451  		}
  2452  
  2453  		envList = generateEnvs(envSet)
  2454  		toKeep, _, _, err = policy.EnforceExecInContainerPolicy(gc.ctx, "", []string{}, envList, "", true, user, nil, "", capabilities)
  2455  		if len(toKeep) > 0 {
  2456  			t.Error("invalid environment variables not filtered from list returned from exec_in_container")
  2457  			return false
  2458  		}
  2459  
  2460  		envList = generateEnvs(envSet)
  2461  		toKeep, _, err = policy.EnforceExecExternalProcessPolicy(gc.ctx, []string{}, envList, "")
  2462  		if len(toKeep) > 0 {
  2463  			t.Error("invalid environment variables not filtered from list returned from exec_external")
  2464  			return false
  2465  		}
  2466  
  2467  		return true
  2468  	}
  2469  
  2470  	if err := quick.Check(testFunc, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  2471  		t.Errorf("Test_Rego_MaliciousEnvList: %v", err)
  2472  	}
  2473  }
  2474  
  2475  func Test_Rego_InvalidEnvList(t *testing.T) {
  2476  	rego := fmt.Sprintf(`package policy
  2477  	api_version := "%s"
  2478  	framework_version := "%s"
  2479  
  2480  	create_container := {
  2481  		"allowed": true,
  2482  		"env_list": {"an_object": 1}
  2483  	}
  2484  	exec_in_container := {
  2485  		"allowed": true,
  2486  		"env_list": "string"
  2487  	}
  2488  	exec_external := {
  2489  		"allowed": true,
  2490  		"env_list": true
  2491  	}`, apiVersion, frameworkVersion)
  2492  
  2493  	policy, err := newRegoPolicy(rego, []oci.Mount{}, []oci.Mount{})
  2494  	if err != nil {
  2495  		t.Fatalf("error creating policy: %v", err)
  2496  	}
  2497  
  2498  	ctx := context.Background()
  2499  	user := generateIDName(testRand)
  2500  	capabilities := &oci.LinuxCapabilities{}
  2501  	seccomp := ""
  2502  	_, _, _, err = policy.EnforceCreateContainerPolicy(ctx, "", "", []string{}, []string{}, "", []oci.Mount{}, false, true, user, nil, "", capabilities, seccomp)
  2503  	if err == nil {
  2504  		t.Errorf("expected call to create_container to fail")
  2505  	} else if err.Error() != "policy returned incorrect type for 'env_list', expected []interface{}, received map[string]interface {}" {
  2506  		t.Errorf("incorrected error message from call to create_container: %v", err)
  2507  	}
  2508  
  2509  	_, _, _, err = policy.EnforceExecInContainerPolicy(ctx, "", []string{}, []string{}, "", true, user, nil, "", capabilities)
  2510  	if err == nil {
  2511  		t.Errorf("expected call to exec_in_container to fail")
  2512  	} else if err.Error() != "policy returned incorrect type for 'env_list', expected []interface{}, received string" {
  2513  		t.Errorf("incorrected error message from call to exec_in_container: %v", err)
  2514  	}
  2515  
  2516  	_, _, err = policy.EnforceExecExternalProcessPolicy(ctx, []string{}, []string{}, "")
  2517  	if err == nil {
  2518  		t.Errorf("expected call to exec_external to fail")
  2519  	} else if err.Error() != "policy returned incorrect type for 'env_list', expected []interface{}, received bool" {
  2520  		t.Errorf("incorrected error message from call to exec_external: %v", err)
  2521  	}
  2522  }
  2523  
  2524  func Test_Rego_InvalidEnvList_Member(t *testing.T) {
  2525  	rego := fmt.Sprintf(`package policy
  2526  	api_version := "%s"
  2527  	framework_version := "%s"
  2528  
  2529  	create_container := {
  2530  		"allowed": true,
  2531  		"env_list": ["one", "two", 3]
  2532  	}
  2533  	exec_in_container := {
  2534  		"allowed": true,
  2535  		"env_list": ["one", true, "three"]
  2536  	}
  2537  	exec_external := {
  2538  		"allowed": true,
  2539  		"env_list": ["one", ["two"], "three"]
  2540  	}`, apiVersion, frameworkVersion)
  2541  
  2542  	policy, err := newRegoPolicy(rego, []oci.Mount{}, []oci.Mount{})
  2543  	if err != nil {
  2544  		t.Fatalf("error creating policy: %v", err)
  2545  	}
  2546  
  2547  	ctx := context.Background()
  2548  	user := generateIDName(testRand)
  2549  	capabilities := &oci.LinuxCapabilities{}
  2550  	seccomp := ""
  2551  
  2552  	_, _, _, err = policy.EnforceCreateContainerPolicy(ctx, "", "", []string{}, []string{}, "", []oci.Mount{}, false, true, user, nil, "", capabilities, seccomp)
  2553  	if err == nil {
  2554  		t.Errorf("expected call to create_container to fail")
  2555  	} else if err.Error() != "members of env_list from policy must be strings, received json.Number" {
  2556  		t.Errorf("incorrected error message from call to create_container: %v", err)
  2557  	}
  2558  
  2559  	_, _, _, err = policy.EnforceExecInContainerPolicy(ctx, "", []string{}, []string{}, "", true, user, nil, "", capabilities)
  2560  	if err == nil {
  2561  		t.Errorf("expected call to exec_in_container to fail")
  2562  	} else if err.Error() != "members of env_list from policy must be strings, received bool" {
  2563  		t.Errorf("incorrected error message from call to exec_in_container: %v", err)
  2564  	}
  2565  
  2566  	_, _, err = policy.EnforceExecExternalProcessPolicy(ctx, []string{}, []string{}, "")
  2567  	if err == nil {
  2568  		t.Errorf("expected call to exec_external to fail")
  2569  	} else if err.Error() != "members of env_list from policy must be strings, received []interface {}" {
  2570  		t.Errorf("incorrected error message from call to exec_external: %v", err)
  2571  	}
  2572  }
  2573  
  2574  func Test_Rego_EnforceEnvironmentVariablePolicy_MissingRequired(t *testing.T) {
  2575  	testFunc := func(gc *generatedConstraints) bool {
  2576  		container := selectContainerFromContainerList(gc.containers, testRand)
  2577  		// add a rule to re2 match
  2578  		requiredRule := EnvRuleConfig{
  2579  			Strategy: "string",
  2580  			Rule:     randVariableString(testRand, maxGeneratedEnvironmentVariableRuleLength),
  2581  			Required: true,
  2582  		}
  2583  
  2584  		container.EnvRules = append(container.EnvRules, requiredRule)
  2585  
  2586  		tc, err := setupRegoCreateContainerTest(gc, container, false)
  2587  		if err != nil {
  2588  			t.Error(err)
  2589  			return false
  2590  		}
  2591  
  2592  		envList := make([]string, 0, len(container.EnvRules))
  2593  		for _, env := range tc.envList {
  2594  			if env != requiredRule.Rule {
  2595  				envList = append(envList, env)
  2596  			}
  2597  		}
  2598  
  2599  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(gc.ctx, tc.sandboxID, tc.containerID, tc.argList, envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  2600  
  2601  		// not getting an error means something is broken
  2602  		if err == nil {
  2603  			t.Errorf("Expected container setup to fail.")
  2604  			return false
  2605  		}
  2606  
  2607  		return true
  2608  	}
  2609  
  2610  	if err := quick.Check(testFunc, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  2611  		t.Errorf("Test_Rego_EnforceEnvironmentVariablePolicy_MissingRequired: %v", err)
  2612  	}
  2613  }
  2614  
  2615  func Test_Rego_ExecExternalProcessPolicy(t *testing.T) {
  2616  	f := func(p *generatedConstraints) bool {
  2617  		tc, err := setupExternalProcessTest(p)
  2618  		if err != nil {
  2619  			t.Error(err)
  2620  			return false
  2621  		}
  2622  
  2623  		process := selectExternalProcessFromConstraints(p, testRand)
  2624  		envList := buildEnvironmentVariablesFromEnvRules(process.envRules, testRand)
  2625  
  2626  		_, _, err = tc.policy.EnforceExecExternalProcessPolicy(p.ctx, process.command, envList, process.workingDir)
  2627  		if err != nil {
  2628  			t.Error("Policy enforcement unexpectedly was denied")
  2629  			return false
  2630  		}
  2631  
  2632  		return true
  2633  	}
  2634  
  2635  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  2636  		t.Errorf("Test_Rego_ExecExternalProcessPolicy: %v", err)
  2637  	}
  2638  }
  2639  
  2640  func Test_Rego_ExecExternalProcessPolicy_No_Matches(t *testing.T) {
  2641  	f := func(p *generatedConstraints) bool {
  2642  		tc, err := setupExternalProcessTest(p)
  2643  		if err != nil {
  2644  			t.Error(err)
  2645  			return false
  2646  		}
  2647  
  2648  		process := generateExternalProcess(testRand)
  2649  		envList := buildEnvironmentVariablesFromEnvRules(process.envRules, testRand)
  2650  
  2651  		_, _, err = tc.policy.EnforceExecExternalProcessPolicy(p.ctx, process.command, envList, process.workingDir)
  2652  		if err == nil {
  2653  			t.Error("Policy was unexpectedly not enforced")
  2654  			return false
  2655  		}
  2656  
  2657  		return true
  2658  	}
  2659  
  2660  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  2661  		t.Errorf("Test_Rego_ExecExternalProcessPolicy_No_Matches: %v", err)
  2662  	}
  2663  }
  2664  
  2665  func Test_Rego_ExecExternalProcessPolicy_Command_No_Match(t *testing.T) {
  2666  	f := func(p *generatedConstraints) bool {
  2667  		tc, err := setupExternalProcessTest(p)
  2668  		if err != nil {
  2669  			t.Error(err)
  2670  			return false
  2671  		}
  2672  
  2673  		process := selectExternalProcessFromConstraints(p, testRand)
  2674  		envList := buildEnvironmentVariablesFromEnvRules(process.envRules, testRand)
  2675  		command := generateCommand(testRand)
  2676  
  2677  		_, _, err = tc.policy.EnforceExecExternalProcessPolicy(p.ctx, command, envList, process.workingDir)
  2678  		if err == nil {
  2679  			t.Error("Policy was unexpectedly not enforced")
  2680  			return false
  2681  		}
  2682  
  2683  		return assertDecisionJSONContains(t, err, "invalid command")
  2684  	}
  2685  
  2686  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  2687  		t.Errorf("Test_Rego_ExecExternalProcessPolicy_Command_No_Match: %v", err)
  2688  	}
  2689  }
  2690  
  2691  func Test_Rego_ExecExternalProcessPolicy_Some_Env_Not_Allowed(t *testing.T) {
  2692  	f := func(p *generatedConstraints) bool {
  2693  		tc, err := setupExternalProcessTest(p)
  2694  		if err != nil {
  2695  			t.Error(err)
  2696  			return false
  2697  		}
  2698  
  2699  		process := selectExternalProcessFromConstraints(p, testRand)
  2700  		envList := generateEnvironmentVariables(testRand)
  2701  
  2702  		_, _, err = tc.policy.EnforceExecExternalProcessPolicy(p.ctx, process.command, envList, process.workingDir)
  2703  		if err == nil {
  2704  			t.Error("Policy was unexpectedly not enforced")
  2705  			return false
  2706  		}
  2707  
  2708  		return assertDecisionJSONContains(t, err, "invalid env list")
  2709  	}
  2710  
  2711  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  2712  		t.Errorf("Test_Rego_ExecExternalProcessPolicy_Some_Env_Not_Allowed: %v", err)
  2713  	}
  2714  }
  2715  
  2716  func Test_Rego_ExecExternalProcessPolicy_WorkingDir_No_Match(t *testing.T) {
  2717  	f := func(p *generatedConstraints) bool {
  2718  		tc, err := setupExternalProcessTest(p)
  2719  		if err != nil {
  2720  			t.Error(err)
  2721  			return false
  2722  		}
  2723  
  2724  		process := selectExternalProcessFromConstraints(p, testRand)
  2725  		envList := buildEnvironmentVariablesFromEnvRules(process.envRules, testRand)
  2726  		workingDir := generateWorkingDir(testRand)
  2727  
  2728  		_, _, err = tc.policy.EnforceExecExternalProcessPolicy(p.ctx, process.command, envList, workingDir)
  2729  		if err == nil {
  2730  			t.Error("Policy was unexpectedly not enforced")
  2731  			return false
  2732  		}
  2733  
  2734  		return assertDecisionJSONContains(t, err, "invalid working directory")
  2735  	}
  2736  
  2737  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  2738  		t.Errorf("Test_Rego_ExecExternalProcessPolicy_WorkingDir_No_Match: %v", err)
  2739  	}
  2740  }
  2741  
  2742  func Test_Rego_ExecExternalProcessPolicy_DropEnvs(t *testing.T) {
  2743  	testFunc := func(gc *generatedConstraints) bool {
  2744  		gc.allowEnvironmentVariableDropping = true
  2745  		tc, err := setupExternalProcessTest(gc)
  2746  		if err != nil {
  2747  			t.Error(err)
  2748  			return false
  2749  		}
  2750  
  2751  		process := selectExternalProcessFromConstraints(gc, testRand)
  2752  		expected := buildEnvironmentVariablesFromEnvRules(process.envRules, testRand)
  2753  
  2754  		extraRules := generateEnvironmentVariableRules(testRand)
  2755  		extraEnvs := buildEnvironmentVariablesFromEnvRules(extraRules, testRand)
  2756  
  2757  		envList := append(expected, extraEnvs...)
  2758  
  2759  		actual, _, err := tc.policy.EnforceExecExternalProcessPolicy(gc.ctx, process.command, envList, process.workingDir)
  2760  
  2761  		if err != nil {
  2762  			t.Errorf("expected exec in container process to be allowed. It wasn't: %v", err)
  2763  			return false
  2764  		}
  2765  
  2766  		if !areStringArraysEqual(actual, expected) {
  2767  			t.Errorf("environment variables were not dropped correctly.")
  2768  			return false
  2769  		}
  2770  
  2771  		return true
  2772  	}
  2773  
  2774  	if err := quick.Check(testFunc, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2775  		t.Errorf("Test_Rego_ExecExternalProcessPolicy_DropEnvs: %v", err)
  2776  	}
  2777  }
  2778  
  2779  func Test_Rego_ExecExternalProcessPolicy_DropEnvs_Multiple(t *testing.T) {
  2780  	envRules := setupEnvRuleSets(3)
  2781  
  2782  	gc := generateConstraints(testRand, 1)
  2783  	gc.allowEnvironmentVariableDropping = true
  2784  	process0 := generateExternalProcess(testRand)
  2785  
  2786  	process1 := process0.clone()
  2787  	process1.envRules = append(envRules[0], envRules[1]...)
  2788  
  2789  	process2 := process0.clone()
  2790  	process2.envRules = append(process1.envRules, envRules[2]...)
  2791  
  2792  	gc.externalProcesses = []*externalProcess{process0, process1, process2}
  2793  	securityPolicy := gc.toPolicy()
  2794  	defaultMounts := generateMounts(testRand)
  2795  	privilegedMounts := generateMounts(testRand)
  2796  
  2797  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  2798  		toOCIMounts(defaultMounts),
  2799  		toOCIMounts(privilegedMounts))
  2800  	if err != nil {
  2801  		t.Fatal(err)
  2802  	}
  2803  
  2804  	envs0 := buildEnvironmentVariablesFromEnvRules(envRules[0], testRand)
  2805  	envs1 := buildEnvironmentVariablesFromEnvRules(envRules[1], testRand)
  2806  	envs2 := buildEnvironmentVariablesFromEnvRules(envRules[2], testRand)
  2807  	envList := append(envs0, envs1...)
  2808  	envList = append(envList, envs2...)
  2809  
  2810  	actual, _, err := policy.EnforceExecExternalProcessPolicy(gc.ctx, process2.command, envList, process2.workingDir)
  2811  
  2812  	// getting an error means something is broken
  2813  	if err != nil {
  2814  		t.Errorf("Expected container creation to be allowed. It wasn't: %v", err)
  2815  	}
  2816  
  2817  	if !areStringArraysEqual(actual, envList) {
  2818  		t.Error("environment variables were not dropped correctly.")
  2819  	}
  2820  }
  2821  
  2822  func Test_Rego_ExecExternalProcessPolicy_DropEnvs_Multiple_NoMatch(t *testing.T) {
  2823  	envRules := setupEnvRuleSets(3)
  2824  
  2825  	gc := generateConstraints(testRand, 1)
  2826  	gc.allowEnvironmentVariableDropping = true
  2827  
  2828  	process0 := generateExternalProcess(testRand)
  2829  
  2830  	process1 := process0.clone()
  2831  	process1.envRules = append(envRules[0], envRules[1]...)
  2832  
  2833  	process2 := process0.clone()
  2834  	process2.envRules = append(envRules[0], envRules[2]...)
  2835  
  2836  	gc.externalProcesses = []*externalProcess{process0, process1, process2}
  2837  	securityPolicy := gc.toPolicy()
  2838  	defaultMounts := generateMounts(testRand)
  2839  	privilegedMounts := generateMounts(testRand)
  2840  
  2841  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  2842  		toOCIMounts(defaultMounts),
  2843  		toOCIMounts(privilegedMounts))
  2844  	if err != nil {
  2845  		t.Fatal(err)
  2846  	}
  2847  
  2848  	envs0 := buildEnvironmentVariablesFromEnvRules(envRules[0], testRand)
  2849  	envs1 := buildEnvironmentVariablesFromEnvRules(envRules[1], testRand)
  2850  	envs2 := buildEnvironmentVariablesFromEnvRules(envRules[2], testRand)
  2851  	var extraLen int
  2852  	if len(envs1) > len(envs2) {
  2853  		extraLen = len(envs2)
  2854  	} else {
  2855  		extraLen = len(envs1)
  2856  	}
  2857  	envList := append(envs0, envs1[:extraLen]...)
  2858  	envList = append(envList, envs2[:extraLen]...)
  2859  
  2860  	actual, _, err := policy.EnforceExecExternalProcessPolicy(gc.ctx, process2.command, envList, process2.workingDir)
  2861  
  2862  	// not getting an error means something is broken
  2863  	if err == nil {
  2864  		t.Error("expected container creation to not be allowed.")
  2865  	}
  2866  
  2867  	if actual != nil {
  2868  		t.Error("envList should be nil.")
  2869  	}
  2870  }
  2871  
  2872  func Test_Rego_ShutdownContainerPolicy_Running_Container(t *testing.T) {
  2873  	p := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  2874  
  2875  	tc, err := setupRegoRunningContainerTest(p, false)
  2876  	if err != nil {
  2877  		t.Fatalf("Unable to set up test: %v", err)
  2878  	}
  2879  
  2880  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  2881  
  2882  	err = tc.policy.EnforceShutdownContainerPolicy(p.ctx, container.containerID)
  2883  	if err != nil {
  2884  		t.Fatal("Expected shutdown of running container to be allowed, it wasn't")
  2885  	}
  2886  }
  2887  
  2888  func Test_Rego_ShutdownContainerPolicy_Not_Running_Container(t *testing.T) {
  2889  	p := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  2890  
  2891  	tc, err := setupRegoRunningContainerTest(p, false)
  2892  	if err != nil {
  2893  		t.Fatalf("Unable to set up test: %v", err)
  2894  	}
  2895  
  2896  	notRunningContainerID := testDataGenerator.uniqueContainerID()
  2897  
  2898  	err = tc.policy.EnforceShutdownContainerPolicy(p.ctx, notRunningContainerID)
  2899  	if err == nil {
  2900  		t.Fatal("Expected shutdown of not running container to be denied, it wasn't")
  2901  	}
  2902  }
  2903  
  2904  func Test_Rego_SignalContainerProcessPolicy_InitProcess_Allowed(t *testing.T) {
  2905  	f := func(p *generatedConstraints) bool {
  2906  		hasAllowedSignals := generateConstraintsContainer(testRand, 1, maxLayersInGeneratedContainer)
  2907  		hasAllowedSignals.Signals = generateListOfSignals(testRand, 1, maxSignalNumber)
  2908  		p.containers = append(p.containers, hasAllowedSignals)
  2909  
  2910  		tc, err := setupRegoRunningContainerTest(p, false)
  2911  		if err != nil {
  2912  			t.Error(err)
  2913  			return false
  2914  		}
  2915  
  2916  		containerID, err := idForRunningContainer(hasAllowedSignals, tc.runningContainers)
  2917  		if err != nil {
  2918  			r, err := runContainer(tc.policy, hasAllowedSignals, tc.defaultMounts, tc.privilegedMounts, false)
  2919  			if err != nil {
  2920  				t.Errorf("Unable to setup test running container: %v", err)
  2921  				return false
  2922  			}
  2923  			containerID = r.containerID
  2924  		}
  2925  
  2926  		signal := selectSignalFromSignals(testRand, hasAllowedSignals.Signals)
  2927  		err = tc.policy.EnforceSignalContainerProcessPolicy(p.ctx, containerID, signal, true, hasAllowedSignals.Command)
  2928  
  2929  		if err != nil {
  2930  			t.Errorf("Signal init process unexpectedly failed: %v", err)
  2931  			return false
  2932  		}
  2933  
  2934  		return true
  2935  	}
  2936  
  2937  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2938  		t.Errorf("Test_Rego_SignalContainerProcessPolicy_InitProcess_Allowed: %v", err)
  2939  	}
  2940  }
  2941  
  2942  func Test_Rego_SignalContainerProcessPolicy_InitProcess_Not_Allowed(t *testing.T) {
  2943  	f := func(p *generatedConstraints) bool {
  2944  		hasNoAllowedSignals := generateConstraintsContainer(testRand, 1, maxLayersInGeneratedContainer)
  2945  		hasNoAllowedSignals.Signals = make([]syscall.Signal, 0)
  2946  
  2947  		p.containers = append(p.containers, hasNoAllowedSignals)
  2948  
  2949  		tc, err := setupRegoRunningContainerTest(p, false)
  2950  		if err != nil {
  2951  			t.Error(err)
  2952  			return false
  2953  		}
  2954  
  2955  		containerID, err := idForRunningContainer(hasNoAllowedSignals, tc.runningContainers)
  2956  		if err != nil {
  2957  			r, err := runContainer(tc.policy, hasNoAllowedSignals, tc.defaultMounts, tc.privilegedMounts, false)
  2958  			if err != nil {
  2959  				t.Errorf("Unable to setup test running container: %v", err)
  2960  				return false
  2961  			}
  2962  			containerID = r.containerID
  2963  		}
  2964  
  2965  		signal := generateSignal(testRand)
  2966  		err = tc.policy.EnforceSignalContainerProcessPolicy(p.ctx, containerID, signal, true, hasNoAllowedSignals.Command)
  2967  
  2968  		if err == nil {
  2969  			t.Errorf("Signal init process unexpectedly passed: %v", err)
  2970  			return false
  2971  		}
  2972  
  2973  		return true
  2974  	}
  2975  
  2976  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  2977  		t.Errorf("Test_Rego_SignalContainerProcessPolicy_InitProcess_Not_Allowed: %v", err)
  2978  	}
  2979  }
  2980  
  2981  func Test_Rego_SignalContainerProcessPolicy_InitProcess_Bad_ContainerID(t *testing.T) {
  2982  	f := func(p *generatedConstraints) bool {
  2983  		hasAllowedSignals := generateConstraintsContainer(testRand, 1, maxLayersInGeneratedContainer)
  2984  		hasAllowedSignals.Signals = generateListOfSignals(testRand, 1, maxSignalNumber)
  2985  		p.containers = append(p.containers, hasAllowedSignals)
  2986  
  2987  		tc, err := setupRegoRunningContainerTest(p, false)
  2988  		if err != nil {
  2989  			t.Error(err)
  2990  			return false
  2991  		}
  2992  
  2993  		_, err = idForRunningContainer(hasAllowedSignals, tc.runningContainers)
  2994  		if err != nil {
  2995  			_, err := runContainer(tc.policy, hasAllowedSignals, tc.defaultMounts, tc.privilegedMounts, false)
  2996  			if err != nil {
  2997  				t.Errorf("Unable to setup test running container: %v", err)
  2998  				return false
  2999  			}
  3000  		}
  3001  
  3002  		signal := selectSignalFromSignals(testRand, hasAllowedSignals.Signals)
  3003  		badContainerID := generateContainerID(testRand)
  3004  		err = tc.policy.EnforceSignalContainerProcessPolicy(p.ctx, badContainerID, signal, true, hasAllowedSignals.Command)
  3005  
  3006  		if err == nil {
  3007  			t.Errorf("Signal init process unexpectedly succeeded: %v", err)
  3008  			return false
  3009  		}
  3010  
  3011  		return true
  3012  	}
  3013  
  3014  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3015  		t.Errorf("Test_Rego_SignalContainerProcessPolicy_InitProcess_Bad_ContainerID: %v", err)
  3016  	}
  3017  }
  3018  
  3019  func Test_Rego_SignalContainerProcessPolicy_ExecProcess_Allowed(t *testing.T) {
  3020  	f := func(p *generatedConstraints) bool {
  3021  		containerUnderTest := generateConstraintsContainer(testRand, 1, maxLayersInGeneratedContainer)
  3022  
  3023  		ep := generateExecProcesses(testRand)
  3024  		ep[0].Signals = generateListOfSignals(testRand, 1, 4)
  3025  		containerUnderTest.ExecProcesses = ep
  3026  		processUnderTest := ep[0]
  3027  
  3028  		p.containers = append(p.containers, containerUnderTest)
  3029  
  3030  		tc, err := setupRegoRunningContainerTest(p, false)
  3031  		if err != nil {
  3032  			t.Error(err)
  3033  			return false
  3034  		}
  3035  
  3036  		containerID, err := idForRunningContainer(containerUnderTest, tc.runningContainers)
  3037  		if err != nil {
  3038  			r, err := runContainer(tc.policy, containerUnderTest, tc.defaultMounts, tc.privilegedMounts, false)
  3039  			if err != nil {
  3040  				t.Errorf("Unable to setup test running container: %v", err)
  3041  				return false
  3042  			}
  3043  			containerID = r.containerID
  3044  		}
  3045  
  3046  		envList := buildEnvironmentVariablesFromEnvRules(containerUnderTest.EnvRules, testRand)
  3047  		user := buildIDNameFromConfig(containerUnderTest.User.UserIDName, testRand)
  3048  		groups := buildGroupIDNamesFromUser(containerUnderTest.User, testRand)
  3049  		umask := containerUnderTest.User.Umask
  3050  		capabilities := containerUnderTest.Capabilities.toExternal()
  3051  
  3052  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, containerID, processUnderTest.Command, envList, containerUnderTest.WorkingDir, containerUnderTest.NoNewPrivileges, user, groups, umask, &capabilities)
  3053  		if err != nil {
  3054  			t.Errorf("Unable to exec process for test: %v", err)
  3055  			return false
  3056  		}
  3057  
  3058  		signal := selectSignalFromSignals(testRand, processUnderTest.Signals)
  3059  
  3060  		err = tc.policy.EnforceSignalContainerProcessPolicy(p.ctx, containerID, signal, false, processUnderTest.Command)
  3061  		if err != nil {
  3062  			t.Errorf("Signal init process unexpectedly failed: %v", err)
  3063  			return false
  3064  		}
  3065  
  3066  		return true
  3067  	}
  3068  
  3069  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3070  		t.Errorf("Test_Rego_SignalContainerProcessPolicy_ExecProcess_Allowed: %v", err)
  3071  	}
  3072  }
  3073  
  3074  func Test_Rego_SignalContainerProcessPolicy_ExecProcess_Not_Allowed(t *testing.T) {
  3075  	f := func(p *generatedConstraints) bool {
  3076  		containerUnderTest := generateConstraintsContainer(testRand, 1, maxLayersInGeneratedContainer)
  3077  
  3078  		ep := generateExecProcesses(testRand)
  3079  		ep[0].Signals = make([]syscall.Signal, 0)
  3080  		containerUnderTest.ExecProcesses = ep
  3081  		processUnderTest := ep[0]
  3082  
  3083  		p.containers = append(p.containers, containerUnderTest)
  3084  
  3085  		tc, err := setupRegoRunningContainerTest(p, false)
  3086  		if err != nil {
  3087  			t.Error(err)
  3088  			return false
  3089  		}
  3090  
  3091  		containerID, err := idForRunningContainer(containerUnderTest, tc.runningContainers)
  3092  		if err != nil {
  3093  			r, err := runContainer(tc.policy, containerUnderTest, tc.defaultMounts, tc.privilegedMounts, false)
  3094  			if err != nil {
  3095  				t.Errorf("Unable to setup test running container: %v", err)
  3096  				return false
  3097  			}
  3098  			containerID = r.containerID
  3099  		}
  3100  
  3101  		envList := buildEnvironmentVariablesFromEnvRules(containerUnderTest.EnvRules, testRand)
  3102  		user := buildIDNameFromConfig(containerUnderTest.User.UserIDName, testRand)
  3103  		groups := buildGroupIDNamesFromUser(containerUnderTest.User, testRand)
  3104  		umask := containerUnderTest.User.Umask
  3105  		capabilities := containerUnderTest.Capabilities.toExternal()
  3106  
  3107  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, containerID, processUnderTest.Command, envList, containerUnderTest.WorkingDir, containerUnderTest.NoNewPrivileges, user, groups, umask, &capabilities)
  3108  		if err != nil {
  3109  			t.Errorf("Unable to exec process for test: %v", err)
  3110  			return false
  3111  		}
  3112  
  3113  		signal := generateSignal(testRand)
  3114  
  3115  		err = tc.policy.EnforceSignalContainerProcessPolicy(p.ctx, containerID, signal, false, processUnderTest.Command)
  3116  		if err == nil {
  3117  			t.Errorf("Signal init process unexpectedly succeeded: %v", err)
  3118  			return false
  3119  		}
  3120  
  3121  		return true
  3122  	}
  3123  
  3124  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3125  		t.Errorf("Test_Rego_SignalContainerProcessPolicy_ExecProcess_Not_Allowed: %v", err)
  3126  	}
  3127  }
  3128  
  3129  func Test_Rego_SignalContainerProcessPolicy_ExecProcess_Bad_Command(t *testing.T) {
  3130  	f := func(p *generatedConstraints) bool {
  3131  		containerUnderTest := generateConstraintsContainer(testRand, 1, maxLayersInGeneratedContainer)
  3132  
  3133  		ep := generateExecProcesses(testRand)
  3134  		ep[0].Signals = generateListOfSignals(testRand, 1, 4)
  3135  		containerUnderTest.ExecProcesses = ep
  3136  		processUnderTest := ep[0]
  3137  
  3138  		p.containers = append(p.containers, containerUnderTest)
  3139  
  3140  		tc, err := setupRegoRunningContainerTest(p, false)
  3141  		if err != nil {
  3142  			t.Error(err)
  3143  			return false
  3144  		}
  3145  
  3146  		containerID, err := idForRunningContainer(containerUnderTest, tc.runningContainers)
  3147  		if err != nil {
  3148  			r, err := runContainer(tc.policy, containerUnderTest, tc.defaultMounts, tc.privilegedMounts, false)
  3149  			if err != nil {
  3150  				t.Errorf("Unable to setup test running container: %v", err)
  3151  				return false
  3152  			}
  3153  			containerID = r.containerID
  3154  		}
  3155  
  3156  		envList := buildEnvironmentVariablesFromEnvRules(containerUnderTest.EnvRules, testRand)
  3157  		user := buildIDNameFromConfig(containerUnderTest.User.UserIDName, testRand)
  3158  		groups := buildGroupIDNamesFromUser(containerUnderTest.User, testRand)
  3159  		umask := containerUnderTest.User.Umask
  3160  		capabilities := containerUnderTest.Capabilities.toExternal()
  3161  
  3162  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, containerID, processUnderTest.Command, envList, containerUnderTest.WorkingDir, containerUnderTest.NoNewPrivileges, user, groups, umask, &capabilities)
  3163  		if err != nil {
  3164  			t.Errorf("Unable to exec process for test: %v", err)
  3165  			return false
  3166  		}
  3167  
  3168  		signal := selectSignalFromSignals(testRand, processUnderTest.Signals)
  3169  		badCommand := generateCommand(testRand)
  3170  
  3171  		err = tc.policy.EnforceSignalContainerProcessPolicy(p.ctx, containerID, signal, false, badCommand)
  3172  		if err == nil {
  3173  			t.Errorf("Signal init process unexpectedly succeeded: %v", err)
  3174  			return false
  3175  		}
  3176  
  3177  		return true
  3178  	}
  3179  
  3180  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3181  		t.Errorf("Test_Rego_SignalContainerProcessPolicy_ExecProcess_Bad_Command: %v", err)
  3182  	}
  3183  }
  3184  
  3185  func Test_Rego_SignalContainerProcessPolicy_ExecProcess_Bad_ContainerID(t *testing.T) {
  3186  	f := func(p *generatedConstraints) bool {
  3187  		containerUnderTest := generateConstraintsContainer(testRand, 1, maxLayersInGeneratedContainer)
  3188  
  3189  		ep := generateExecProcesses(testRand)
  3190  		ep[0].Signals = generateListOfSignals(testRand, 1, 4)
  3191  		containerUnderTest.ExecProcesses = ep
  3192  		processUnderTest := ep[0]
  3193  
  3194  		p.containers = append(p.containers, containerUnderTest)
  3195  
  3196  		tc, err := setupRegoRunningContainerTest(p, false)
  3197  		if err != nil {
  3198  			t.Error(err)
  3199  			return false
  3200  		}
  3201  
  3202  		containerID, err := idForRunningContainer(containerUnderTest, tc.runningContainers)
  3203  		if err != nil {
  3204  			r, err := runContainer(tc.policy, containerUnderTest, tc.defaultMounts, tc.privilegedMounts, false)
  3205  			if err != nil {
  3206  				t.Errorf("Unable to setup test running container: %v", err)
  3207  				return false
  3208  			}
  3209  			containerID = r.containerID
  3210  		}
  3211  
  3212  		envList := buildEnvironmentVariablesFromEnvRules(containerUnderTest.EnvRules, testRand)
  3213  		user := buildIDNameFromConfig(containerUnderTest.User.UserIDName, testRand)
  3214  		groups := buildGroupIDNamesFromUser(containerUnderTest.User, testRand)
  3215  		umask := containerUnderTest.User.Umask
  3216  		capabilities := containerUnderTest.Capabilities.toExternal()
  3217  
  3218  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, containerID, processUnderTest.Command, envList, containerUnderTest.WorkingDir, containerUnderTest.NoNewPrivileges, user, groups, umask, &capabilities)
  3219  		if err != nil {
  3220  			t.Errorf("Unable to exec process for test: %v", err)
  3221  			return false
  3222  		}
  3223  
  3224  		signal := selectSignalFromSignals(testRand, processUnderTest.Signals)
  3225  		badContainerID := generateContainerID(testRand)
  3226  
  3227  		err = tc.policy.EnforceSignalContainerProcessPolicy(p.ctx, badContainerID, signal, false, processUnderTest.Command)
  3228  		if err == nil {
  3229  			t.Errorf("Signal init process unexpectedly succeeded: %v", err)
  3230  			return false
  3231  		}
  3232  
  3233  		return true
  3234  	}
  3235  
  3236  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3237  		t.Errorf("Test_Rego_SignalContainerProcessPolicy_ExecProcess_Bad_ContainerID: %v", err)
  3238  	}
  3239  }
  3240  
  3241  func Test_Rego_Plan9MountPolicy(t *testing.T) {
  3242  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  3243  
  3244  	tc, err := setupPlan9MountTest(gc)
  3245  	if err != nil {
  3246  		t.Fatalf("unable to setup test: %v", err)
  3247  	}
  3248  
  3249  	err = tc.policy.EnforcePlan9MountPolicy(gc.ctx, tc.uvmPathForShare)
  3250  	if err != nil {
  3251  		t.Fatalf("Policy enforcement unexpectedly was denied: %v", err)
  3252  	}
  3253  
  3254  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(
  3255  		gc.ctx,
  3256  		tc.sandboxID,
  3257  		tc.containerID,
  3258  		tc.argList,
  3259  		tc.envList,
  3260  		tc.workingDir,
  3261  		tc.mounts,
  3262  		false,
  3263  		tc.noNewPrivileges,
  3264  		tc.user,
  3265  		tc.groups,
  3266  		tc.umask,
  3267  		tc.capabilities,
  3268  		tc.seccomp,
  3269  	)
  3270  
  3271  	if err != nil {
  3272  		t.Fatalf("Policy enforcement unexpectedly was denied: %v", err)
  3273  	}
  3274  }
  3275  
  3276  func Test_Rego_Plan9MountPolicy_No_Matches(t *testing.T) {
  3277  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  3278  
  3279  	tc, err := setupPlan9MountTest(gc)
  3280  	if err != nil {
  3281  		t.Fatalf("unable to setup test: %v", err)
  3282  	}
  3283  
  3284  	mount := generateUVMPathForShare(testRand, tc.containerID)
  3285  	for {
  3286  		if mount != tc.uvmPathForShare {
  3287  			break
  3288  		}
  3289  		mount = generateUVMPathForShare(testRand, tc.containerID)
  3290  	}
  3291  
  3292  	err = tc.policy.EnforcePlan9MountPolicy(gc.ctx, mount)
  3293  	if err != nil {
  3294  		t.Fatalf("Policy enforcement unexpectedly was denied: %v", err)
  3295  	}
  3296  
  3297  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(
  3298  		gc.ctx,
  3299  		tc.sandboxID,
  3300  		tc.containerID,
  3301  		tc.argList,
  3302  		tc.envList,
  3303  		tc.workingDir,
  3304  		tc.mounts,
  3305  		false,
  3306  		tc.noNewPrivileges,
  3307  		tc.user,
  3308  		tc.groups,
  3309  		tc.umask,
  3310  		tc.capabilities,
  3311  		tc.seccomp,
  3312  	)
  3313  
  3314  	if err == nil {
  3315  		t.Fatal("Policy enforcement unexpectedly was allowed")
  3316  	}
  3317  }
  3318  
  3319  func Test_Rego_Plan9MountPolicy_Invalid(t *testing.T) {
  3320  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  3321  
  3322  	tc, err := setupPlan9MountTest(gc)
  3323  	if err != nil {
  3324  		t.Fatalf("unable to setup test: %v", err)
  3325  	}
  3326  
  3327  	mount := randString(testRand, maxGeneratedMountSourceLength)
  3328  	err = tc.policy.EnforcePlan9MountPolicy(gc.ctx, mount)
  3329  	if err == nil {
  3330  		t.Fatal("Policy enforcement unexpectedly was allowed", err)
  3331  	}
  3332  }
  3333  
  3334  func Test_Rego_Plan9UnmountPolicy(t *testing.T) {
  3335  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  3336  
  3337  	tc, err := setupPlan9MountTest(gc)
  3338  	if err != nil {
  3339  		t.Fatalf("unable to setup test: %v", err)
  3340  	}
  3341  
  3342  	err = tc.policy.EnforcePlan9MountPolicy(gc.ctx, tc.uvmPathForShare)
  3343  	if err != nil {
  3344  		t.Fatalf("Couldn't mount as part of setup: %v", err)
  3345  	}
  3346  
  3347  	err = tc.policy.EnforcePlan9UnmountPolicy(gc.ctx, tc.uvmPathForShare)
  3348  	if err != nil {
  3349  		t.Fatalf("Policy enforcement unexpectedly was denied: %v", err)
  3350  	}
  3351  
  3352  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(
  3353  		gc.ctx,
  3354  		tc.sandboxID,
  3355  		tc.containerID,
  3356  		tc.argList,
  3357  		tc.envList,
  3358  		tc.workingDir,
  3359  		tc.mounts,
  3360  		false,
  3361  		tc.noNewPrivileges,
  3362  		tc.user,
  3363  		tc.groups,
  3364  		tc.umask,
  3365  		tc.capabilities,
  3366  		tc.seccomp,
  3367  	)
  3368  
  3369  	if err == nil {
  3370  		t.Fatal("Policy enforcement unexpectedly was allowed")
  3371  	}
  3372  }
  3373  
  3374  func Test_Rego_Plan9UnmountPolicy_No_Matches(t *testing.T) {
  3375  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  3376  
  3377  	tc, err := setupPlan9MountTest(gc)
  3378  	if err != nil {
  3379  		t.Fatalf("unable to setup test: %v", err)
  3380  	}
  3381  
  3382  	mount := generateUVMPathForShare(testRand, tc.containerID)
  3383  	err = tc.policy.EnforcePlan9MountPolicy(gc.ctx, mount)
  3384  	if err != nil {
  3385  		t.Fatalf("Couldn't mount as part of setup: %v", err)
  3386  	}
  3387  
  3388  	badMount := randString(testRand, maxPlan9MountTargetLength)
  3389  	err = tc.policy.EnforcePlan9UnmountPolicy(gc.ctx, badMount)
  3390  	if err == nil {
  3391  		t.Fatalf("Policy enforcement unexpectedly was allowed")
  3392  	}
  3393  }
  3394  
  3395  func Test_Rego_GetPropertiesPolicy_On(t *testing.T) {
  3396  	f := func(constraints *generatedConstraints) bool {
  3397  		tc, err := setupGetPropertiesTest(constraints, true)
  3398  		if err != nil {
  3399  			t.Error(err)
  3400  			return false
  3401  		}
  3402  
  3403  		err = tc.policy.EnforceGetPropertiesPolicy(constraints.ctx)
  3404  		if err != nil {
  3405  			t.Error("Policy enforcement unexpectedly was denied")
  3406  			return false
  3407  		}
  3408  
  3409  		return true
  3410  	}
  3411  
  3412  	if err := quick.Check(f, &quick.Config{MaxCount: 50}); err != nil {
  3413  		t.Errorf("Test_Rego_GetPropertiesPolicy_On: %v", err)
  3414  	}
  3415  }
  3416  
  3417  func Test_Rego_GetPropertiesPolicy_Off(t *testing.T) {
  3418  	f := func(constraints *generatedConstraints) bool {
  3419  		tc, err := setupGetPropertiesTest(constraints, false)
  3420  		if err != nil {
  3421  			t.Error(err)
  3422  			return false
  3423  		}
  3424  
  3425  		err = tc.policy.EnforceGetPropertiesPolicy(constraints.ctx)
  3426  		if err == nil {
  3427  			t.Error("Policy enforcement unexpectedly was allowed")
  3428  			return false
  3429  		}
  3430  
  3431  		return true
  3432  	}
  3433  
  3434  	if err := quick.Check(f, &quick.Config{MaxCount: 50}); err != nil {
  3435  		t.Errorf("Test_Rego_GetPropertiesPolicy_Off: %v", err)
  3436  	}
  3437  }
  3438  
  3439  func Test_Rego_DumpStacksPolicy_On(t *testing.T) {
  3440  	f := func(constraints *generatedConstraints) bool {
  3441  		tc, err := setupDumpStacksTest(constraints, true)
  3442  		if err != nil {
  3443  			t.Error(err)
  3444  			return false
  3445  		}
  3446  
  3447  		err = tc.policy.EnforceDumpStacksPolicy(constraints.ctx)
  3448  		if err != nil {
  3449  			t.Errorf("Policy enforcement unexpectedly was denied: %v", err)
  3450  			return false
  3451  		}
  3452  
  3453  		return true
  3454  	}
  3455  
  3456  	if err := quick.Check(f, &quick.Config{MaxCount: 50}); err != nil {
  3457  		t.Errorf("Test_Rego_DumpStacksPolicy_On: %v", err)
  3458  	}
  3459  }
  3460  
  3461  func Test_Rego_DumpStacksPolicy_Off(t *testing.T) {
  3462  	f := func(constraints *generatedConstraints) bool {
  3463  		tc, err := setupDumpStacksTest(constraints, false)
  3464  		if err != nil {
  3465  			t.Error(err)
  3466  			return false
  3467  		}
  3468  
  3469  		err = tc.policy.EnforceDumpStacksPolicy(constraints.ctx)
  3470  		if err == nil {
  3471  			t.Error("Policy enforcement unexpectedly was allowed")
  3472  			return false
  3473  		}
  3474  
  3475  		return true
  3476  	}
  3477  
  3478  	if err := quick.Check(f, &quick.Config{MaxCount: 50}); err != nil {
  3479  		t.Errorf("Test_Rego_DumpStacksPolicy_Off: %v", err)
  3480  	}
  3481  }
  3482  
  3483  func Test_EnforceRuntimeLogging_Allowed(t *testing.T) {
  3484  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  3485  	gc.allowRuntimeLogging = true
  3486  
  3487  	tc, err := setupRegoPolicyOnlyTest(gc)
  3488  	if err != nil {
  3489  		t.Fatalf("unable to setup test: %v", err)
  3490  	}
  3491  
  3492  	err = tc.policy.EnforceRuntimeLoggingPolicy(gc.ctx)
  3493  	if err != nil {
  3494  		t.Fatalf("Policy enforcement unexpectedly was denied: %v", err)
  3495  	}
  3496  }
  3497  
  3498  func Test_EnforceRuntimeLogging_Not_Allowed(t *testing.T) {
  3499  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  3500  	gc.allowRuntimeLogging = false
  3501  
  3502  	tc, err := setupRegoPolicyOnlyTest(gc)
  3503  	if err != nil {
  3504  		t.Fatalf("unable to setup test: %v", err)
  3505  	}
  3506  
  3507  	err = tc.policy.EnforceRuntimeLoggingPolicy(gc.ctx)
  3508  	if err == nil {
  3509  		t.Fatalf("Policy enforcement unexpectedly was allowed")
  3510  	}
  3511  }
  3512  
  3513  func Test_Rego_LoadFragment_Container(t *testing.T) {
  3514  	f := func(p *generatedConstraints) bool {
  3515  		tc, err := setupRegoFragmentTestConfigWithIncludes(p, []string{"containers"})
  3516  		if err != nil {
  3517  			t.Error(err)
  3518  			return false
  3519  		}
  3520  
  3521  		fragment := tc.fragments[0]
  3522  		container := tc.containers[0]
  3523  
  3524  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  3525  		if err != nil {
  3526  			t.Error("unable to load fragment: %w", err)
  3527  			return false
  3528  		}
  3529  
  3530  		containerID, err := mountImageForContainer(tc.policy, container.container)
  3531  		if err != nil {
  3532  			t.Error("unable to mount image for fragment container: %w", err)
  3533  			return false
  3534  		}
  3535  
  3536  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx,
  3537  			container.sandboxID,
  3538  			containerID,
  3539  			copyStrings(container.container.Command),
  3540  			copyStrings(container.envList),
  3541  			container.container.WorkingDir,
  3542  			copyMounts(container.mounts),
  3543  			false,
  3544  			container.container.NoNewPrivileges,
  3545  			container.user,
  3546  			container.groups,
  3547  			container.container.User.Umask,
  3548  			container.capabilities,
  3549  			container.seccomp,
  3550  		)
  3551  
  3552  		if err != nil {
  3553  			t.Error("unable to create container from fragment: %w", err)
  3554  			return false
  3555  		}
  3556  
  3557  		if tc.policy.rego.IsModuleActive(rpi.ModuleID(fragment.info.issuer, fragment.info.feed)) {
  3558  			t.Error("module not removed after load")
  3559  			return false
  3560  		}
  3561  
  3562  		return true
  3563  	}
  3564  
  3565  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3566  		t.Errorf("Test_Rego_LoadFragment_Container: %v", err)
  3567  	}
  3568  }
  3569  
  3570  func Test_Rego_LoadFragment_Fragment(t *testing.T) {
  3571  	f := func(p *generatedConstraints) bool {
  3572  		tc, err := setupRegoFragmentTestConfigWithIncludes(p, []string{"fragments"})
  3573  		if err != nil {
  3574  			t.Error(err)
  3575  			return false
  3576  		}
  3577  
  3578  		fragment := tc.fragments[0]
  3579  		subFragment := tc.subFragments[0]
  3580  
  3581  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  3582  		if err != nil {
  3583  			t.Error("unable to load fragment: %w", err)
  3584  			return false
  3585  		}
  3586  
  3587  		err = tc.policy.LoadFragment(p.ctx, subFragment.info.issuer, subFragment.info.feed, subFragment.code)
  3588  		if err != nil {
  3589  			t.Error("unable to load sub-fragment from fragment: %w", err)
  3590  			return false
  3591  		}
  3592  
  3593  		container := selectContainerFromContainerList(subFragment.constraints.containers, testRand)
  3594  		_, err = mountImageForContainer(tc.policy, container)
  3595  		if err != nil {
  3596  			t.Error("unable to mount image for sub-fragment container: %w", err)
  3597  			return false
  3598  		}
  3599  
  3600  		if tc.policy.rego.IsModuleActive(rpi.ModuleID(fragment.info.issuer, fragment.info.feed)) {
  3601  			t.Error("module not removed after load")
  3602  			return false
  3603  		}
  3604  
  3605  		return true
  3606  	}
  3607  
  3608  	if err := quick.Check(f, &quick.Config{MaxCount: 15, Rand: testRand}); err != nil {
  3609  		t.Errorf("Test_Rego_LoadFragment_Fragment: %v", err)
  3610  	}
  3611  }
  3612  
  3613  func Test_Rego_LoadFragment_ExternalProcess(t *testing.T) {
  3614  	f := func(p *generatedConstraints) bool {
  3615  		tc, err := setupRegoFragmentTestConfigWithIncludes(p, []string{"external_processes"})
  3616  		if err != nil {
  3617  			t.Error(err)
  3618  			return false
  3619  		}
  3620  
  3621  		fragment := tc.fragments[0]
  3622  		process := tc.externalProcesses[0]
  3623  
  3624  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  3625  		if err != nil {
  3626  			t.Error("unable to load fragment: %w", err)
  3627  			return false
  3628  		}
  3629  
  3630  		envList := buildEnvironmentVariablesFromEnvRules(process.envRules, testRand)
  3631  		_, _, err = tc.policy.EnforceExecExternalProcessPolicy(p.ctx, process.command, envList, process.workingDir)
  3632  		if err != nil {
  3633  			t.Error("unable to execute external process from fragment: %w", err)
  3634  			return false
  3635  		}
  3636  
  3637  		if tc.policy.rego.IsModuleActive(rpi.ModuleID(fragment.info.issuer, fragment.info.feed)) {
  3638  			t.Error("module not removed after load")
  3639  			return false
  3640  		}
  3641  
  3642  		return true
  3643  	}
  3644  
  3645  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3646  		t.Errorf("Test_Rego_LoadFragment_ExternalProcess: %v", err)
  3647  	}
  3648  }
  3649  
  3650  func Test_Rego_LoadFragment_BadIssuer(t *testing.T) {
  3651  	f := func(p *generatedConstraints) bool {
  3652  		tc, err := setupSimpleRegoFragmentTestConfig(p)
  3653  		if err != nil {
  3654  			t.Error(err)
  3655  			return false
  3656  		}
  3657  
  3658  		fragment := tc.fragments[0]
  3659  		issuer := testDataGenerator.uniqueFragmentIssuer()
  3660  		err = tc.policy.LoadFragment(p.ctx, issuer, fragment.info.feed, fragment.code)
  3661  		if err == nil {
  3662  			t.Error("expected to be unable to load fragment due to bad issuer")
  3663  			return false
  3664  		}
  3665  
  3666  		if !assertDecisionJSONContains(t, err, "invalid fragment issuer") {
  3667  			t.Error("expected error string to contain 'invalid fragment issuer'")
  3668  			return false
  3669  		}
  3670  
  3671  		if tc.policy.rego.IsModuleActive(rpi.ModuleID(issuer, fragment.info.feed)) {
  3672  			t.Error("module not removed upon failure")
  3673  			return false
  3674  		}
  3675  
  3676  		return true
  3677  	}
  3678  
  3679  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3680  		t.Errorf("Test_Rego_LoadFragment_BadIssuer: %v", err)
  3681  	}
  3682  }
  3683  
  3684  func Test_Rego_LoadFragment_BadFeed(t *testing.T) {
  3685  	f := func(p *generatedConstraints) bool {
  3686  		tc, err := setupSimpleRegoFragmentTestConfig(p)
  3687  		if err != nil {
  3688  			t.Error(err)
  3689  			return false
  3690  		}
  3691  
  3692  		fragment := tc.fragments[0]
  3693  		feed := testDataGenerator.uniqueFragmentFeed()
  3694  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, feed, fragment.code)
  3695  		if err == nil {
  3696  			t.Error("expected to be unable to load fragment due to bad feed")
  3697  			return false
  3698  		}
  3699  
  3700  		if !assertDecisionJSONContains(t, err, "invalid fragment feed") {
  3701  			t.Error("expected error string to contain 'invalid fragment feed'")
  3702  			return false
  3703  		}
  3704  
  3705  		if tc.policy.rego.IsModuleActive(rpi.ModuleID(fragment.info.issuer, feed)) {
  3706  			t.Error("module not removed upon failure")
  3707  			return false
  3708  		}
  3709  
  3710  		return true
  3711  	}
  3712  
  3713  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3714  		t.Errorf("Test_Rego_LoadFragment_BadFeed: %v", err)
  3715  	}
  3716  }
  3717  
  3718  func Test_Rego_LoadFragment_InvalidSVN(t *testing.T) {
  3719  	f := func(p *generatedConstraints) bool {
  3720  		tc, err := setupRegoFragmentSVNErrorTestConfig(p)
  3721  		if err != nil {
  3722  			t.Error(err)
  3723  			return false
  3724  		}
  3725  
  3726  		fragment := tc.fragments[0]
  3727  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  3728  		if err == nil {
  3729  			t.Error("expected to be unable to load fragment due to invalid svn")
  3730  			return false
  3731  		}
  3732  
  3733  		if !assertDecisionJSONContains(t, err, "fragment svn is below the specified minimum") {
  3734  			t.Error("expected error string to contain 'fragment svn is below the specified minimum'")
  3735  			return false
  3736  		}
  3737  
  3738  		if tc.policy.rego.IsModuleActive(rpi.ModuleID(fragment.info.issuer, fragment.info.feed)) {
  3739  			t.Error("module not removed upon failure")
  3740  			return false
  3741  		}
  3742  
  3743  		return true
  3744  	}
  3745  
  3746  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3747  		t.Errorf("Test_Rego_LoadFragment_InvalidSVN: %v", err)
  3748  	}
  3749  }
  3750  
  3751  func Test_Rego_LoadFragment_Fragment_InvalidSVN(t *testing.T) {
  3752  	f := func(p *generatedConstraints) bool {
  3753  		tc, err := setupRegoSubfragmentSVNErrorTestConfig(p)
  3754  		if err != nil {
  3755  			t.Error(err)
  3756  			return false
  3757  		}
  3758  
  3759  		fragment := tc.fragments[0]
  3760  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  3761  		if err != nil {
  3762  			t.Error("unable to load fragment: %w", err)
  3763  			return false
  3764  		}
  3765  
  3766  		subFragment := tc.subFragments[0]
  3767  		err = tc.policy.LoadFragment(p.ctx, subFragment.info.issuer, subFragment.info.feed, subFragment.code)
  3768  		if err == nil {
  3769  			t.Error("expected to be unable to load subfragment due to invalid svn")
  3770  			return false
  3771  		}
  3772  
  3773  		if !assertDecisionJSONContains(t, err, "fragment svn is below the specified minimum") {
  3774  			t.Error("expected error string to contain 'fragment svn is below the specified minimum'")
  3775  			return false
  3776  		}
  3777  
  3778  		if tc.policy.rego.IsModuleActive(rpi.ModuleID(subFragment.info.issuer, fragment.info.feed)) {
  3779  			t.Error("module not removed upon failure")
  3780  			return false
  3781  		}
  3782  
  3783  		return true
  3784  	}
  3785  
  3786  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3787  		t.Errorf("Test_Rego_LoadFragment_Fragment_InvalidSVN: %v", err)
  3788  	}
  3789  }
  3790  
  3791  func Test_Rego_LoadFragment_SemverVersion(t *testing.T) {
  3792  	f := func(p *generatedConstraints) bool {
  3793  		p.fragments = generateFragments(testRand, 1)
  3794  		p.fragments[0].minimumSVN = generateSemver(testRand)
  3795  		securityPolicy := p.toPolicy()
  3796  
  3797  		defaultMounts := toOCIMounts(generateMounts(testRand))
  3798  		privilegedMounts := toOCIMounts(generateMounts(testRand))
  3799  		policy, err := newRegoPolicy(securityPolicy.marshalRego(), defaultMounts, privilegedMounts)
  3800  
  3801  		if err != nil {
  3802  			t.Fatalf("error compiling policy: %v", err)
  3803  		}
  3804  
  3805  		issuer := p.fragments[0].issuer
  3806  		feed := p.fragments[0].feed
  3807  
  3808  		fragmentConstraints := generateConstraints(testRand, 1)
  3809  		fragmentConstraints.svn = mustIncrementSVN(p.fragments[0].minimumSVN)
  3810  		code := fragmentConstraints.toFragment().marshalRego()
  3811  
  3812  		err = policy.LoadFragment(p.ctx, issuer, feed, code)
  3813  		if err != nil {
  3814  			t.Error("unable to load fragment: %w", err)
  3815  			return false
  3816  		}
  3817  
  3818  		if policy.rego.IsModuleActive(rpi.ModuleID(issuer, feed)) {
  3819  			t.Error("module not removed after load")
  3820  			return false
  3821  		}
  3822  
  3823  		return true
  3824  	}
  3825  
  3826  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3827  		t.Errorf("Test_Rego_LoadFragment_SemverVersion: %v", err)
  3828  	}
  3829  }
  3830  
  3831  func Test_Rego_LoadFragment_SVNMismatch(t *testing.T) {
  3832  	f := func(p *generatedConstraints) bool {
  3833  		tc, err := setupRegoFragmentSVNMismatchTestConfig(p)
  3834  		if err != nil {
  3835  			t.Error(err)
  3836  			return false
  3837  		}
  3838  
  3839  		fragment := tc.fragments[0]
  3840  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  3841  		if err == nil {
  3842  			t.Error("expected to be unable to load fragment due to invalid version")
  3843  			return false
  3844  		}
  3845  
  3846  		if !assertDecisionJSONContains(t, err, "fragment svn and the specified minimum are different types") {
  3847  			t.Error("expected error string to contain 'fragment svn and the specified minimum are different types'")
  3848  			return false
  3849  		}
  3850  
  3851  		if tc.policy.rego.IsModuleActive(rpi.ModuleID(fragment.info.issuer, fragment.info.feed)) {
  3852  			t.Error("module not removed upon failure")
  3853  			return false
  3854  		}
  3855  
  3856  		return true
  3857  	}
  3858  
  3859  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  3860  		t.Errorf("Test_Rego_LoadFragment_SVNMismatch: %v", err)
  3861  	}
  3862  }
  3863  
  3864  func Test_Rego_LoadFragment_SameIssuerTwoFeeds(t *testing.T) {
  3865  	f := func(p *generatedConstraints) bool {
  3866  		tc, err := setupRegoFragmentTwoFeedTestConfig(p, true, false)
  3867  		if err != nil {
  3868  			t.Error(err)
  3869  			return false
  3870  		}
  3871  
  3872  		for _, fragment := range tc.fragments {
  3873  			err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  3874  			if err != nil {
  3875  				t.Error("unable to load fragment: %w", err)
  3876  				return false
  3877  			}
  3878  		}
  3879  
  3880  		for _, container := range tc.containers {
  3881  			containerID, err := mountImageForContainer(tc.policy, container.container)
  3882  			if err != nil {
  3883  				t.Error("unable to mount image for fragment container: %w", err)
  3884  				return false
  3885  			}
  3886  
  3887  			_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx,
  3888  				container.sandboxID,
  3889  				containerID,
  3890  				copyStrings(container.container.Command),
  3891  				copyStrings(container.envList),
  3892  				container.container.WorkingDir,
  3893  				copyMounts(container.mounts),
  3894  				false,
  3895  				container.container.NoNewPrivileges,
  3896  				container.user,
  3897  				container.groups,
  3898  				container.container.User.Umask,
  3899  				container.capabilities,
  3900  				container.seccomp,
  3901  			)
  3902  
  3903  			if err != nil {
  3904  				t.Error("unable to create container from fragment: %w", err)
  3905  				return false
  3906  			}
  3907  		}
  3908  
  3909  		return true
  3910  	}
  3911  
  3912  	if err := quick.Check(f, &quick.Config{MaxCount: 15, Rand: testRand}); err != nil {
  3913  		t.Errorf("Test_Rego_LoadFragment_SameIssuerTwoFeeds: %v", err)
  3914  	}
  3915  }
  3916  
  3917  func Test_Rego_LoadFragment_TwoFeeds(t *testing.T) {
  3918  	f := func(p *generatedConstraints) bool {
  3919  		tc, err := setupRegoFragmentTwoFeedTestConfig(p, false, false)
  3920  		if err != nil {
  3921  			t.Error(err)
  3922  			return false
  3923  		}
  3924  
  3925  		for _, fragment := range tc.fragments {
  3926  			err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  3927  			if err != nil {
  3928  				t.Error("unable to load fragment: %w", err)
  3929  				return false
  3930  			}
  3931  		}
  3932  
  3933  		for _, container := range tc.containers {
  3934  			containerID, err := mountImageForContainer(tc.policy, container.container)
  3935  			if err != nil {
  3936  				t.Error("unable to mount image for fragment container: %w", err)
  3937  				return false
  3938  			}
  3939  
  3940  			_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx,
  3941  				container.sandboxID,
  3942  				containerID,
  3943  				copyStrings(container.container.Command),
  3944  				copyStrings(container.envList),
  3945  				container.container.WorkingDir,
  3946  				copyMounts(container.mounts),
  3947  				false,
  3948  				container.container.NoNewPrivileges,
  3949  				container.user,
  3950  				container.groups,
  3951  				container.container.User.Umask,
  3952  				container.capabilities,
  3953  				container.seccomp,
  3954  			)
  3955  
  3956  			if err != nil {
  3957  				t.Error("unable to create container from fragment: %w", err)
  3958  				return false
  3959  			}
  3960  		}
  3961  
  3962  		return true
  3963  	}
  3964  
  3965  	if err := quick.Check(f, &quick.Config{MaxCount: 15, Rand: testRand}); err != nil {
  3966  		t.Errorf("Test_Rego_LoadFragment_TwoFeeds: %v", err)
  3967  	}
  3968  }
  3969  
  3970  func Test_Rego_LoadFragment_SameFeedTwice(t *testing.T) {
  3971  	f := func(p *generatedConstraints) bool {
  3972  		tc, err := setupRegoFragmentTwoFeedTestConfig(p, true, true)
  3973  		if err != nil {
  3974  			t.Error(err)
  3975  			return false
  3976  		}
  3977  
  3978  		err = tc.policy.LoadFragment(p.ctx, tc.fragments[0].info.issuer, tc.fragments[0].info.feed, tc.fragments[0].code)
  3979  		if err != nil {
  3980  			t.Error("unable to load fragment the first time: %w", err)
  3981  			return false
  3982  		}
  3983  
  3984  		err = tc.policy.LoadFragment(p.ctx, tc.fragments[1].info.issuer, tc.fragments[1].info.feed, tc.fragments[1].code)
  3985  		if err != nil {
  3986  			t.Error("expected to be able to load the same issuer/feed twice: %w", err)
  3987  			return false
  3988  		}
  3989  
  3990  		for _, container := range tc.containers {
  3991  			containerID, err := mountImageForContainer(tc.policy, container.container)
  3992  			if err != nil {
  3993  				t.Error("unable to mount image for fragment container: %w", err)
  3994  				return false
  3995  			}
  3996  
  3997  			_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx,
  3998  				container.sandboxID,
  3999  				containerID,
  4000  				copyStrings(container.container.Command),
  4001  				copyStrings(container.envList),
  4002  				container.container.WorkingDir,
  4003  				copyMounts(container.mounts),
  4004  				false,
  4005  				container.container.NoNewPrivileges,
  4006  				container.user,
  4007  				container.groups,
  4008  				container.container.User.Umask,
  4009  				container.capabilities,
  4010  				container.seccomp,
  4011  			)
  4012  
  4013  			if err != nil {
  4014  				t.Error("unable to create container from fragment: %w", err)
  4015  				return false
  4016  			}
  4017  		}
  4018  
  4019  		return true
  4020  	}
  4021  
  4022  	if err := quick.Check(f, &quick.Config{MaxCount: 15, Rand: testRand}); err != nil {
  4023  		t.Errorf("Test_Rego_LoadFragment_SameFragmentTwice: %v", err)
  4024  	}
  4025  }
  4026  
  4027  func Test_Rego_LoadFragment_ExcludedContainer(t *testing.T) {
  4028  	f := func(p *generatedConstraints) bool {
  4029  		tc, err := setupRegoFragmentTestConfigWithExcludes(p, []string{"containers"})
  4030  		if err != nil {
  4031  			t.Error(err)
  4032  			return false
  4033  		}
  4034  
  4035  		fragment := tc.fragments[0]
  4036  		container := tc.containers[0]
  4037  
  4038  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  4039  		if err != nil {
  4040  			t.Error("unable to load fragment: %w", err)
  4041  			return false
  4042  		}
  4043  
  4044  		_, err = mountImageForContainer(tc.policy, container.container)
  4045  		if err == nil {
  4046  			t.Error("expected to be unable to mount image for fragment container")
  4047  			return false
  4048  		}
  4049  
  4050  		return true
  4051  	}
  4052  
  4053  	if err := quick.Check(f, &quick.Config{MaxCount: 15, Rand: testRand}); err != nil {
  4054  		t.Errorf("Test_Rego_LoadFragment_ExcludedContainer: %v", err)
  4055  	}
  4056  }
  4057  
  4058  func Test_Rego_LoadFragment_ExcludedFragment(t *testing.T) {
  4059  	f := func(p *generatedConstraints) bool {
  4060  		tc, err := setupRegoFragmentTestConfigWithExcludes(p, []string{"fragments"})
  4061  		if err != nil {
  4062  			t.Error(err)
  4063  			return false
  4064  		}
  4065  
  4066  		fragment := tc.fragments[0]
  4067  		subFragment := tc.subFragments[0]
  4068  
  4069  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  4070  		if err != nil {
  4071  			t.Error("unable to load fragment: %w", err)
  4072  			return false
  4073  		}
  4074  
  4075  		err = tc.policy.LoadFragment(p.ctx, subFragment.info.issuer, subFragment.info.feed, subFragment.code)
  4076  		if err == nil {
  4077  			t.Error("expected to be unable to load a sub-fragment from a fragment")
  4078  			return false
  4079  		}
  4080  
  4081  		return true
  4082  	}
  4083  
  4084  	if err := quick.Check(f, &quick.Config{MaxCount: 15, Rand: testRand}); err != nil {
  4085  		t.Errorf("Test_Rego_LoadFragment_ExcludedFragment: %v", err)
  4086  	}
  4087  }
  4088  
  4089  func Test_Rego_LoadFragment_ExcludedExternalProcess(t *testing.T) {
  4090  	f := func(p *generatedConstraints) bool {
  4091  		tc, err := setupRegoFragmentTestConfigWithExcludes(p, []string{"external_processes"})
  4092  		if err != nil {
  4093  			t.Error(err)
  4094  			return false
  4095  		}
  4096  
  4097  		fragment := tc.fragments[0]
  4098  		process := tc.externalProcesses[0]
  4099  
  4100  		err = tc.policy.LoadFragment(p.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  4101  		if err != nil {
  4102  			t.Error("unable to load fragment: %w", err)
  4103  			return false
  4104  		}
  4105  
  4106  		envList := buildEnvironmentVariablesFromEnvRules(process.envRules, testRand)
  4107  
  4108  		_, _, err = tc.policy.EnforceExecExternalProcessPolicy(p.ctx, process.command, envList, process.workingDir)
  4109  		if err == nil {
  4110  			t.Error("expected to be unable to execute external process from a fragment")
  4111  			return false
  4112  		}
  4113  
  4114  		return true
  4115  	}
  4116  
  4117  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  4118  		t.Errorf("Test_Rego_LoadFragment_ExcludedExternalProcess: %v", err)
  4119  	}
  4120  }
  4121  
  4122  func Test_Rego_LoadFragment_FragmentNamespace(t *testing.T) {
  4123  	ctx := context.Background()
  4124  	deviceHash := generateRootHash(testRand)
  4125  	key := randVariableString(testRand, 32)
  4126  	value := randVariableString(testRand, 32)
  4127  	fragmentCode := fmt.Sprintf(`package fragment
  4128  
  4129  svn := 1
  4130  framework_version := "%s"
  4131  
  4132  layer := "%s"
  4133  
  4134  mount_device := {"allowed": allowed, "metadata": [addCustom]} {
  4135  	allowed := input.deviceHash == layer
  4136  	addCustom := {
  4137  		"name": "custom",
  4138          "action": "add",
  4139          "key": "%s",
  4140          "value": "%s"
  4141  	}
  4142  }`, frameworkVersion, deviceHash, key, value)
  4143  
  4144  	issuer := testDataGenerator.uniqueFragmentIssuer()
  4145  	feed := testDataGenerator.uniqueFragmentFeed()
  4146  	policyCode := fmt.Sprintf(`package policy
  4147  
  4148  api_version := "%s"
  4149  framework_version := "%s"
  4150  
  4151  default load_fragment := {"allowed": false}
  4152  
  4153  load_fragment := {"allowed": true, "add_module": true} {
  4154  	input.issuer == "%s"
  4155  	input.feed == "%s"
  4156  	data[input.namespace].svn >= 1
  4157  }
  4158  
  4159  mount_device := data.fragment.mount_device
  4160  	`, apiVersion, frameworkVersion, issuer, feed)
  4161  
  4162  	policy, err := newRegoPolicy(policyCode, []oci.Mount{}, []oci.Mount{})
  4163  	if err != nil {
  4164  		t.Fatalf("unable to create Rego policy: %v", err)
  4165  	}
  4166  
  4167  	err = policy.LoadFragment(ctx, issuer, feed, fragmentCode)
  4168  	if err != nil {
  4169  		t.Fatalf("unable to load fragment: %v", err)
  4170  	}
  4171  
  4172  	err = policy.EnforceDeviceMountPolicy(ctx, "/mnt/foo", deviceHash)
  4173  	if err != nil {
  4174  		t.Fatalf("unable to mount device: %v", err)
  4175  	}
  4176  
  4177  	if test, err := policy.rego.GetMetadata("custom", key); err == nil {
  4178  		if test != value {
  4179  			t.Error("incorrect metadata value stored by fragment")
  4180  		}
  4181  	} else {
  4182  		t.Errorf("unable to located metadata key stored by fragment: %v", err)
  4183  	}
  4184  }
  4185  
  4186  func Test_Rego_Scratch_Mount_Policy(t *testing.T) {
  4187  	for _, tc := range []struct {
  4188  		unencryptedAllowed bool
  4189  		encrypted          bool
  4190  		failureExpected    bool
  4191  	}{
  4192  		{
  4193  			unencryptedAllowed: false,
  4194  			encrypted:          false,
  4195  			failureExpected:    true,
  4196  		},
  4197  		{
  4198  			unencryptedAllowed: false,
  4199  			encrypted:          true,
  4200  			failureExpected:    false,
  4201  		},
  4202  		{
  4203  			unencryptedAllowed: true,
  4204  			encrypted:          false,
  4205  			failureExpected:    false,
  4206  		},
  4207  		{
  4208  			unencryptedAllowed: true,
  4209  			encrypted:          true,
  4210  			failureExpected:    false,
  4211  		},
  4212  	} {
  4213  		t.Run(fmt.Sprintf("UnencryptedAllowed_%t_And_Encrypted_%t", tc.unencryptedAllowed, tc.encrypted), func(t *testing.T) {
  4214  			gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  4215  			smConfig, err := setupRegoScratchMountTest(gc, tc.unencryptedAllowed)
  4216  			if err != nil {
  4217  				t.Fatalf("unable to setup test: %s", err)
  4218  			}
  4219  
  4220  			scratchPath := generateMountTarget(testRand)
  4221  			err = smConfig.policy.EnforceScratchMountPolicy(gc.ctx, scratchPath, tc.encrypted)
  4222  			if tc.failureExpected {
  4223  				if err == nil {
  4224  					t.Fatal("policy enforcement should've been denied")
  4225  				}
  4226  			} else {
  4227  				if err != nil {
  4228  					t.Fatalf("policy enforcement unexpectedly was denied: %s", err)
  4229  				}
  4230  			}
  4231  		})
  4232  	}
  4233  }
  4234  
  4235  // We only test cases where scratch mount should succeed, so that we can test
  4236  // the scratch unmount policy. The negative cases for scratch mount are covered
  4237  // in Test_Rego_Scratch_Mount_Policy test.
  4238  func Test_Rego_Scratch_Unmount_Policy(t *testing.T) {
  4239  	for _, tc := range []struct {
  4240  		unencryptedAllowed bool
  4241  		encrypted          bool
  4242  		failureExpected    bool
  4243  	}{
  4244  		{
  4245  			unencryptedAllowed: true,
  4246  			encrypted:          false,
  4247  			failureExpected:    false,
  4248  		},
  4249  		{
  4250  			unencryptedAllowed: true,
  4251  			encrypted:          true,
  4252  			failureExpected:    false,
  4253  		},
  4254  		{
  4255  			unencryptedAllowed: false,
  4256  			encrypted:          true,
  4257  			failureExpected:    false,
  4258  		},
  4259  	} {
  4260  		t.Run(fmt.Sprintf("UnencryptedAllowed_%t_And_Encrypted_%t", tc.unencryptedAllowed, tc.encrypted), func(t *testing.T) {
  4261  			gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  4262  			smConfig, err := setupRegoScratchMountTest(gc, tc.unencryptedAllowed)
  4263  			if err != nil {
  4264  				t.Fatalf("unable to setup test: %s", err)
  4265  			}
  4266  
  4267  			scratchPath := generateMountTarget(testRand)
  4268  			err = smConfig.policy.EnforceScratchMountPolicy(gc.ctx, scratchPath, tc.encrypted)
  4269  			if err != nil {
  4270  				t.Fatalf("scratch_mount policy enforcement unexpectedly was denied: %s", err)
  4271  			}
  4272  
  4273  			err = smConfig.policy.EnforceScratchUnmountPolicy(gc.ctx, scratchPath)
  4274  			if err != nil {
  4275  				t.Fatalf("scratch_unmount policy enforcement unexpectedly was denied: %s", err)
  4276  			}
  4277  		})
  4278  	}
  4279  }
  4280  
  4281  func Test_Rego_StdioAccess_Allowed(t *testing.T) {
  4282  	gc := generateConstraints(testRand, 1)
  4283  	gc.containers[0].AllowStdioAccess = true
  4284  	gc.externalProcesses = generateExternalProcesses(testRand)
  4285  	gc.externalProcesses[0].allowStdioAccess = true
  4286  	tc, err := setupRegoCreateContainerTest(gc, gc.containers[0], false)
  4287  	if err != nil {
  4288  		t.Fatalf("error setting up test: %v", err)
  4289  	}
  4290  
  4291  	_, _, allow_stdio_access, err := tc.policy.EnforceCreateContainerPolicy(
  4292  		gc.ctx,
  4293  		tc.sandboxID,
  4294  		tc.containerID,
  4295  		tc.argList,
  4296  		tc.envList,
  4297  		tc.workingDir,
  4298  		tc.mounts,
  4299  		false,
  4300  		tc.noNewPrivileges,
  4301  		tc.user,
  4302  		tc.groups,
  4303  		tc.umask,
  4304  		tc.capabilities,
  4305  		tc.seccomp,
  4306  	)
  4307  
  4308  	if err != nil {
  4309  		t.Errorf("create_container not allowed: %v", err)
  4310  	}
  4311  
  4312  	if !allow_stdio_access {
  4313  		t.Errorf("expected allow_stdio_access to be true")
  4314  	}
  4315  
  4316  	// stdio access is inherited from the container and should be the same
  4317  	_, _, allow_stdio_access, err = tc.policy.EnforceExecInContainerPolicy(
  4318  		gc.ctx,
  4319  		tc.containerID,
  4320  		gc.containers[0].ExecProcesses[0].Command,
  4321  		tc.envList,
  4322  		tc.workingDir,
  4323  		tc.noNewPrivileges,
  4324  		tc.user,
  4325  		tc.groups,
  4326  		tc.umask,
  4327  		tc.capabilities,
  4328  	)
  4329  
  4330  	if err != nil {
  4331  		t.Errorf("exec_in_container not allowed: %v", err)
  4332  	}
  4333  
  4334  	if !allow_stdio_access {
  4335  		t.Errorf("expected allow_stdio_access to be true")
  4336  	}
  4337  
  4338  	envList := buildEnvironmentVariablesFromEnvRules(gc.externalProcesses[0].envRules, testRand)
  4339  	_, allow_stdio_access, err = tc.policy.EnforceExecExternalProcessPolicy(
  4340  		gc.ctx,
  4341  		gc.externalProcesses[0].command,
  4342  		envList,
  4343  		gc.externalProcesses[0].workingDir,
  4344  	)
  4345  
  4346  	if err != nil {
  4347  		t.Errorf("exec_external not allowed: %v", err)
  4348  	}
  4349  
  4350  	if !allow_stdio_access {
  4351  		t.Errorf("expected allow_stdio_access to be true")
  4352  	}
  4353  }
  4354  
  4355  func Test_Rego_EnforeCreateContainerPolicy_StdioAccess_NotAllowed(t *testing.T) {
  4356  	gc := generateConstraints(testRand, 1)
  4357  	gc.containers[0].AllowStdioAccess = false
  4358  	tc, err := setupRegoCreateContainerTest(gc, gc.containers[0], false)
  4359  	if err != nil {
  4360  		t.Fatalf("error setting up test: %v", err)
  4361  	}
  4362  
  4363  	_, _, allow_stdio_access, err := tc.policy.EnforceCreateContainerPolicy(
  4364  		tc.ctx,
  4365  		tc.sandboxID,
  4366  		tc.containerID,
  4367  		tc.argList,
  4368  		tc.envList,
  4369  		tc.workingDir,
  4370  		tc.mounts,
  4371  		false,
  4372  		tc.noNewPrivileges,
  4373  		tc.user,
  4374  		tc.groups,
  4375  		tc.umask,
  4376  		tc.capabilities,
  4377  		tc.seccomp,
  4378  	)
  4379  
  4380  	if err != nil {
  4381  		t.Errorf("create_container not allowed: %v", err)
  4382  	}
  4383  
  4384  	if allow_stdio_access {
  4385  		t.Errorf("expected allow_stdio_access to be false")
  4386  	}
  4387  }
  4388  
  4389  func Test_Rego_Container_StdioAccess_NotDecidable(t *testing.T) {
  4390  	gc := generateConstraints(testRand, 1)
  4391  	container0 := gc.containers[0]
  4392  	container0.AllowStdioAccess = true
  4393  	container1, err := container0.clone()
  4394  	if err != nil {
  4395  		t.Fatalf("unable to clone container: %v", err)
  4396  	}
  4397  
  4398  	container1.AllowStdioAccess = false
  4399  	gc.containers = append(gc.containers, container1)
  4400  
  4401  	container0.ExecProcesses = append(container0.ExecProcesses, container0.ExecProcesses[0].clone())
  4402  
  4403  	gc.externalProcesses = generateExternalProcesses(testRand)
  4404  	gc.externalProcesses = append(gc.externalProcesses, gc.externalProcesses[0].clone())
  4405  	gc.externalProcesses[0].allowStdioAccess = true
  4406  
  4407  	tc, err := setupRegoCreateContainerTest(gc, gc.containers[0], false)
  4408  	if err != nil {
  4409  		t.Fatalf("error setting up test: %v", err)
  4410  	}
  4411  
  4412  	_, _, allow_stdio_access, err := tc.policy.EnforceCreateContainerPolicy(
  4413  		tc.ctx,
  4414  		tc.sandboxID,
  4415  		tc.containerID,
  4416  		tc.argList,
  4417  		tc.envList,
  4418  		tc.workingDir,
  4419  		tc.mounts,
  4420  		false,
  4421  		tc.noNewPrivileges,
  4422  		tc.user,
  4423  		tc.groups,
  4424  		tc.umask,
  4425  		tc.capabilities,
  4426  		tc.seccomp,
  4427  	)
  4428  
  4429  	if err == nil {
  4430  		t.Errorf("expected create_container to not be allowed")
  4431  	}
  4432  
  4433  	if allow_stdio_access {
  4434  		t.Errorf("expected allow_stdio_access to be false")
  4435  	}
  4436  }
  4437  
  4438  func Test_Rego_ExecExternal_StdioAccess_NotAllowed(t *testing.T) {
  4439  	gc := generateConstraints(testRand, 1)
  4440  	gc.externalProcesses = generateExternalProcesses(testRand)
  4441  	gc.externalProcesses = append(gc.externalProcesses, gc.externalProcesses[0].clone())
  4442  	gc.externalProcesses[0].allowStdioAccess = !gc.externalProcesses[0].allowStdioAccess
  4443  
  4444  	policy, err := newRegoPolicy(gc.toPolicy().marshalRego(), []oci.Mount{}, []oci.Mount{})
  4445  	if err != nil {
  4446  		t.Fatalf("error marshaling policy: %v", err)
  4447  	}
  4448  
  4449  	envList := buildEnvironmentVariablesFromEnvRules(gc.externalProcesses[0].envRules, testRand)
  4450  	_, allow_stdio_access, err := policy.EnforceExecExternalProcessPolicy(
  4451  		gc.ctx,
  4452  		gc.externalProcesses[0].command,
  4453  		envList,
  4454  		gc.externalProcesses[0].workingDir,
  4455  	)
  4456  
  4457  	if err == nil {
  4458  		t.Errorf("expected exec_external to not be allowed")
  4459  	}
  4460  
  4461  	if allow_stdio_access {
  4462  		t.Errorf("expected allow_stdio_access to be false")
  4463  	}
  4464  }
  4465  
  4466  func Test_Rego_EnforceCreateContainerPolicy_AllowElevatedAllowsPrivilegedContainer(t *testing.T) {
  4467  	gc := generateConstraints(testRand, 1)
  4468  	gc.containers[0].AllowElevated = true
  4469  	tc, err := setupRegoCreateContainerTest(gc, gc.containers[0], false)
  4470  	if err != nil {
  4471  		t.Fatalf("error setting up test: %v", err)
  4472  	}
  4473  
  4474  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(
  4475  		tc.ctx,
  4476  		tc.sandboxID,
  4477  		tc.containerID,
  4478  		tc.argList,
  4479  		tc.envList,
  4480  		tc.workingDir,
  4481  		tc.mounts,
  4482  		false,
  4483  		tc.noNewPrivileges,
  4484  		tc.user,
  4485  		tc.groups,
  4486  		tc.umask,
  4487  		tc.capabilities,
  4488  		tc.seccomp,
  4489  	)
  4490  
  4491  	if err != nil {
  4492  		t.Fatalf("expected privilege escalation to be allowed: %s", err)
  4493  	}
  4494  }
  4495  
  4496  func Test_Rego_EnforceCreateContainerPolicy_AllowElevatedAllowsUnprivilegedContainer(t *testing.T) {
  4497  	gc := generateConstraints(testRand, 1)
  4498  	gc.containers[0].AllowElevated = true
  4499  	tc, err := setupRegoCreateContainerTest(gc, gc.containers[0], false)
  4500  	if err != nil {
  4501  		t.Fatalf("error setting up test: %v", err)
  4502  	}
  4503  
  4504  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(
  4505  		tc.ctx,
  4506  		tc.sandboxID,
  4507  		tc.containerID,
  4508  		tc.argList,
  4509  		tc.envList,
  4510  		tc.workingDir,
  4511  		tc.mounts,
  4512  		false,
  4513  		tc.noNewPrivileges,
  4514  		tc.user,
  4515  		tc.groups,
  4516  		tc.umask,
  4517  		tc.capabilities,
  4518  		tc.seccomp,
  4519  	)
  4520  
  4521  	if err != nil {
  4522  		t.Fatalf("expected lack of escalation to be fine: %s", err)
  4523  	}
  4524  }
  4525  
  4526  func Test_Rego_EnforceCreateContainerPolicy_NoAllowElevatedDenysPrivilegedContainer(t *testing.T) {
  4527  	gc := generateConstraints(testRand, 1)
  4528  	gc.containers[0].AllowElevated = false
  4529  	tc, err := setupRegoCreateContainerTest(gc, gc.containers[0], false)
  4530  	if err != nil {
  4531  		t.Fatalf("error setting up test: %v", err)
  4532  	}
  4533  
  4534  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(
  4535  		tc.ctx,
  4536  		tc.sandboxID,
  4537  		tc.containerID,
  4538  		tc.argList,
  4539  		tc.envList,
  4540  		tc.workingDir,
  4541  		tc.mounts,
  4542  		true,
  4543  		tc.noNewPrivileges,
  4544  		tc.user,
  4545  		tc.groups,
  4546  		tc.umask,
  4547  		tc.capabilities,
  4548  		tc.seccomp,
  4549  	)
  4550  
  4551  	if err == nil {
  4552  		t.Fatal("expected escalation to be denied")
  4553  	}
  4554  }
  4555  
  4556  func Test_Rego_EnforceCreateContainerPolicy_NoAllowElevatedAllowsUnprivilegedContainer(t *testing.T) {
  4557  	gc := generateConstraints(testRand, 1)
  4558  	gc.containers[0].AllowElevated = false
  4559  	tc, err := setupRegoCreateContainerTest(gc, gc.containers[0], false)
  4560  	if err != nil {
  4561  		t.Fatalf("error setting up test: %v", err)
  4562  	}
  4563  
  4564  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(
  4565  		tc.ctx,
  4566  		tc.sandboxID,
  4567  		tc.containerID,
  4568  		tc.argList,
  4569  		tc.envList,
  4570  		tc.workingDir,
  4571  		tc.mounts,
  4572  		false,
  4573  		tc.noNewPrivileges,
  4574  		tc.user,
  4575  		tc.groups,
  4576  		tc.umask,
  4577  		tc.capabilities,
  4578  		tc.seccomp,
  4579  	)
  4580  
  4581  	if err != nil {
  4582  		t.Fatalf("expected lack of escalation to be fine: %s", err)
  4583  	}
  4584  }
  4585  
  4586  func Test_Rego_CreateContainer_NoNewPrivileges_Default(t *testing.T) {
  4587  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  4588  	tc, err := setupFrameworkVersionSimpleTest(gc, "0.1.0", frameworkVersion)
  4589  	if err != nil {
  4590  		t.Fatalf("error setting up test: %v", err)
  4591  	}
  4592  
  4593  	input := map[string]interface{}{}
  4594  	result, err := tc.policy.rego.RawQuery("data.framework.candidate_containers", input)
  4595  
  4596  	if err != nil {
  4597  		t.Fatalf("unable to query containers: %v", err)
  4598  	}
  4599  
  4600  	containers, ok := result[0].Expressions[0].Value.([]interface{})
  4601  	if !ok {
  4602  		t.Fatal("unable to extract containers from result")
  4603  	}
  4604  
  4605  	if len(containers) != len(gc.containers) {
  4606  		t.Error("incorrect number of candidate containers.")
  4607  	}
  4608  
  4609  	for _, container := range containers {
  4610  		object := container.(map[string]interface{})
  4611  		err := assertKeyValue(object, "no_new_privileges", false)
  4612  		if err != nil {
  4613  			t.Error(err)
  4614  		}
  4615  	}
  4616  }
  4617  
  4618  func Test_Rego_CreateContainer_User_Default(t *testing.T) {
  4619  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  4620  	tc, err := setupFrameworkVersionSimpleTest(gc, "0.1.0", frameworkVersion)
  4621  	if err != nil {
  4622  		t.Fatalf("error setting up test: %v", err)
  4623  	}
  4624  
  4625  	input := map[string]interface{}{}
  4626  	result, err := tc.policy.rego.RawQuery("data.framework.candidate_containers", input)
  4627  
  4628  	if err != nil {
  4629  		t.Fatalf("unable to query containers: %v", err)
  4630  	}
  4631  
  4632  	containers, ok := result[0].Expressions[0].Value.([]interface{})
  4633  	if !ok {
  4634  		t.Fatal("unable to extract containers from result")
  4635  	}
  4636  
  4637  	if len(containers) != len(gc.containers) {
  4638  		t.Error("incorrect number of candidate containers.")
  4639  	}
  4640  
  4641  	for _, container := range containers {
  4642  		object := container.(map[string]interface{})
  4643  		user, ok := object["user"].(map[string]interface{})
  4644  		if !ok {
  4645  			t.Error("unable to extract user from container")
  4646  			continue
  4647  		}
  4648  
  4649  		err := assertKeyValue(user, "umask", "0022")
  4650  		if err != nil {
  4651  			t.Error(err)
  4652  		}
  4653  
  4654  		if user_idname, ok := user["user_idname"].(map[string]interface{}); ok {
  4655  			err = assertKeyValue(user_idname, "strategy", "any")
  4656  			if err != nil {
  4657  				t.Error(err)
  4658  			}
  4659  		} else {
  4660  			t.Error("unable to extract user_idname from user")
  4661  		}
  4662  
  4663  		if group_idnames, ok := user["group_idnames"].([]interface{}); ok {
  4664  			if len(group_idnames) != 1 {
  4665  				t.Error("incorrect number of group_idnames")
  4666  			} else {
  4667  				group_idname := group_idnames[0].(map[string]interface{})
  4668  				err = assertKeyValue(group_idname, "strategy", "any")
  4669  				if err != nil {
  4670  					t.Error(err)
  4671  				}
  4672  			}
  4673  		}
  4674  	}
  4675  }
  4676  
  4677  func Test_Rego_CreateContainer_Capabilities_Default(t *testing.T) {
  4678  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  4679  	tc, err := setupFrameworkVersionSimpleTest(gc, "0.1.0", frameworkVersion)
  4680  	if err != nil {
  4681  		t.Fatalf("error setting up test: %v", err)
  4682  	}
  4683  
  4684  	input := map[string]interface{}{
  4685  		"privileged": false,
  4686  	}
  4687  	result, err := tc.policy.rego.RawQuery("data.framework.candidate_containers", input)
  4688  
  4689  	if err != nil {
  4690  		t.Fatalf("unable to query containers: %v", err)
  4691  	}
  4692  
  4693  	containers, ok := result[0].Expressions[0].Value.([]interface{})
  4694  	if !ok {
  4695  		t.Fatal("unable to extract containers from result")
  4696  	}
  4697  
  4698  	if len(containers) != len(gc.containers) {
  4699  		t.Error("incorrect number of candidate containers.")
  4700  	}
  4701  
  4702  	for _, container := range containers {
  4703  		object := container.(map[string]interface{})
  4704  		capabilities, ok := object["capabilities"]
  4705  		if !ok {
  4706  			t.Error("unable to extract capabilities from container")
  4707  			continue
  4708  		}
  4709  
  4710  		if capabilities != nil {
  4711  			t.Error("capabilities should be nil by default")
  4712  		}
  4713  	}
  4714  }
  4715  
  4716  func Test_Rego_CreateContainer_AllowCapabilityDropping_Default(t *testing.T) {
  4717  	gc := generateConstraints(testRand, 1)
  4718  	tc, err := setupFrameworkVersionSimpleTest(gc, "0.1.0", frameworkVersion)
  4719  	if err != nil {
  4720  		t.Fatalf("error setting up test: %v", err)
  4721  	}
  4722  
  4723  	input := map[string]interface{}{}
  4724  	result, err := tc.policy.rego.RawQuery("data.framework.allow_capability_dropping", input)
  4725  
  4726  	if err != nil {
  4727  		t.Fatalf("unable to query allow_capability_dropping: %v", err)
  4728  	}
  4729  
  4730  	actualValue, ok := result[0].Expressions[0].Value.(bool)
  4731  	if !ok {
  4732  		t.Fatal("unable to extract allow_capability_dropping from result")
  4733  	}
  4734  
  4735  	if actualValue != false {
  4736  		t.Error("unexpected allow_capability_dropping value")
  4737  	}
  4738  }
  4739  
  4740  func Test_Rego_CreateContainer_Seccomp_Default(t *testing.T) {
  4741  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  4742  	tc, err := setupFrameworkVersionSimpleTest(gc, "0.1.0", frameworkVersion)
  4743  	if err != nil {
  4744  		t.Fatalf("error setting up test: %v", err)
  4745  	}
  4746  
  4747  	input := map[string]interface{}{}
  4748  	result, err := tc.policy.rego.RawQuery("data.framework.candidate_containers", input)
  4749  
  4750  	if err != nil {
  4751  		t.Fatalf("unable to query containers: %v", err)
  4752  	}
  4753  
  4754  	containers, ok := result[0].Expressions[0].Value.([]interface{})
  4755  	if !ok {
  4756  		t.Fatal("unable to extract containers from result")
  4757  	}
  4758  
  4759  	if len(containers) != len(gc.containers) {
  4760  		t.Error("incorrect number of candidate containers.")
  4761  	}
  4762  
  4763  	for _, container := range containers {
  4764  		object := container.(map[string]interface{})
  4765  		err := assertKeyValue(object, "seccomp_profile_sha256", "")
  4766  		if err != nil {
  4767  			t.Error(err)
  4768  		}
  4769  	}
  4770  }
  4771  
  4772  func Test_FrameworkVersion_Missing(t *testing.T) {
  4773  	gc := generateConstraints(testRand, 1)
  4774  	tc, err := setupFrameworkVersionSimpleTest(gc, "", frameworkVersion)
  4775  	if err != nil {
  4776  		t.Fatalf("unable to setup test: %v", err)
  4777  	}
  4778  
  4779  	containerID := testDataGenerator.uniqueContainerID()
  4780  	c := selectContainerFromContainerList(gc.containers, testRand)
  4781  
  4782  	layerPaths, err := testDataGenerator.createValidOverlayForContainer(tc.policy, c)
  4783  
  4784  	err = tc.policy.EnforceOverlayMountPolicy(gc.ctx, containerID, layerPaths, testDataGenerator.uniqueMountTarget())
  4785  	if err == nil {
  4786  		t.Error("unexpected success. Missing framework_version should trigger an error.")
  4787  	}
  4788  
  4789  	assertDecisionJSONContains(t, err, fmt.Sprintf("framework_version is missing. Current version: %s", frameworkVersion))
  4790  }
  4791  
  4792  func Test_Fragment_FrameworkVersion_Missing(t *testing.T) {
  4793  	gc := generateConstraints(testRand, 1)
  4794  	tc, err := setupFrameworkVersionTest(gc, frameworkVersion, frameworkVersion, 1, "", []string{})
  4795  	if err != nil {
  4796  		t.Fatalf("unable to setup test: %v", err)
  4797  	}
  4798  
  4799  	fragment := tc.fragments[0]
  4800  	err = tc.policy.LoadFragment(gc.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  4801  	if err == nil {
  4802  		t.Error("unexpected success. Missing framework_version should trigger an error.")
  4803  	}
  4804  
  4805  	assertDecisionJSONContains(t, err, fmt.Sprintf("fragment framework_version is missing. Current version: %s", frameworkVersion))
  4806  }
  4807  
  4808  func Test_FrameworkVersion_In_Future(t *testing.T) {
  4809  	gc := generateConstraints(testRand, 1)
  4810  	tc, err := setupFrameworkVersionSimpleTest(gc, "100.0.0", frameworkVersion)
  4811  	if err != nil {
  4812  		t.Fatalf("unable to setup test: %v", err)
  4813  	}
  4814  
  4815  	containerID := testDataGenerator.uniqueContainerID()
  4816  	c := selectContainerFromContainerList(gc.containers, testRand)
  4817  
  4818  	layerPaths, err := testDataGenerator.createValidOverlayForContainer(tc.policy, c)
  4819  
  4820  	err = tc.policy.EnforceOverlayMountPolicy(gc.ctx, containerID, layerPaths, testDataGenerator.uniqueMountTarget())
  4821  	if err == nil {
  4822  		t.Error("unexpected success. Future framework_version should trigger an error.")
  4823  	}
  4824  
  4825  	assertDecisionJSONContains(t, err, fmt.Sprintf("framework_version is ahead of the current version: 100.0.0 is greater than %s", frameworkVersion))
  4826  }
  4827  
  4828  func Test_Fragment_FrameworkVersion_In_Future(t *testing.T) {
  4829  	gc := generateConstraints(testRand, 1)
  4830  	tc, err := setupFrameworkVersionTest(gc, frameworkVersion, frameworkVersion, 1, "100.0.0", []string{})
  4831  	if err != nil {
  4832  		t.Fatalf("unable to setup test: %v", err)
  4833  	}
  4834  
  4835  	fragment := tc.fragments[0]
  4836  	err = tc.policy.LoadFragment(gc.ctx, fragment.info.issuer, fragment.info.feed, fragment.code)
  4837  	if err == nil {
  4838  		t.Error("unexpected success. Future framework_version should trigger an error.")
  4839  	}
  4840  
  4841  	assertDecisionJSONContains(t, err, fmt.Sprintf("fragment framework_version is ahead of the current version: 100.0.0 is greater than %s", frameworkVersion))
  4842  }
  4843  
  4844  func Test_Rego_MissingEnvList(t *testing.T) {
  4845  	code := fmt.Sprintf(`package policy
  4846  
  4847  	api_version := "%s"
  4848  
  4849  	create_container := {"allowed": true}
  4850  	exec_in_container := {"allowed": true}
  4851  	exec_external := {"allowed": true}
  4852  	`, apiVersion)
  4853  
  4854  	policy, err := newRegoPolicy(code, []oci.Mount{}, []oci.Mount{})
  4855  	if err != nil {
  4856  		t.Fatalf("error compiling the rego policy: %v", err)
  4857  	}
  4858  
  4859  	ctx := context.Background()
  4860  	sandboxID := generateSandboxID(testRand)
  4861  	containerID := generateContainerID(testRand)
  4862  	command := generateCommand(testRand)
  4863  	expectedEnvs := generateEnvironmentVariables(testRand)
  4864  	workingDir := generateWorkingDir(testRand)
  4865  	privileged := randBool(testRand)
  4866  	noNewPrivileges := randBool(testRand)
  4867  	user := generateIDName(testRand)
  4868  	groups := []IDName{}
  4869  	umask := generateUmask(testRand)
  4870  	capabilities := generateCapabilities(testRand)
  4871  	seccomp := ""
  4872  
  4873  	actualEnvs, _, _, err := policy.EnforceCreateContainerPolicy(
  4874  		ctx,
  4875  		sandboxID,
  4876  		containerID,
  4877  		command,
  4878  		expectedEnvs,
  4879  		workingDir,
  4880  		[]oci.Mount{},
  4881  		privileged,
  4882  		noNewPrivileges,
  4883  		user,
  4884  		groups,
  4885  		umask,
  4886  		capabilities,
  4887  		seccomp,
  4888  	)
  4889  
  4890  	if err != nil {
  4891  		t.Errorf("unexpected error when calling EnforceCreateContainerPolicy: %v", err)
  4892  	}
  4893  
  4894  	if !areStringArraysEqual(actualEnvs, expectedEnvs) {
  4895  		t.Error("invalid envList returned from EnforceCreateContainerPolicy")
  4896  	}
  4897  
  4898  	actualEnvs, _, _, err = policy.EnforceExecInContainerPolicy(ctx, containerID, command, expectedEnvs, workingDir, noNewPrivileges, user, groups, umask, capabilities)
  4899  
  4900  	if err != nil {
  4901  		t.Errorf("unexpected error when calling EnforceExecInContainerPolicy: %v", err)
  4902  	}
  4903  
  4904  	if !areStringArraysEqual(actualEnvs, expectedEnvs) {
  4905  		t.Error("invalid envList returned from EnforceExecInContainerPolicy")
  4906  	}
  4907  
  4908  	actualEnvs, _, err = policy.EnforceExecExternalProcessPolicy(ctx, command, expectedEnvs, workingDir)
  4909  
  4910  	if err != nil {
  4911  		t.Errorf("unexpected error when calling EnfForceExecExternalProcessPolicy: %v", err)
  4912  	}
  4913  
  4914  	if !areStringArraysEqual(actualEnvs, expectedEnvs) {
  4915  		t.Error("invalid envList returned from EnforceExecExternalProcessPolicy")
  4916  	}
  4917  }
  4918  
  4919  func Test_Rego_EnvListGetsRedacted(t *testing.T) {
  4920  	c := generateConstraints(testRand, 1)
  4921  	// don't allow env dropping. with dropping we aren't testing the
  4922  	// "invalid env list" message, only the input
  4923  	c.allowEnvironmentVariableDropping = false
  4924  
  4925  	// No environment variables are allowed
  4926  	tc, err := setupRegoCreateContainerTest(c, c.containers[0], false)
  4927  	if err != nil {
  4928  		t.Fatal(err)
  4929  	}
  4930  
  4931  	var envList []string
  4932  	envVar := "FOO=BAR"
  4933  	envList = append(envList, envVar)
  4934  
  4935  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, envList, "bunk", tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  4936  
  4937  	// not getting an error means something is broken
  4938  	if err == nil {
  4939  		t.Fatal("Unexpected success when enforcing policy")
  4940  	}
  4941  
  4942  	if !assertDecisionJSONDoesNotContain(t, err, envVar) {
  4943  		t.Fatal("EnvList wasn't redacted in error message")
  4944  	}
  4945  
  4946  	if !assertDecisionJSONContains(t, err, `FOO=\u003c\u003credacted\u003e\u003e`) {
  4947  		t.Fatal("EnvList redaction format wasn't as expected")
  4948  	}
  4949  }
  4950  
  4951  func Test_Rego_EnforceCreateContainer_ConflictingAllowStdioAccessHasErrorMessage(t *testing.T) {
  4952  	constraints := generateConstraints(testRand, 1)
  4953  	constraints.containers[0].AllowStdioAccess = true
  4954  
  4955  	// create a "duplicate" as far as create container is concerned except for
  4956  	// a different "AllowStdioAccess" value
  4957  	duplicate := &securityPolicyContainer{
  4958  		Command:              constraints.containers[0].Command,
  4959  		EnvRules:             constraints.containers[0].EnvRules,
  4960  		WorkingDir:           constraints.containers[0].WorkingDir,
  4961  		Mounts:               constraints.containers[0].Mounts,
  4962  		Layers:               constraints.containers[0].Layers,
  4963  		Capabilities:         constraints.containers[0].Capabilities,
  4964  		ExecProcesses:        generateExecProcesses(testRand),
  4965  		Signals:              generateListOfSignals(testRand, 0, maxSignalNumber),
  4966  		AllowElevated:        constraints.containers[0].AllowElevated,
  4967  		AllowStdioAccess:     false,
  4968  		NoNewPrivileges:      constraints.containers[0].NoNewPrivileges,
  4969  		User:                 constraints.containers[0].User,
  4970  		SeccompProfileSHA256: constraints.containers[0].SeccompProfileSHA256,
  4971  	}
  4972  
  4973  	constraints.containers = append(constraints.containers, duplicate)
  4974  
  4975  	tc, err := setupRegoCreateContainerTest(constraints, constraints.containers[0], false)
  4976  	if err != nil {
  4977  		t.Fatal(err)
  4978  	}
  4979  
  4980  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  4981  
  4982  	// not getting an error means something is broken
  4983  	if err == nil {
  4984  		t.Fatalf("Unexpected success when enforcing policy")
  4985  	}
  4986  
  4987  	if !assertDecisionJSONContains(t, err, "containers only distinguishable by allow_stdio_access") {
  4988  		t.Fatal("No error message given for conflicting allow_stdio_access on otherwise 'same' containers")
  4989  	}
  4990  }
  4991  
  4992  func Test_Rego_ExecExternalProcessPolicy_ConflictingAllowStdioAccessHasErrorMessage(t *testing.T) {
  4993  	constraints := generateConstraints(testRand, 1)
  4994  	process := generateExternalProcess(testRand)
  4995  	process.allowStdioAccess = false
  4996  	duplicate := process.clone()
  4997  	duplicate.allowStdioAccess = true
  4998  
  4999  	constraints.externalProcesses = append(constraints.externalProcesses, process)
  5000  	constraints.externalProcesses = append(constraints.externalProcesses, duplicate)
  5001  	securityPolicy := constraints.toPolicy()
  5002  	defaultMounts := generateMounts(testRand)
  5003  	privilegedMounts := generateMounts(testRand)
  5004  
  5005  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  5006  		toOCIMounts(defaultMounts),
  5007  		toOCIMounts(privilegedMounts))
  5008  	if err != nil {
  5009  		t.Fatal(err)
  5010  	}
  5011  
  5012  	envList := buildEnvironmentVariablesFromEnvRules(process.envRules, testRand)
  5013  
  5014  	_, _, err = policy.EnforceExecExternalProcessPolicy(constraints.ctx, process.command, envList, process.workingDir)
  5015  	if err == nil {
  5016  		t.Fatal("Policy was unexpectedly not enforced")
  5017  	}
  5018  
  5019  	if !assertDecisionJSONContains(t, err, "external processes only distinguishable by allow_stdio_access") {
  5020  		t.Fatal("No error message given for conflicting allow_stdio_access on otherwise 'same' external processes")
  5021  	}
  5022  }
  5023  
  5024  func Test_Rego_Enforce_CreateContainer_RequiredEnvMissingHasErrorMessage(t *testing.T) {
  5025  	constraints := generateConstraints(testRand, 1)
  5026  	container := selectContainerFromContainerList(constraints.containers, testRand)
  5027  	requiredRule := EnvRuleConfig{
  5028  		Strategy: "string",
  5029  		Rule:     randVariableString(testRand, maxGeneratedEnvironmentVariableRuleLength),
  5030  		Required: true,
  5031  	}
  5032  
  5033  	container.EnvRules = append(container.EnvRules, requiredRule)
  5034  
  5035  	tc, err := setupRegoCreateContainerTest(constraints, container, false)
  5036  	if err != nil {
  5037  		t.Fatal(err)
  5038  	}
  5039  
  5040  	envList := make([]string, 0, len(container.EnvRules))
  5041  	for _, env := range tc.envList {
  5042  		if env != requiredRule.Rule {
  5043  			envList = append(envList, env)
  5044  		}
  5045  	}
  5046  
  5047  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5048  
  5049  	// not getting an error means something is broken
  5050  	if err == nil {
  5051  		t.Fatalf("Unexpected success when enforcing policy")
  5052  	}
  5053  
  5054  	if !assertDecisionJSONContains(t, err, "missing required environment variable") {
  5055  		t.Fatal("No error message given for missing required environment variable")
  5056  	}
  5057  }
  5058  
  5059  func Test_Rego_ExecInContainerPolicy_RequiredEnvMissingHasErrorMessage(t *testing.T) {
  5060  	constraints := generateConstraints(testRand, 1)
  5061  	container := selectContainerFromContainerList(constraints.containers, testRand)
  5062  	neededEnv := randVariableString(testRand, maxGeneratedEnvironmentVariableRuleLength)
  5063  	requiredRule := EnvRuleConfig{
  5064  		Strategy: "string",
  5065  		Rule:     neededEnv,
  5066  		Required: true,
  5067  	}
  5068  
  5069  	container.EnvRules = append(container.EnvRules, requiredRule)
  5070  
  5071  	tc, err := setupRegoRunningContainerTest(constraints, false)
  5072  	if err != nil {
  5073  		t.Fatal(err)
  5074  	}
  5075  
  5076  	running := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  5077  
  5078  	process := selectExecProcess(running.container.ExecProcesses, testRand)
  5079  
  5080  	allEnvs := buildEnvironmentVariablesFromEnvRules(running.container.EnvRules, testRand)
  5081  	envList := make([]string, 0, len(container.EnvRules))
  5082  	for _, env := range allEnvs {
  5083  		if env != requiredRule.Rule {
  5084  			envList = append(envList, env)
  5085  		}
  5086  	}
  5087  	user := buildIDNameFromConfig(running.container.User.UserIDName, testRand)
  5088  	groups := buildGroupIDNamesFromUser(running.container.User, testRand)
  5089  	umask := running.container.User.Umask
  5090  	capabilities := running.container.Capabilities.toExternal()
  5091  
  5092  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(constraints.ctx, running.containerID, process.Command, envList, running.container.WorkingDir, running.container.NoNewPrivileges, user, groups, umask, &capabilities)
  5093  
  5094  	// not getting an error means something is broken
  5095  	if err == nil {
  5096  		t.Fatal("Unexpected success when enforcing policy")
  5097  	}
  5098  
  5099  	if !assertDecisionJSONContains(t, err, "missing required environment variable") {
  5100  		fmt.Print(err.Error())
  5101  		t.Fatal("No error message given for missing required environment variable")
  5102  	}
  5103  }
  5104  
  5105  func Test_Rego_ExecExternalProcessPolicy_RequiredEnvMissingHasErrorMessage(t *testing.T) {
  5106  	constraints := generateConstraints(testRand, 1)
  5107  	process := generateExternalProcess(testRand)
  5108  	neededEnv := randVariableString(testRand, maxGeneratedEnvironmentVariableRuleLength)
  5109  	requiredRule := EnvRuleConfig{
  5110  		Strategy: "string",
  5111  		Rule:     neededEnv,
  5112  		Required: true,
  5113  	}
  5114  
  5115  	process.envRules = append(process.envRules, requiredRule)
  5116  
  5117  	constraints.externalProcesses = append(constraints.externalProcesses, process)
  5118  	securityPolicy := constraints.toPolicy()
  5119  	defaultMounts := generateMounts(testRand)
  5120  	privilegedMounts := generateMounts(testRand)
  5121  
  5122  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  5123  		toOCIMounts(defaultMounts),
  5124  		toOCIMounts(privilegedMounts))
  5125  	if err != nil {
  5126  		t.Fatal(err)
  5127  	}
  5128  
  5129  	allEnvs := buildEnvironmentVariablesFromEnvRules(process.envRules, testRand)
  5130  	envList := make([]string, 0, len(process.envRules))
  5131  	for _, env := range allEnvs {
  5132  		if env != requiredRule.Rule {
  5133  			envList = append(envList, env)
  5134  		}
  5135  	}
  5136  
  5137  	_, _, err = policy.EnforceExecExternalProcessPolicy(constraints.ctx, process.command, envList, process.workingDir)
  5138  	if err == nil {
  5139  		t.Fatal("Policy was unexpectedly not enforced")
  5140  	}
  5141  
  5142  	if !assertDecisionJSONContains(t, err, "missing required environment variable") {
  5143  		fmt.Print(err.Error())
  5144  		t.Fatal("No error message given for missing required environment variable")
  5145  	}
  5146  }
  5147  
  5148  func Test_Rego_EnforceContainerNoNewPrivilegesPolicy_FalseAllowsFalse(t *testing.T) {
  5149  	p := generateConstraints(testRand, 1)
  5150  	p.containers[0].NoNewPrivileges = false
  5151  
  5152  	tc, err := setupSimpleRegoCreateContainerTest(p)
  5153  	if err != nil {
  5154  		t.Fatal(err)
  5155  	}
  5156  
  5157  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, false, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5158  
  5159  	if err != nil {
  5160  		t.Fatal("Unexpected failure with false")
  5161  	}
  5162  }
  5163  
  5164  func Test_Rego_EnforceContainerNoNewPrivilegesPolicy_FalseAllowsTrue(t *testing.T) {
  5165  	p := generateConstraints(testRand, 1)
  5166  	p.containers[0].NoNewPrivileges = false
  5167  
  5168  	tc, err := setupSimpleRegoCreateContainerTest(p)
  5169  	if err != nil {
  5170  		t.Fatal(err)
  5171  	}
  5172  
  5173  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, true, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5174  
  5175  	if err != nil {
  5176  		t.Fatal("Unexpected failure with true")
  5177  	}
  5178  }
  5179  
  5180  func Test_Rego_EnforceContainerNoNewPrivilegesPolicy_TrueDisallowsFalse(t *testing.T) {
  5181  	p := generateConstraints(testRand, 1)
  5182  	p.containers[0].NoNewPrivileges = true
  5183  
  5184  	tc, err := setupSimpleRegoCreateContainerTest(p)
  5185  	if err != nil {
  5186  		t.Fatal(err)
  5187  	}
  5188  
  5189  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, false, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5190  
  5191  	if err == nil {
  5192  		t.Fatal("Unexpected success with false")
  5193  	}
  5194  
  5195  	if !assertDecisionJSONContains(t, err, "invalid noNewPrivileges") {
  5196  		t.Fatal("Expected error message is missing")
  5197  	}
  5198  }
  5199  
  5200  func Test_Rego_EnforceContainerNoNewPrivilegesPolicy_TrueAllowsTrue(t *testing.T) {
  5201  	p := generateConstraints(testRand, 1)
  5202  	p.containers[0].NoNewPrivileges = true
  5203  
  5204  	tc, err := setupSimpleRegoCreateContainerTest(p)
  5205  	if err != nil {
  5206  		t.Fatal(err)
  5207  	}
  5208  
  5209  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, true, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5210  
  5211  	if err != nil {
  5212  		t.Fatal("Unexpected failure with true")
  5213  	}
  5214  }
  5215  
  5216  func Test_Rego_EnforceExecInContainerNoNewPrivilegesPolicy_FalseAllowsFalse(t *testing.T) {
  5217  	p := generateConstraints(testRand, 1)
  5218  	p.containers[0].NoNewPrivileges = false
  5219  
  5220  	tc, err := setupRegoRunningContainerTest(p, false)
  5221  	if err != nil {
  5222  		t.Fatal(err)
  5223  	}
  5224  
  5225  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  5226  	process := selectExecProcess(container.container.ExecProcesses, testRand)
  5227  	envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  5228  	user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  5229  	groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  5230  	umask := container.container.User.Umask
  5231  	capabilities := container.container.Capabilities.toExternal()
  5232  
  5233  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, false, user, groups, umask, &capabilities)
  5234  
  5235  	if err != nil {
  5236  		t.Fatal("Unexpected failure with false")
  5237  	}
  5238  }
  5239  
  5240  func Test_Rego_EnforceExecInContainerNoNewPrivilegesPolicy_FalseAllowsTrue(t *testing.T) {
  5241  	p := generateConstraints(testRand, 1)
  5242  	p.containers[0].NoNewPrivileges = false
  5243  
  5244  	tc, err := setupRegoRunningContainerTest(p, false)
  5245  	if err != nil {
  5246  		t.Fatal(err)
  5247  	}
  5248  
  5249  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  5250  	process := selectExecProcess(container.container.ExecProcesses, testRand)
  5251  	envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  5252  	user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  5253  	groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  5254  	umask := container.container.User.Umask
  5255  	capabilities := container.container.Capabilities.toExternal()
  5256  
  5257  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, true, user, groups, umask, &capabilities)
  5258  
  5259  	if err != nil {
  5260  		t.Fatal("Unexpected failure with true")
  5261  	}
  5262  }
  5263  
  5264  func Test_Rego_EnforceExecInContainerNoNewPrivilegesPolicy_TrueDisallowsFalse(t *testing.T) {
  5265  	p := generateConstraints(testRand, 1)
  5266  	p.containers[0].NoNewPrivileges = true
  5267  
  5268  	tc, err := setupRegoRunningContainerTest(p, false)
  5269  	if err != nil {
  5270  		t.Fatal(err)
  5271  	}
  5272  
  5273  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  5274  	process := selectExecProcess(container.container.ExecProcesses, testRand)
  5275  	envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  5276  	user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  5277  	groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  5278  	umask := container.container.User.Umask
  5279  	capabilities := container.container.Capabilities.toExternal()
  5280  
  5281  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, false, user, groups, umask, &capabilities)
  5282  
  5283  	if err == nil {
  5284  		t.Fatal("Unexpected success with false")
  5285  	}
  5286  
  5287  	if !assertDecisionJSONContains(t, err, "invalid noNewPrivileges") {
  5288  		t.Fatal("Expected error message is missing")
  5289  	}
  5290  }
  5291  
  5292  func Test_Rego_EnforceExecInContainerNoNewPrivilegesPolicy_TrueAllowsTrue(t *testing.T) {
  5293  	p := generateConstraints(testRand, 1)
  5294  	p.containers[0].NoNewPrivileges = true
  5295  
  5296  	tc, err := setupRegoRunningContainerTest(p, false)
  5297  	if err != nil {
  5298  		t.Fatal(err)
  5299  	}
  5300  
  5301  	container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  5302  	process := selectExecProcess(container.container.ExecProcesses, testRand)
  5303  	envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  5304  	user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  5305  	groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  5306  	umask := container.container.User.Umask
  5307  	capabilities := container.container.Capabilities.toExternal()
  5308  
  5309  	_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, true, user, groups, umask, &capabilities)
  5310  
  5311  	if err != nil {
  5312  		t.Fatal("Unexpected failure with true")
  5313  	}
  5314  }
  5315  
  5316  func Test_Rego_EnforceContainerUserPolicy_UserName_NoMatches(t *testing.T) {
  5317  	f := func(p *generatedConstraints) bool {
  5318  		tc, err := setupSimpleRegoCreateContainerTest(p)
  5319  		if err != nil {
  5320  			t.Error(err)
  5321  			return false
  5322  		}
  5323  
  5324  		user := generateIDName(testRand)
  5325  
  5326  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5327  
  5328  		if err == nil {
  5329  			return false
  5330  		}
  5331  
  5332  		return assertDecisionJSONContains(t, err, "invalid user")
  5333  	}
  5334  
  5335  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  5336  		t.Errorf("Test_Rego_EnforceContainerUserPolicy_UserName_NoMatches: %v", err)
  5337  	}
  5338  }
  5339  
  5340  func Test_Rego_EnforceContainerUserPolicy_GroupNames_NoMatches(t *testing.T) {
  5341  	f := func(p *generatedConstraints) bool {
  5342  		tc, err := setupSimpleRegoCreateContainerTest(p)
  5343  		if err != nil {
  5344  			t.Error(err)
  5345  			return false
  5346  		}
  5347  
  5348  		groups := append(tc.groups, generateIDName(testRand))
  5349  
  5350  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, groups, tc.umask, tc.capabilities, tc.seccomp)
  5351  
  5352  		if err == nil {
  5353  			return false
  5354  		}
  5355  
  5356  		return assertDecisionJSONContains(t, err, "invalid user")
  5357  	}
  5358  
  5359  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  5360  		t.Errorf("Test_Rego_EnforceContainerUserPolicy_GroupNames_NoMatches: %v", err)
  5361  	}
  5362  }
  5363  
  5364  func Test_Rego_EnforceContainerUserPolicy_Umask_NoMatches(t *testing.T) {
  5365  	f := func(p *generatedConstraints) bool {
  5366  		tc, err := setupSimpleRegoCreateContainerTest(p)
  5367  		if err != nil {
  5368  			t.Error(err)
  5369  			return false
  5370  		}
  5371  
  5372  		umask := "0888"
  5373  
  5374  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(p.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, umask, tc.capabilities, tc.seccomp)
  5375  
  5376  		if err == nil {
  5377  			return false
  5378  		}
  5379  
  5380  		return assertDecisionJSONContains(t, err, "invalid user")
  5381  	}
  5382  
  5383  	if err := quick.Check(f, &quick.Config{MaxCount: 25, Rand: testRand}); err != nil {
  5384  		t.Errorf("Test_Rego_EnforceContainerUserPolicy_Umask_NoMatches: %v", err)
  5385  	}
  5386  }
  5387  
  5388  func Test_Rego_EnforceExecInContainerUserPolicy_Username_NoMatches(t *testing.T) {
  5389  	f := func(p *generatedConstraints) bool {
  5390  		tc, err := setupRegoRunningContainerTest(p, false)
  5391  		if err != nil {
  5392  			t.Error(err)
  5393  			return false
  5394  		}
  5395  
  5396  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  5397  		process := selectExecProcess(container.container.ExecProcesses, testRand)
  5398  		envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  5399  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  5400  		umask := container.container.User.Umask
  5401  		capabilities := container.container.Capabilities.toExternal()
  5402  
  5403  		user := generateIDName(testRand)
  5404  
  5405  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  5406  
  5407  		// not getting an error means something is broken
  5408  		if err == nil {
  5409  			return false
  5410  		}
  5411  
  5412  		return assertDecisionJSONContains(t, err, "invalid user")
  5413  	}
  5414  
  5415  	if err := quick.Check(f, &quick.Config{MaxCount: 10, Rand: testRand}); err != nil {
  5416  		t.Errorf("Test_Rego_EnforceExecInContainerUserPolicy_Username_NoMatches: %v", err)
  5417  	}
  5418  }
  5419  
  5420  func Test_Rego_EnforceExecInContainerUserPolicy_GroupNames_NoMatches(t *testing.T) {
  5421  	f := func(p *generatedConstraints) bool {
  5422  		tc, err := setupRegoRunningContainerTest(p, false)
  5423  		if err != nil {
  5424  			t.Error(err)
  5425  			return false
  5426  		}
  5427  
  5428  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  5429  		process := selectExecProcess(container.container.ExecProcesses, testRand)
  5430  		envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  5431  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  5432  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  5433  		umask := container.container.User.Umask
  5434  		capabilities := container.container.Capabilities.toExternal()
  5435  
  5436  		groups = append(groups, generateIDName(testRand))
  5437  
  5438  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  5439  
  5440  		// not getting an error means something is broken
  5441  		if err == nil {
  5442  			return false
  5443  		}
  5444  
  5445  		return assertDecisionJSONContains(t, err, "invalid user")
  5446  	}
  5447  
  5448  	if err := quick.Check(f, &quick.Config{MaxCount: 10, Rand: testRand}); err != nil {
  5449  		t.Errorf("Test_Rego_EnforceExecInContainerUserPolicy_GroupNames_NoMatches: %v", err)
  5450  	}
  5451  }
  5452  
  5453  func Test_Rego_EnforceExecInContainerUserPolicy_Umask_NoMatches(t *testing.T) {
  5454  	f := func(p *generatedConstraints) bool {
  5455  		tc, err := setupRegoRunningContainerTest(p, false)
  5456  		if err != nil {
  5457  			t.Error(err)
  5458  			return false
  5459  		}
  5460  
  5461  		container := selectContainerFromRunningContainers(tc.runningContainers, testRand)
  5462  		process := selectExecProcess(container.container.ExecProcesses, testRand)
  5463  		envList := buildEnvironmentVariablesFromEnvRules(container.container.EnvRules, testRand)
  5464  		user := buildIDNameFromConfig(container.container.User.UserIDName, testRand)
  5465  		groups := buildGroupIDNamesFromUser(container.container.User, testRand)
  5466  		capabilities := container.container.Capabilities.toExternal()
  5467  
  5468  		// This value will never be generated by our generators as it isn't valid.
  5469  		// We don't care about valid for this test, only that it won't match any
  5470  		// generated value.
  5471  		umask := "8888"
  5472  
  5473  		_, _, _, err = tc.policy.EnforceExecInContainerPolicy(p.ctx, container.containerID, process.Command, envList, container.container.WorkingDir, container.container.NoNewPrivileges, user, groups, umask, &capabilities)
  5474  
  5475  		// not getting an error means something is broken
  5476  		if err == nil {
  5477  			return false
  5478  		}
  5479  
  5480  		return assertDecisionJSONContains(t, err, "invalid user")
  5481  	}
  5482  
  5483  	if err := quick.Check(f, &quick.Config{MaxCount: 10, Rand: testRand}); err != nil {
  5484  		t.Errorf("Test_Rego_EnforceExecInContainerUserPolicy_Umask_NoMatches: %v", err)
  5485  	}
  5486  }
  5487  
  5488  func Test_Rego_EnforceCreateContainerUserPolicy_UserIDName_Re2Match(t *testing.T) {
  5489  	gc := generateConstraints(testRand, 1)
  5490  	gc.containers[0].User.UserIDName = IDNameConfig{
  5491  		Strategy: IDNameStrategyRegex,
  5492  		Rule:     "foo\\d+",
  5493  	}
  5494  
  5495  	tc, err := setupSimpleRegoCreateContainerTest(gc)
  5496  	if err != nil {
  5497  		t.Fatalf("unable to setup test: %v", err)
  5498  	}
  5499  
  5500  	user := IDName{
  5501  		ID:   "1000",
  5502  		Name: "foo123",
  5503  	}
  5504  
  5505  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5506  	if err != nil {
  5507  		t.Errorf("Expected container setup to be allowed. It wasn't: %v", err)
  5508  	}
  5509  }
  5510  
  5511  func Test_Rego_EnforceCreateContainerUserPolicy_UserIDName_AnyMatch(t *testing.T) {
  5512  	gc := generateConstraints(testRand, 1)
  5513  	gc.containers[0].User.UserIDName = IDNameConfig{
  5514  		Strategy: IDNameStrategyAny,
  5515  		Rule:     "",
  5516  	}
  5517  
  5518  	tc, err := setupSimpleRegoCreateContainerTest(gc)
  5519  	if err != nil {
  5520  		t.Fatalf("unable to setup test: %v", err)
  5521  	}
  5522  
  5523  	user := generateIDName(testRand)
  5524  
  5525  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5526  	if err != nil {
  5527  		t.Errorf("Expected container setup to be allowed. It wasn't: %v", err)
  5528  	}
  5529  }
  5530  
  5531  func Test_Rego_EnforceCreateContainerUserPolicy_GroupIDName_Re2Match(t *testing.T) {
  5532  	gc := generateConstraints(testRand, 1)
  5533  	gc.containers[0].User.GroupIDNames = append(gc.containers[0].User.GroupIDNames, IDNameConfig{
  5534  		Strategy: IDNameStrategyRegex,
  5535  		Rule:     "foo\\d+",
  5536  	})
  5537  
  5538  	tc, err := setupSimpleRegoCreateContainerTest(gc)
  5539  	if err != nil {
  5540  		t.Fatalf("unable to setup test: %v", err)
  5541  	}
  5542  
  5543  	groups := append(tc.groups, IDName{ID: "1000", Name: "foo123"})
  5544  
  5545  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, groups, tc.umask, tc.capabilities, tc.seccomp)
  5546  	if err != nil {
  5547  		t.Errorf("Expected container setup to be allowed. It wasn't: %v", err)
  5548  	}
  5549  }
  5550  
  5551  func Test_Rego_EnforceCreateContainerUserPolicy_GroupIDName_AnyMatch(t *testing.T) {
  5552  	gc := generateConstraints(testRand, 1)
  5553  	gc.containers[0].User.GroupIDNames = append(gc.containers[0].User.GroupIDNames, IDNameConfig{
  5554  		Strategy: IDNameStrategyAny,
  5555  		Rule:     "",
  5556  	})
  5557  
  5558  	tc, err := setupSimpleRegoCreateContainerTest(gc)
  5559  	if err != nil {
  5560  		t.Fatalf("unable to setup test: %v", err)
  5561  	}
  5562  
  5563  	groups := append(tc.groups, generateIDName(testRand))
  5564  
  5565  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, groups, tc.umask, tc.capabilities, tc.seccomp)
  5566  	if err != nil {
  5567  		t.Errorf("Expected container setup to be allowed. It wasn't: %v", err)
  5568  	}
  5569  }
  5570  
  5571  func Test_Rego_EnforceCreateContainerSeccompPolicy_NoMatch(t *testing.T) {
  5572  	gc := generateConstraints(testRand, 1)
  5573  
  5574  	tc, err := setupSimpleRegoCreateContainerTest(gc)
  5575  	if err != nil {
  5576  		t.Fatalf("unable to setup test: %v", err)
  5577  	}
  5578  
  5579  	seccomp := generateRootHash(testRand)
  5580  
  5581  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, tc.workingDir, tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, seccomp)
  5582  	if err == nil {
  5583  		t.Error("Expected container setup to not be allowed.")
  5584  	} else if !assertDecisionJSONContains(t, err, "invalid seccomp") {
  5585  		t.Error("`invalid seccomp` missing from error message")
  5586  	}
  5587  }
  5588  
  5589  func Test_Rego_FrameworkSVN(t *testing.T) {
  5590  	gc := generateConstraints(testRand, 1)
  5591  	securityPolicy := gc.toPolicy()
  5592  	defaultMounts := generateMounts(testRand)
  5593  	privilegedMounts := generateMounts(testRand)
  5594  
  5595  	code := securityPolicy.marshalRego()
  5596  	code = strings.Replace(code, "framework_version", "framework_svn", 1)
  5597  
  5598  	policy, err := newRegoPolicy(code,
  5599  		toOCIMounts(defaultMounts),
  5600  		toOCIMounts(privilegedMounts))
  5601  	if err != nil {
  5602  		t.Fatalf("unable to create policy: %v", err)
  5603  	}
  5604  
  5605  	value, err := policy.rego.RawQuery("data.framework.policy_framework_version", map[string]interface{}{})
  5606  	if err != nil {
  5607  		t.Fatalf("unable to query policy: %v", err)
  5608  	}
  5609  
  5610  	policyFrameworkVersion, ok := value[0].Expressions[0].Value.(string)
  5611  	if ok {
  5612  		if policyFrameworkVersion != frameworkVersion {
  5613  			t.Error("policy_framework_version is not set correctly from framework_svn")
  5614  		}
  5615  	} else {
  5616  		t.Error("no result set from querying data.framework.policy_framework_version")
  5617  	}
  5618  }
  5619  
  5620  func Test_Rego_Fragment_FrameworkSVN(t *testing.T) {
  5621  	gc := generateConstraints(testRand, 1)
  5622  	gc.fragments = generateFragments(testRand, 1)
  5623  
  5624  	gc.fragments = generateFragments(testRand, 1)
  5625  	gc.fragments[0].minimumSVN = generateSemver(testRand)
  5626  	securityPolicy := gc.toPolicy()
  5627  
  5628  	defaultMounts := toOCIMounts(generateMounts(testRand))
  5629  	privilegedMounts := toOCIMounts(generateMounts(testRand))
  5630  	policy, err := newRegoPolicy(securityPolicy.marshalRego(), defaultMounts, privilegedMounts)
  5631  
  5632  	if err != nil {
  5633  		t.Fatalf("error compiling policy: %v", err)
  5634  	}
  5635  
  5636  	fragmentConstraints := generateConstraints(testRand, 1)
  5637  	fragmentConstraints.svn = mustIncrementSVN(gc.fragments[0].minimumSVN)
  5638  	code := fragmentConstraints.toFragment().marshalRego()
  5639  
  5640  	policy.rego.AddModule(fragmentConstraints.namespace, &rpi.RegoModule{
  5641  		Namespace: fragmentConstraints.namespace,
  5642  		Feed:      gc.fragments[0].feed,
  5643  		Issuer:    gc.fragments[0].issuer,
  5644  		Code:      code,
  5645  	})
  5646  
  5647  	input := map[string]interface{}{
  5648  		"namespace": fragmentConstraints.namespace,
  5649  	}
  5650  	result, err := policy.rego.RawQuery("data.framework.fragment_framework_version", input)
  5651  
  5652  	if err != nil {
  5653  		t.Fatalf("error querying policy: %v", err)
  5654  	}
  5655  
  5656  	fragmentFrameworkVersion, ok := result[0].Expressions[0].Value.(string)
  5657  
  5658  	if ok {
  5659  		if fragmentFrameworkVersion != frameworkVersion {
  5660  			t.Error("fragment_framework_version is not set correctly from framework_svn")
  5661  		}
  5662  	} else {
  5663  		t.Error("no result set from querying data.framework.fragment_framework_version")
  5664  	}
  5665  }
  5666  
  5667  func Test_Rego_APISVN(t *testing.T) {
  5668  	gc := generateConstraints(testRand, 1)
  5669  	securityPolicy := gc.toPolicy()
  5670  	defaultMounts := generateMounts(testRand)
  5671  	privilegedMounts := generateMounts(testRand)
  5672  
  5673  	code := securityPolicy.marshalRego()
  5674  	code = strings.Replace(code, "api_version", "api_svn", 1)
  5675  
  5676  	policy, err := newRegoPolicy(code,
  5677  		toOCIMounts(defaultMounts),
  5678  		toOCIMounts(privilegedMounts))
  5679  	if err != nil {
  5680  		t.Fatalf("unable to create policy: %v", err)
  5681  	}
  5682  
  5683  	value, err := policy.rego.RawQuery("data.framework.policy_api_version", map[string]interface{}{})
  5684  	if err != nil {
  5685  		t.Fatalf("unable to query policy: %v", err)
  5686  	}
  5687  
  5688  	policyAPIVersion, ok := value[0].Expressions[0].Value.(string)
  5689  	if ok {
  5690  		if policyAPIVersion != apiVersion {
  5691  			t.Error("policy_api_version is not set correctly from api_svn")
  5692  		}
  5693  	} else {
  5694  		t.Error("no result set from querying data.framework.policy_api_version")
  5695  	}
  5696  }
  5697  
  5698  func Test_Rego_NoReason(t *testing.T) {
  5699  	code := `package policy
  5700  
  5701  	api_version := "0.0.1"
  5702  
  5703  	mount_device := {"allowed": false}
  5704  `
  5705  	policy, err := newRegoPolicy(code, []oci.Mount{}, []oci.Mount{})
  5706  	if err != nil {
  5707  		t.Fatalf("unable to create policy: %v", err)
  5708  	}
  5709  
  5710  	ctx := context.Background()
  5711  	err = policy.EnforceDeviceMountPolicy(ctx, generateMountTarget(testRand), generateRootHash(testRand))
  5712  	if err == nil {
  5713  		t.Error("expected error, got nil")
  5714  	}
  5715  
  5716  	assertDecisionJSONContains(t, err, noReasonMessage)
  5717  }
  5718  
  5719  func Test_Rego_ErrorTruncation(t *testing.T) {
  5720  	f := func(p *generatedConstraints) bool {
  5721  		tc, err := setupSimpleRegoCreateContainerTest(p)
  5722  		if err != nil {
  5723  			t.Error(err)
  5724  			return false
  5725  		}
  5726  
  5727  		maxErrorMessageLength := int(randMinMax(testRand, 128, 4*1024))
  5728  		tc.policy.maxErrorMessageLength = maxErrorMessageLength
  5729  
  5730  		_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, randString(testRand, 20), tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5731  		// not getting an error means something is broken
  5732  		if err == nil {
  5733  			return false
  5734  		}
  5735  
  5736  		if len(err.Error()) > maxErrorMessageLength {
  5737  			return assertDecisionJSONContains(t, err, `"reason.error_objects","input","reason"`)
  5738  		}
  5739  
  5740  		policyDecisionJSON, err := ExtractPolicyDecision(err.Error())
  5741  		if err != nil {
  5742  			t.Errorf("unable to extract policy decision JSON: %v", err)
  5743  			return false
  5744  		}
  5745  
  5746  		var policyDecision map[string]interface{}
  5747  		err = json.Unmarshal([]byte(policyDecisionJSON), &policyDecision)
  5748  		if err != nil {
  5749  			t.Errorf("unable to unmarshal policy decision: %v", err)
  5750  		}
  5751  
  5752  		if truncated, ok := policyDecision["truncated"].([]interface{}); ok {
  5753  			if truncated[0].(string) != "reason.error_objects" {
  5754  				t.Error("first item to be truncated should be reason.error_objects")
  5755  				return false
  5756  			} else if len(truncated) > 1 && truncated[1].(string) != "input" {
  5757  				t.Error("second item to be truncated should be input")
  5758  				return false
  5759  			}
  5760  		}
  5761  
  5762  		return true
  5763  	}
  5764  
  5765  	if err := quick.Check(f, &quick.Config{MaxCount: 50, Rand: testRand}); err != nil {
  5766  		t.Errorf("Test_Rego_EnforceOverlayMountPolicy_No_Matches failed: %v", err)
  5767  	}
  5768  }
  5769  
  5770  func Test_Rego_ErrorTruncation_Unable(t *testing.T) {
  5771  	gc := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  5772  	tc, err := setupRegoOverlayTest(gc, false)
  5773  	if err != nil {
  5774  		t.Fatal(err)
  5775  	}
  5776  
  5777  	maxErrorMessageLength := 32
  5778  	tc.policy.maxErrorMessageLength = maxErrorMessageLength
  5779  	err = tc.policy.EnforceOverlayMountPolicy(gc.ctx, tc.containerID, tc.layers, testDataGenerator.uniqueMountTarget())
  5780  
  5781  	if err == nil {
  5782  		t.Fatal("Policy did not throw the expected error")
  5783  	}
  5784  
  5785  	assertDecisionJSONContains(t, err, `"reason.error_objects","input","reason"`)
  5786  }
  5787  
  5788  func Test_Rego_ErrorTruncation_CustomPolicy(t *testing.T) {
  5789  	code := fmt.Sprintf(`package policy
  5790  
  5791  	api_version := "0.1.0"
  5792  
  5793  	mount_device := {"allowed": false}
  5794  
  5795  	reason := {"custom_error": "%s"}
  5796  `, randString(testRand, 2048))
  5797  
  5798  	policy, err := newRegoPolicy(code, []oci.Mount{}, []oci.Mount{})
  5799  	if err != nil {
  5800  		t.Fatalf("unable to create policy: %v", err)
  5801  	}
  5802  
  5803  	policy.maxErrorMessageLength = 512
  5804  	ctx := context.Background()
  5805  	err = policy.EnforceDeviceMountPolicy(ctx, generateMountTarget(testRand), generateRootHash(testRand))
  5806  	if err == nil {
  5807  		t.Error("expected error, got nil")
  5808  	}
  5809  
  5810  	assertDecisionJSONContains(t, err, `"input","reason"`)
  5811  }
  5812  
  5813  func Test_Rego_Missing_Enforcement_Point(t *testing.T) {
  5814  	code := `package policy
  5815  
  5816  	api_svn := "0.10.0"
  5817  
  5818  	mount_device := {"allowed": true}
  5819  	unmount_device := {"allowed": true}
  5820  	mount_overlay := {"allowed": true}
  5821  	unmount_overlay := {"allowed": true}
  5822  
  5823  	reason := {"errors": data.framework.errors}
  5824  `
  5825  
  5826  	policy, err := newRegoPolicy(code, []oci.Mount{}, []oci.Mount{})
  5827  	if err != nil {
  5828  		t.Fatalf("unable to create policy: %v", err)
  5829  	}
  5830  
  5831  	sandboxID := generateSandboxID(testRand)
  5832  	containerID := generateContainerID(testRand)
  5833  	argList := generateCommand(testRand)
  5834  	envList := generateEnvironmentVariables(testRand)
  5835  	workingDir := generateWorkingDir(testRand)
  5836  	mounts := []oci.Mount{}
  5837  	user := generateIDName(testRand)
  5838  	groups := []IDName{}
  5839  	umask := generateUmask(testRand)
  5840  	capabilities := &oci.LinuxCapabilities{
  5841  		Bounding:    DefaultUnprivilegedCapabilities(),
  5842  		Effective:   DefaultUnprivilegedCapabilities(),
  5843  		Inheritable: EmptyCapabiltiesSet(),
  5844  		Permitted:   DefaultUnprivilegedCapabilities(),
  5845  		Ambient:     EmptyCapabiltiesSet(),
  5846  	}
  5847  
  5848  	ctx := context.Background()
  5849  	_, _, _, err = policy.EnforceCreateContainerPolicy(
  5850  		ctx,
  5851  		sandboxID,
  5852  		containerID,
  5853  		argList,
  5854  		envList,
  5855  		workingDir,
  5856  		mounts,
  5857  		false,
  5858  		false,
  5859  		user,
  5860  		groups,
  5861  		umask,
  5862  		capabilities,
  5863  		"",
  5864  	)
  5865  
  5866  	assertDecisionJSONContains(t, err, "rule for create_container is missing from policy")
  5867  }
  5868  
  5869  func Test_Rego_Capabiltiies_Placeholder_Object_Privileged(t *testing.T) {
  5870  	gc := generateConstraints(testRand, 1)
  5871  	gc.containers[0].Capabilities = &capabilitiesInternal{
  5872  		Bounding:    DefaultPrivilegedCapabilities(),
  5873  		Effective:   DefaultPrivilegedCapabilities(),
  5874  		Inheritable: DefaultPrivilegedCapabilities(),
  5875  		Permitted:   DefaultPrivilegedCapabilities(),
  5876  		Ambient:     EmptyCapabiltiesSet(),
  5877  	}
  5878  	tc, err := setupSimpleRegoCreateContainerTest(gc)
  5879  	if err != nil {
  5880  		t.Fatal(err)
  5881  	}
  5882  
  5883  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, randString(testRand, 20), tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5884  
  5885  	if err == nil {
  5886  		t.Fatal("Policy did not throw the expected error")
  5887  	}
  5888  
  5889  	assertDecisionJSONContains(t, err, "[privileged]")
  5890  	assertDecisionJSONDoesNotContain(t, err, DefaultPrivilegedCapabilities()...)
  5891  }
  5892  
  5893  func Test_Rego_Capabiltiies_Placeholder_Object_Unprivileged(t *testing.T) {
  5894  	gc := generateConstraints(testRand, 1)
  5895  	gc.containers[0].Capabilities = &capabilitiesInternal{
  5896  		Bounding:    DefaultUnprivilegedCapabilities(),
  5897  		Effective:   DefaultUnprivilegedCapabilities(),
  5898  		Inheritable: EmptyCapabiltiesSet(),
  5899  		Permitted:   DefaultUnprivilegedCapabilities(),
  5900  		Ambient:     EmptyCapabiltiesSet(),
  5901  	}
  5902  	tc, err := setupSimpleRegoCreateContainerTest(gc)
  5903  	if err != nil {
  5904  		t.Fatal(err)
  5905  	}
  5906  
  5907  	_, _, _, err = tc.policy.EnforceCreateContainerPolicy(tc.ctx, tc.sandboxID, tc.containerID, tc.argList, tc.envList, randString(testRand, 20), tc.mounts, false, tc.noNewPrivileges, tc.user, tc.groups, tc.umask, tc.capabilities, tc.seccomp)
  5908  
  5909  	if err == nil {
  5910  		t.Fatal("Policy did not throw the expected error")
  5911  	}
  5912  
  5913  	assertDecisionJSONContains(t, err, "[unprivileged]")
  5914  	assertDecisionJSONDoesNotContain(t, err, DefaultUnprivilegedCapabilities()...)
  5915  }
  5916  
  5917  //
  5918  // Setup and "fixtures" follow...
  5919  //
  5920  
  5921  func generateExternalProcesses(r *rand.Rand) []*externalProcess {
  5922  	var processes []*externalProcess
  5923  
  5924  	numProcesses := atLeastOneAtMost(r, maxExternalProcessesInGeneratedConstraints)
  5925  	for i := 0; i < int(numProcesses); i++ {
  5926  		processes = append(processes, generateExternalProcess(r))
  5927  	}
  5928  
  5929  	return processes
  5930  }
  5931  
  5932  func generateExternalProcess(r *rand.Rand) *externalProcess {
  5933  	return &externalProcess{
  5934  		command:          generateCommand(r),
  5935  		envRules:         generateEnvironmentVariableRules(r),
  5936  		workingDir:       generateWorkingDir(r),
  5937  		allowStdioAccess: randBool(r),
  5938  	}
  5939  }
  5940  
  5941  func randChoices(r *rand.Rand, numChoices int, numItems int) []int {
  5942  	shuffle := r.Perm(numItems)
  5943  	if numChoices > numItems {
  5944  		return shuffle
  5945  	}
  5946  
  5947  	return shuffle[:numChoices]
  5948  }
  5949  
  5950  func randChoicesWithReplacement(r *rand.Rand, numChoices int, numItems int) []int {
  5951  	choices := make([]int, numChoices)
  5952  	for i := 0; i < numChoices; i++ {
  5953  		choices[i] = r.Intn(numItems)
  5954  	}
  5955  
  5956  	return choices
  5957  }
  5958  
  5959  func randChooseStrings(r *rand.Rand, items []string, numChoices int) []string {
  5960  	numItems := len(items)
  5961  	choiceIndices := randChoices(r, numChoices, numItems)
  5962  	choices := make([]string, numChoices)
  5963  	for i, index := range choiceIndices {
  5964  		choices[i] = items[index]
  5965  	}
  5966  	return choices
  5967  }
  5968  
  5969  func randChooseStringsWithReplacement(r *rand.Rand, items []string, numChoices int) []string {
  5970  	numItems := len(items)
  5971  	choiceIndices := randChoicesWithReplacement(r, numChoices, numItems)
  5972  	choices := make([]string, numChoices)
  5973  	for i, index := range choiceIndices {
  5974  		choices[i] = items[index]
  5975  	}
  5976  	return choices
  5977  }
  5978  
  5979  func selectExternalProcessFromConstraints(constraints *generatedConstraints, r *rand.Rand) *externalProcess {
  5980  	numberOfProcessesInConstraints := len(constraints.externalProcesses)
  5981  	return constraints.externalProcesses[r.Intn(numberOfProcessesInConstraints)]
  5982  }
  5983  
  5984  func (constraints *generatedConstraints) toPolicy() *securityPolicyInternal {
  5985  	return &securityPolicyInternal{
  5986  		Containers:                       constraints.containers,
  5987  		ExternalProcesses:                constraints.externalProcesses,
  5988  		Fragments:                        constraints.fragments,
  5989  		AllowPropertiesAccess:            constraints.allowGetProperties,
  5990  		AllowDumpStacks:                  constraints.allowDumpStacks,
  5991  		AllowRuntimeLogging:              constraints.allowRuntimeLogging,
  5992  		AllowEnvironmentVariableDropping: constraints.allowEnvironmentVariableDropping,
  5993  		AllowUnencryptedScratch:          constraints.allowUnencryptedScratch,
  5994  		AllowCapabilityDropping:          constraints.allowCapabilityDropping,
  5995  	}
  5996  }
  5997  
  5998  func (constraints *generatedConstraints) toFragment() *securityPolicyFragment {
  5999  	return &securityPolicyFragment{
  6000  		Namespace:         constraints.namespace,
  6001  		SVN:               constraints.svn,
  6002  		Containers:        constraints.containers,
  6003  		ExternalProcesses: constraints.externalProcesses,
  6004  		Fragments:         constraints.fragments,
  6005  	}
  6006  }
  6007  
  6008  func toOCIMounts(mounts []mountInternal) []oci.Mount {
  6009  	result := make([]oci.Mount, len(mounts))
  6010  	for i, mount := range mounts {
  6011  		result[i] = oci.Mount{
  6012  			Source:      mount.Source,
  6013  			Destination: mount.Destination,
  6014  			Options:     mount.Options,
  6015  			Type:        mount.Type,
  6016  		}
  6017  	}
  6018  	return result
  6019  }
  6020  
  6021  /**
  6022   * NOTE_TESTCOPY: the following "copy*" functions are provided to ensure that
  6023   * everything passed to the policy is a new object which will not be shared in
  6024   * any way with other policy objects in other tests. In any additional fixture
  6025   * setup routines these functions (or others like them) should be used.
  6026   */
  6027  
  6028  func copyStrings(values []string) []string {
  6029  	valuesCopy := make([]string, len(values))
  6030  	copy(valuesCopy, values)
  6031  	return valuesCopy
  6032  }
  6033  
  6034  func copyMounts(mounts []oci.Mount) []oci.Mount {
  6035  	bytes, err := json.Marshal(mounts)
  6036  	if err != nil {
  6037  		panic(err)
  6038  	}
  6039  
  6040  	mountsCopy := make([]oci.Mount, len(mounts))
  6041  	err = json.Unmarshal(bytes, &mountsCopy)
  6042  	if err != nil {
  6043  		panic(err)
  6044  	}
  6045  
  6046  	return mountsCopy
  6047  }
  6048  
  6049  func copyMountsInternal(mounts []mountInternal) []mountInternal {
  6050  	var mountsCopy []mountInternal
  6051  
  6052  	for _, in := range mounts {
  6053  		out := mountInternal{
  6054  			Source:      in.Source,
  6055  			Destination: in.Destination,
  6056  			Type:        in.Type,
  6057  			Options:     copyStrings(in.Options),
  6058  		}
  6059  
  6060  		mountsCopy = append(mountsCopy, out)
  6061  	}
  6062  
  6063  	return mountsCopy
  6064  }
  6065  
  6066  func copyLinuxCapabilities(caps oci.LinuxCapabilities) oci.LinuxCapabilities {
  6067  	bytes, err := json.Marshal(caps)
  6068  	if err != nil {
  6069  		panic(err)
  6070  	}
  6071  
  6072  	capsCopy := oci.LinuxCapabilities{}
  6073  	err = json.Unmarshal(bytes, &capsCopy)
  6074  	if err != nil {
  6075  		panic(err)
  6076  	}
  6077  
  6078  	return capsCopy
  6079  }
  6080  
  6081  func copyLinuxSeccomp(seccomp oci.LinuxSeccomp) oci.LinuxSeccomp {
  6082  	bytes, err := json.Marshal(seccomp)
  6083  	if err != nil {
  6084  		panic(err)
  6085  	}
  6086  
  6087  	seccompCopy := oci.LinuxSeccomp{}
  6088  	err = json.Unmarshal(bytes, &seccompCopy)
  6089  	if err != nil {
  6090  		panic(err)
  6091  	}
  6092  
  6093  	return seccompCopy
  6094  }
  6095  
  6096  type regoOverlayTestConfig struct {
  6097  	layers      []string
  6098  	containerID string
  6099  	policy      *regoEnforcer
  6100  }
  6101  
  6102  func setupRegoOverlayTest(gc *generatedConstraints, valid bool) (tc *regoOverlayTestConfig, err error) {
  6103  	securityPolicy := gc.toPolicy()
  6104  	policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
  6105  	if err != nil {
  6106  		return nil, err
  6107  	}
  6108  
  6109  	containerID := testDataGenerator.uniqueContainerID()
  6110  	c := selectContainerFromContainerList(gc.containers, testRand)
  6111  
  6112  	var layerPaths []string
  6113  	if valid {
  6114  		layerPaths, err = testDataGenerator.createValidOverlayForContainer(policy, c)
  6115  		if err != nil {
  6116  			return nil, fmt.Errorf("error creating valid overlay: %w", err)
  6117  		}
  6118  	} else {
  6119  		layerPaths, err = testDataGenerator.createInvalidOverlayForContainer(policy, c)
  6120  		if err != nil {
  6121  			return nil, fmt.Errorf("error creating invalid overlay: %w", err)
  6122  		}
  6123  	}
  6124  
  6125  	// see NOTE_TESTCOPY
  6126  	return &regoOverlayTestConfig{
  6127  		layers:      copyStrings(layerPaths),
  6128  		containerID: containerID,
  6129  		policy:      policy,
  6130  	}, nil
  6131  }
  6132  
  6133  type regoContainerTestConfig struct {
  6134  	envList         []string
  6135  	argList         []string
  6136  	workingDir      string
  6137  	containerID     string
  6138  	sandboxID       string
  6139  	mounts          []oci.Mount
  6140  	noNewPrivileges bool
  6141  	user            IDName
  6142  	groups          []IDName
  6143  	umask           string
  6144  	capabilities    *oci.LinuxCapabilities
  6145  	seccomp         string
  6146  	policy          *regoEnforcer
  6147  	ctx             context.Context
  6148  }
  6149  
  6150  func setupSimpleRegoCreateContainerTest(gc *generatedConstraints) (tc *regoContainerTestConfig, err error) {
  6151  	c := selectContainerFromContainerList(gc.containers, testRand)
  6152  	return setupRegoCreateContainerTest(gc, c, false)
  6153  }
  6154  
  6155  func setupRegoPrivilegedMountTest(gc *generatedConstraints) (tc *regoContainerTestConfig, err error) {
  6156  	c := selectContainerFromContainerList(gc.containers, testRand)
  6157  	return setupRegoCreateContainerTest(gc, c, true)
  6158  }
  6159  
  6160  func setupRegoCreateContainerTest(gc *generatedConstraints, testContainer *securityPolicyContainer, privilegedError bool) (tc *regoContainerTestConfig, err error) {
  6161  	securityPolicy := gc.toPolicy()
  6162  	defaultMounts := generateMounts(testRand)
  6163  	privilegedMounts := generateMounts(testRand)
  6164  
  6165  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  6166  		toOCIMounts(defaultMounts),
  6167  		toOCIMounts(privilegedMounts))
  6168  	if err != nil {
  6169  		return nil, err
  6170  	}
  6171  
  6172  	containerID, err := mountImageForContainer(policy, testContainer)
  6173  	if err != nil {
  6174  		return nil, err
  6175  	}
  6176  
  6177  	envList := buildEnvironmentVariablesFromEnvRules(testContainer.EnvRules, testRand)
  6178  	sandboxID := testDataGenerator.uniqueSandboxID()
  6179  
  6180  	mounts := testContainer.Mounts
  6181  	mounts = append(mounts, defaultMounts...)
  6182  	if privilegedError {
  6183  		testContainer.AllowElevated = false
  6184  	}
  6185  
  6186  	if testContainer.AllowElevated || privilegedError {
  6187  		mounts = append(mounts, privilegedMounts...)
  6188  	}
  6189  	mountSpec := buildMountSpecFromMountArray(mounts, sandboxID, testRand)
  6190  
  6191  	user := IDName{}
  6192  	if testContainer.User.UserIDName.Strategy != IDNameStrategyRegex {
  6193  		user = buildIDNameFromConfig(testContainer.User.UserIDName, testRand)
  6194  	}
  6195  	groups := buildGroupIDNamesFromUser(testContainer.User, testRand)
  6196  	umask := testContainer.User.Umask
  6197  
  6198  	var capabilities *oci.LinuxCapabilities
  6199  	if testContainer.Capabilities != nil {
  6200  		capsExternal := copyLinuxCapabilities(testContainer.Capabilities.toExternal())
  6201  		capabilities = &capsExternal
  6202  	} else {
  6203  		capabilities = nil
  6204  	}
  6205  	seccomp := testContainer.SeccompProfileSHA256
  6206  
  6207  	// see NOTE_TESTCOPY
  6208  	return &regoContainerTestConfig{
  6209  		envList:         copyStrings(envList),
  6210  		argList:         copyStrings(testContainer.Command),
  6211  		workingDir:      testContainer.WorkingDir,
  6212  		containerID:     containerID,
  6213  		sandboxID:       sandboxID,
  6214  		mounts:          copyMounts(mountSpec.Mounts),
  6215  		noNewPrivileges: testContainer.NoNewPrivileges,
  6216  		user:            user,
  6217  		groups:          groups,
  6218  		umask:           umask,
  6219  		capabilities:    capabilities,
  6220  		seccomp:         seccomp,
  6221  		policy:          policy,
  6222  		ctx:             gc.ctx,
  6223  	}, nil
  6224  }
  6225  
  6226  func setupRegoRunningContainerTest(gc *generatedConstraints, privileged bool) (tc *regoRunningContainerTestConfig, err error) {
  6227  	securityPolicy := gc.toPolicy()
  6228  	defaultMounts := generateMounts(testRand)
  6229  	privilegedMounts := generateMounts(testRand)
  6230  
  6231  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  6232  		toOCIMounts(defaultMounts),
  6233  		toOCIMounts(privilegedMounts))
  6234  	if err != nil {
  6235  		return nil, err
  6236  	}
  6237  
  6238  	var runningContainers []regoRunningContainer
  6239  	numOfRunningContainers := int(atLeastOneAtMost(testRand, int32(len(gc.containers))))
  6240  	containersToRun := randChoicesWithReplacement(testRand, numOfRunningContainers, len(gc.containers))
  6241  	for _, i := range containersToRun {
  6242  		containerToStart := gc.containers[i]
  6243  		r, err := runContainer(policy, containerToStart, defaultMounts, privilegedMounts, privileged)
  6244  		if err != nil {
  6245  			return nil, err
  6246  		}
  6247  		runningContainers = append(runningContainers, *r)
  6248  	}
  6249  
  6250  	return &regoRunningContainerTestConfig{
  6251  		runningContainers: runningContainers,
  6252  		policy:            policy,
  6253  		defaultMounts:     copyMountsInternal(defaultMounts),
  6254  		privilegedMounts:  copyMountsInternal(privilegedMounts),
  6255  	}, nil
  6256  }
  6257  
  6258  func runContainer(enforcer *regoEnforcer, container *securityPolicyContainer, defaultMounts []mountInternal, privilegedMounts []mountInternal, privileged bool) (*regoRunningContainer, error) {
  6259  	ctx := context.Background()
  6260  	containerID, err := mountImageForContainer(enforcer, container)
  6261  	if err != nil {
  6262  		return nil, err
  6263  	}
  6264  
  6265  	envList := buildEnvironmentVariablesFromEnvRules(container.EnvRules, testRand)
  6266  	user := buildIDNameFromConfig(container.User.UserIDName, testRand)
  6267  	groups := buildGroupIDNamesFromUser(container.User, testRand)
  6268  	umask := container.User.Umask
  6269  	sandboxID := generateSandboxID(testRand)
  6270  
  6271  	mounts := container.Mounts
  6272  	mounts = append(mounts, defaultMounts...)
  6273  	if container.AllowElevated {
  6274  		mounts = append(mounts, privilegedMounts...)
  6275  	}
  6276  	mountSpec := buildMountSpecFromMountArray(mounts, sandboxID, testRand)
  6277  	var capabilities oci.LinuxCapabilities
  6278  	if container.Capabilities == nil {
  6279  		if privileged {
  6280  			capabilities = capabilitiesInternal{
  6281  				Bounding:    DefaultPrivilegedCapabilities(),
  6282  				Inheritable: DefaultPrivilegedCapabilities(),
  6283  				Effective:   DefaultPrivilegedCapabilities(),
  6284  				Permitted:   DefaultPrivilegedCapabilities(),
  6285  				Ambient:     []string{},
  6286  			}.toExternal()
  6287  		} else {
  6288  			capabilities = capabilitiesInternal{
  6289  				Bounding:    DefaultUnprivilegedCapabilities(),
  6290  				Inheritable: []string{},
  6291  				Effective:   DefaultUnprivilegedCapabilities(),
  6292  				Permitted:   DefaultUnprivilegedCapabilities(),
  6293  				Ambient:     []string{},
  6294  			}.toExternal()
  6295  		}
  6296  	} else {
  6297  		capabilities = container.Capabilities.toExternal()
  6298  	}
  6299  	seccomp := container.SeccompProfileSHA256
  6300  
  6301  	_, _, _, err = enforcer.EnforceCreateContainerPolicy(ctx, sandboxID, containerID, container.Command, envList, container.WorkingDir, mountSpec.Mounts, privileged, container.NoNewPrivileges, user, groups, umask, &capabilities, seccomp)
  6302  	if err != nil {
  6303  		return nil, err
  6304  	}
  6305  
  6306  	return &regoRunningContainer{
  6307  		container:   container,
  6308  		envList:     envList,
  6309  		containerID: containerID,
  6310  	}, nil
  6311  }
  6312  
  6313  type regoRunningContainerTestConfig struct {
  6314  	runningContainers []regoRunningContainer
  6315  	policy            *regoEnforcer
  6316  	defaultMounts     []mountInternal
  6317  	privilegedMounts  []mountInternal
  6318  }
  6319  
  6320  type regoRunningContainer struct {
  6321  	container   *securityPolicyContainer
  6322  	envList     []string
  6323  	containerID string
  6324  }
  6325  
  6326  func setupExternalProcessTest(gc *generatedConstraints) (tc *regoExternalPolicyTestConfig, err error) {
  6327  	gc.externalProcesses = generateExternalProcesses(testRand)
  6328  	securityPolicy := gc.toPolicy()
  6329  	defaultMounts := generateMounts(testRand)
  6330  	privilegedMounts := generateMounts(testRand)
  6331  
  6332  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  6333  		toOCIMounts(defaultMounts),
  6334  		toOCIMounts(privilegedMounts))
  6335  	if err != nil {
  6336  		return nil, err
  6337  	}
  6338  
  6339  	return &regoExternalPolicyTestConfig{
  6340  		policy: policy,
  6341  	}, nil
  6342  }
  6343  
  6344  type regoExternalPolicyTestConfig struct {
  6345  	policy *regoEnforcer
  6346  }
  6347  
  6348  func setupPlan9MountTest(gc *generatedConstraints) (tc *regoPlan9MountTestConfig, err error) {
  6349  	securityPolicy := gc.toPolicy()
  6350  	defaultMounts := generateMounts(testRand)
  6351  	privilegedMounts := generateMounts(testRand)
  6352  
  6353  	testContainer := selectContainerFromContainerList(gc.containers, testRand)
  6354  	mountIndex := atMost(testRand, int32(len(testContainer.Mounts)-1))
  6355  	testMount := &testContainer.Mounts[mountIndex]
  6356  	testMount.Source = plan9Prefix
  6357  	testMount.Type = "secret"
  6358  
  6359  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  6360  		toOCIMounts(defaultMounts),
  6361  		toOCIMounts(privilegedMounts))
  6362  	if err != nil {
  6363  		return nil, err
  6364  	}
  6365  
  6366  	containerID, err := mountImageForContainer(policy, testContainer)
  6367  	if err != nil {
  6368  		return nil, err
  6369  	}
  6370  
  6371  	uvmPathForShare := generateUVMPathForShare(testRand, containerID)
  6372  
  6373  	envList := buildEnvironmentVariablesFromEnvRules(testContainer.EnvRules, testRand)
  6374  	sandboxID := testDataGenerator.uniqueSandboxID()
  6375  
  6376  	mounts := testContainer.Mounts
  6377  	mounts = append(mounts, defaultMounts...)
  6378  
  6379  	if testContainer.AllowElevated {
  6380  		mounts = append(mounts, privilegedMounts...)
  6381  	}
  6382  	mountSpec := buildMountSpecFromMountArray(mounts, sandboxID, testRand)
  6383  	mountSpec.Mounts = append(mountSpec.Mounts, oci.Mount{
  6384  		Source:      uvmPathForShare,
  6385  		Destination: testMount.Destination,
  6386  		Options:     testMount.Options,
  6387  		Type:        testMount.Type,
  6388  	})
  6389  
  6390  	user := buildIDNameFromConfig(testContainer.User.UserIDName, testRand)
  6391  	groups := buildGroupIDNamesFromUser(testContainer.User, testRand)
  6392  	umask := testContainer.User.Umask
  6393  
  6394  	capabilities := testContainer.Capabilities.toExternal()
  6395  	seccomp := testContainer.SeccompProfileSHA256
  6396  
  6397  	// see NOTE_TESTCOPY
  6398  	return &regoPlan9MountTestConfig{
  6399  		envList:         copyStrings(envList),
  6400  		argList:         copyStrings(testContainer.Command),
  6401  		workingDir:      testContainer.WorkingDir,
  6402  		containerID:     containerID,
  6403  		sandboxID:       sandboxID,
  6404  		mounts:          copyMounts(mountSpec.Mounts),
  6405  		noNewPrivileges: testContainer.NoNewPrivileges,
  6406  		user:            user,
  6407  		groups:          groups,
  6408  		umask:           umask,
  6409  		uvmPathForShare: uvmPathForShare,
  6410  		policy:          policy,
  6411  		capabilities:    &capabilities,
  6412  		seccomp:         seccomp,
  6413  	}, nil
  6414  }
  6415  
  6416  type regoPlan9MountTestConfig struct {
  6417  	envList         []string
  6418  	argList         []string
  6419  	workingDir      string
  6420  	containerID     string
  6421  	sandboxID       string
  6422  	mounts          []oci.Mount
  6423  	uvmPathForShare string
  6424  	noNewPrivileges bool
  6425  	user            IDName
  6426  	groups          []IDName
  6427  	umask           string
  6428  	policy          *regoEnforcer
  6429  	capabilities    *oci.LinuxCapabilities
  6430  	seccomp         string
  6431  }
  6432  
  6433  func setupGetPropertiesTest(gc *generatedConstraints, allowPropertiesAccess bool) (tc *regoGetPropertiesTestConfig, err error) {
  6434  	gc.allowGetProperties = allowPropertiesAccess
  6435  
  6436  	securityPolicy := gc.toPolicy()
  6437  	defaultMounts := generateMounts(testRand)
  6438  	privilegedMounts := generateMounts(testRand)
  6439  
  6440  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  6441  		toOCIMounts(defaultMounts),
  6442  		toOCIMounts(privilegedMounts))
  6443  	if err != nil {
  6444  		return nil, err
  6445  	}
  6446  
  6447  	return &regoGetPropertiesTestConfig{
  6448  		policy: policy,
  6449  	}, nil
  6450  }
  6451  
  6452  type regoGetPropertiesTestConfig struct {
  6453  	policy *regoEnforcer
  6454  }
  6455  
  6456  func setupDumpStacksTest(constraints *generatedConstraints, allowDumpStacks bool) (tc *regoGetPropertiesTestConfig, err error) {
  6457  	constraints.allowDumpStacks = allowDumpStacks
  6458  
  6459  	securityPolicy := constraints.toPolicy()
  6460  	defaultMounts := generateMounts(testRand)
  6461  	privilegedMounts := generateMounts(testRand)
  6462  
  6463  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  6464  		toOCIMounts(defaultMounts),
  6465  		toOCIMounts(privilegedMounts))
  6466  	if err != nil {
  6467  		return nil, err
  6468  	}
  6469  
  6470  	return &regoGetPropertiesTestConfig{
  6471  		policy: policy,
  6472  	}, nil
  6473  }
  6474  
  6475  type regoDumpStacksTestConfig struct {
  6476  	policy *regoEnforcer
  6477  }
  6478  
  6479  func mountImageForContainer(policy *regoEnforcer, container *securityPolicyContainer) (string, error) {
  6480  	ctx := context.Background()
  6481  	containerID := testDataGenerator.uniqueContainerID()
  6482  
  6483  	layerPaths, err := testDataGenerator.createValidOverlayForContainer(policy, container)
  6484  	if err != nil {
  6485  		return "", fmt.Errorf("error creating valid overlay: %w", err)
  6486  	}
  6487  
  6488  	// see NOTE_TESTCOPY
  6489  	err = policy.EnforceOverlayMountPolicy(ctx, containerID, copyStrings(layerPaths), testDataGenerator.uniqueMountTarget())
  6490  	if err != nil {
  6491  		return "", fmt.Errorf("error mounting filesystem: %w", err)
  6492  	}
  6493  
  6494  	return containerID, nil
  6495  }
  6496  
  6497  type regoPolicyOnlyTestConfig struct {
  6498  	policy *regoEnforcer
  6499  }
  6500  
  6501  func setupRegoPolicyOnlyTest(gc *generatedConstraints) (tc *regoPolicyOnlyTestConfig, err error) {
  6502  	securityPolicy := gc.toPolicy()
  6503  	policy, err := newRegoPolicy(securityPolicy.marshalRego(), []oci.Mount{}, []oci.Mount{})
  6504  	if err != nil {
  6505  		return nil, err
  6506  	}
  6507  
  6508  	// see NOTE_TESTCOPY
  6509  	return &regoPolicyOnlyTestConfig{
  6510  		policy: policy,
  6511  	}, nil
  6512  }
  6513  
  6514  type regoFragmentTestConfig struct {
  6515  	fragments         []*regoFragment
  6516  	containers        []*regoFragmentContainer
  6517  	externalProcesses []*externalProcess
  6518  	subFragments      []*regoFragment
  6519  	plan9Mounts       []string
  6520  	mountSpec         []string
  6521  	policy            *regoEnforcer
  6522  }
  6523  
  6524  type regoFragmentContainer struct {
  6525  	container    *securityPolicyContainer
  6526  	envList      []string
  6527  	sandboxID    string
  6528  	mounts       []oci.Mount
  6529  	user         IDName
  6530  	groups       []IDName
  6531  	capabilities *oci.LinuxCapabilities
  6532  	seccomp      string
  6533  }
  6534  
  6535  func setupSimpleRegoFragmentTestConfig(gc *generatedConstraints) (*regoFragmentTestConfig, error) {
  6536  	return setupRegoFragmentTestConfig(gc, 1, []string{"containers"}, []string{}, false, false, false, false)
  6537  }
  6538  
  6539  func setupRegoFragmentTestConfigWithIncludes(gc *generatedConstraints, includes []string) (*regoFragmentTestConfig, error) {
  6540  	return setupRegoFragmentTestConfig(gc, 1, includes, []string{}, false, false, false, false)
  6541  }
  6542  
  6543  func setupRegoFragmentTestConfigWithExcludes(gc *generatedConstraints, excludes []string) (*regoFragmentTestConfig, error) {
  6544  	return setupRegoFragmentTestConfig(gc, 1, []string{}, excludes, false, false, false, false)
  6545  }
  6546  
  6547  func setupRegoFragmentSVNErrorTestConfig(gc *generatedConstraints) (*regoFragmentTestConfig, error) {
  6548  	return setupRegoFragmentTestConfig(gc, 1, []string{"containers"}, []string{}, true, false, false, false)
  6549  }
  6550  
  6551  func setupRegoSubfragmentSVNErrorTestConfig(gc *generatedConstraints) (*regoFragmentTestConfig, error) {
  6552  	return setupRegoFragmentTestConfig(gc, 1, []string{"fragments"}, []string{}, true, false, false, false)
  6553  }
  6554  
  6555  func setupRegoFragmentTwoFeedTestConfig(gc *generatedConstraints, sameIssuer bool, sameFeed bool) (*regoFragmentTestConfig, error) {
  6556  	return setupRegoFragmentTestConfig(gc, 2, []string{"containers"}, []string{}, false, sameIssuer, sameFeed, false)
  6557  }
  6558  
  6559  func setupRegoFragmentSVNMismatchTestConfig(gc *generatedConstraints) (*regoFragmentTestConfig, error) {
  6560  	return setupRegoFragmentTestConfig(gc, 2, []string{"containers"}, []string{}, false, false, false, true)
  6561  }
  6562  
  6563  func compareSVNs(lhs string, rhs string) int {
  6564  	lhs_int, err := strconv.Atoi(lhs)
  6565  	if err == nil {
  6566  		rhs_int, err := strconv.Atoi(rhs)
  6567  		if err == nil {
  6568  			return lhs_int - rhs_int
  6569  		}
  6570  	}
  6571  
  6572  	panic("unable to compare SVNs")
  6573  }
  6574  
  6575  func setupRegoFragmentTestConfig(gc *generatedConstraints, numFragments int, includes []string, excludes []string, svnError bool, sameIssuer bool, sameFeed bool, svnMismatch bool) (tc *regoFragmentTestConfig, err error) {
  6576  	gc.fragments = generateFragments(testRand, int32(numFragments))
  6577  
  6578  	if sameIssuer {
  6579  		for _, fragment := range gc.fragments {
  6580  			fragment.issuer = gc.fragments[0].issuer
  6581  			if sameFeed {
  6582  				fragment.feed = gc.fragments[0].feed
  6583  			}
  6584  		}
  6585  	}
  6586  
  6587  	subSVNError := svnError
  6588  	if len(includes) > 0 && includes[0] == "fragments" {
  6589  		svnError = false
  6590  	}
  6591  	fragments := selectFragmentsFromConstraints(gc, numFragments, includes, excludes, svnError, frameworkVersion, svnMismatch)
  6592  
  6593  	containers := make([]*regoFragmentContainer, numFragments)
  6594  	subFragments := make([]*regoFragment, numFragments)
  6595  	externalProcesses := make([]*externalProcess, numFragments)
  6596  	plan9Mounts := make([]string, numFragments)
  6597  	for i, fragment := range fragments {
  6598  		container := fragment.selectContainer()
  6599  
  6600  		envList := buildEnvironmentVariablesFromEnvRules(container.EnvRules, testRand)
  6601  		sandboxID := testDataGenerator.uniqueSandboxID()
  6602  		user := buildIDNameFromConfig(container.User.UserIDName, testRand)
  6603  		groups := buildGroupIDNamesFromUser(container.User, testRand)
  6604  		capabilities := copyLinuxCapabilities(container.Capabilities.toExternal())
  6605  		seccomp := container.SeccompProfileSHA256
  6606  
  6607  		mounts := container.Mounts
  6608  		mountSpec := buildMountSpecFromMountArray(mounts, sandboxID, testRand)
  6609  		containers[i] = &regoFragmentContainer{
  6610  			container:    container,
  6611  			envList:      envList,
  6612  			sandboxID:    sandboxID,
  6613  			mounts:       mountSpec.Mounts,
  6614  			user:         user,
  6615  			groups:       groups,
  6616  			capabilities: &capabilities,
  6617  			seccomp:      seccomp,
  6618  		}
  6619  
  6620  		for _, include := range fragment.info.includes {
  6621  			switch include {
  6622  			case "fragments":
  6623  				subFragments[i] = selectFragmentsFromConstraints(fragment.constraints, 1, []string{"containers"}, []string{}, subSVNError, frameworkVersion, false)[0]
  6624  				break
  6625  
  6626  			case "external_processes":
  6627  				externalProcesses[i] = selectExternalProcessFromConstraints(fragment.constraints, testRand)
  6628  				break
  6629  			}
  6630  		}
  6631  
  6632  		// now that we've explicitly added the excluded items to the fragment
  6633  		// we remove the include string so that the generated policy
  6634  		// does not include them.
  6635  		fragment.info.includes = removeStringsFromArray(fragment.info.includes, excludes)
  6636  
  6637  		code := fragment.constraints.toFragment().marshalRego()
  6638  		fragment.code = setFrameworkVersion(code, frameworkVersion)
  6639  	}
  6640  
  6641  	if sameFeed {
  6642  		includeSet := make(map[string]bool)
  6643  		minSVN := strconv.Itoa(maxGeneratedVersion)
  6644  		for _, fragment := range gc.fragments {
  6645  			svn := fragment.minimumSVN
  6646  			if compareSVNs(svn, minSVN) < 0 {
  6647  				minSVN = svn
  6648  			}
  6649  			for _, include := range fragment.includes {
  6650  				includeSet[include] = true
  6651  			}
  6652  		}
  6653  		frag := gc.fragments[0]
  6654  		frag.minimumSVN = minSVN
  6655  		frag.includes = make([]string, 0, len(includeSet))
  6656  		for include := range includeSet {
  6657  			frag.includes = append(frag.includes, include)
  6658  		}
  6659  
  6660  		gc.fragments = []*fragment{frag}
  6661  
  6662  	}
  6663  
  6664  	securityPolicy := gc.toPolicy()
  6665  	defaultMounts := toOCIMounts(generateMounts(testRand))
  6666  	privilegedMounts := toOCIMounts(generateMounts(testRand))
  6667  	policy, err := newRegoPolicy(securityPolicy.marshalRego(), defaultMounts, privilegedMounts)
  6668  
  6669  	if err != nil {
  6670  		return nil, err
  6671  	}
  6672  
  6673  	return &regoFragmentTestConfig{
  6674  		fragments:         fragments,
  6675  		containers:        containers,
  6676  		subFragments:      subFragments,
  6677  		externalProcesses: externalProcesses,
  6678  		plan9Mounts:       plan9Mounts,
  6679  		policy:            policy,
  6680  	}, nil
  6681  }
  6682  
  6683  type regoDropEnvsTestConfig struct {
  6684  	envList      []string
  6685  	expected     []string
  6686  	argList      []string
  6687  	workingDir   string
  6688  	containerID  string
  6689  	sandboxID    string
  6690  	mounts       []oci.Mount
  6691  	policy       *regoEnforcer
  6692  	capabilities oci.LinuxCapabilities
  6693  }
  6694  
  6695  func setupEnvRuleSets(count int) [][]EnvRuleConfig {
  6696  	numEnvRules := []int{int(randMinMax(testRand, 1, 4)),
  6697  		int(randMinMax(testRand, 1, 4)),
  6698  		int(randMinMax(testRand, 1, 4))}
  6699  	envRuleLookup := make(stringSet)
  6700  	envRules := make([][]EnvRuleConfig, count)
  6701  
  6702  	for i := 0; i < count; i++ {
  6703  		rules := envRuleLookup.randUniqueArray(testRand, func(r *rand.Rand) string {
  6704  			return randVariableString(r, 10)
  6705  		}, int32(numEnvRules[i]))
  6706  
  6707  		envRules[i] = make([]EnvRuleConfig, numEnvRules[i])
  6708  		for j, rule := range rules {
  6709  			envRules[i][j] = EnvRuleConfig{
  6710  				Strategy: "string",
  6711  				Rule:     rule,
  6712  			}
  6713  		}
  6714  	}
  6715  
  6716  	return envRules
  6717  }
  6718  
  6719  func setupRegoDropEnvsTest(disjoint bool) (*regoContainerTestConfig, error) {
  6720  	gc := generateConstraints(testRand, 1)
  6721  	gc.allowEnvironmentVariableDropping = true
  6722  
  6723  	const numContainers int = 3
  6724  	envRules := setupEnvRuleSets(numContainers)
  6725  	containers := make([]*securityPolicyContainer, numContainers)
  6726  	envs := make([][]string, numContainers)
  6727  
  6728  	for i := 0; i < numContainers; i++ {
  6729  		c, err := gc.containers[0].clone()
  6730  		if err != nil {
  6731  			return nil, err
  6732  		}
  6733  		containers[i] = c
  6734  		envs[i] = buildEnvironmentVariablesFromEnvRules(envRules[i], testRand)
  6735  		if i == 0 {
  6736  			c.EnvRules = envRules[i]
  6737  		} else if disjoint {
  6738  			c.EnvRules = append(envRules[0], envRules[i]...)
  6739  		} else {
  6740  			c.EnvRules = append(containers[i-1].EnvRules, envRules[i]...)
  6741  		}
  6742  	}
  6743  
  6744  	gc.containers = containers
  6745  	securityPolicy := gc.toPolicy()
  6746  	defaultMounts := generateMounts(testRand)
  6747  	privilegedMounts := generateMounts(testRand)
  6748  
  6749  	policy, err := newRegoPolicy(securityPolicy.marshalRego(),
  6750  		toOCIMounts(defaultMounts),
  6751  		toOCIMounts(privilegedMounts))
  6752  
  6753  	if err != nil {
  6754  		return nil, err
  6755  	}
  6756  
  6757  	containerIDs := make([]string, numContainers)
  6758  	for i, c := range gc.containers {
  6759  		containerID, err := mountImageForContainer(policy, c)
  6760  		if err != nil {
  6761  			return nil, err
  6762  		}
  6763  
  6764  		containerIDs[i] = containerID
  6765  	}
  6766  
  6767  	var envList []string
  6768  	if disjoint {
  6769  		var extraLen int
  6770  		if len(envs[1]) < len(envs[2]) {
  6771  			extraLen = len(envs[1])
  6772  		} else {
  6773  			extraLen = len(envs[2])
  6774  		}
  6775  		envList = append(envs[0], envs[1][:extraLen]...)
  6776  		envList = append(envList, envs[2][:extraLen]...)
  6777  	} else {
  6778  		envList = append(envs[0], envs[1]...)
  6779  		envList = append(envList, envs[2]...)
  6780  	}
  6781  
  6782  	user := buildIDNameFromConfig(containers[2].User.UserIDName, testRand)
  6783  	groups := buildGroupIDNamesFromUser(containers[2].User, testRand)
  6784  	umask := containers[2].User.Umask
  6785  
  6786  	sandboxID := testDataGenerator.uniqueSandboxID()
  6787  
  6788  	mounts := containers[2].Mounts
  6789  	mounts = append(mounts, defaultMounts...)
  6790  	if containers[2].AllowElevated {
  6791  		mounts = append(mounts, privilegedMounts...)
  6792  	}
  6793  
  6794  	mountSpec := buildMountSpecFromMountArray(mounts, sandboxID, testRand)
  6795  	capabilities := copyLinuxCapabilities(containers[2].Capabilities.toExternal())
  6796  	seccomp := containers[2].SeccompProfileSHA256
  6797  
  6798  	// see NOTE_TESTCOPY
  6799  	return &regoContainerTestConfig{
  6800  		envList:         copyStrings(envList),
  6801  		argList:         copyStrings(containers[2].Command),
  6802  		workingDir:      containers[2].WorkingDir,
  6803  		containerID:     containerIDs[2],
  6804  		sandboxID:       sandboxID,
  6805  		mounts:          copyMounts(mountSpec.Mounts),
  6806  		noNewPrivileges: containers[2].NoNewPrivileges,
  6807  		user:            user,
  6808  		groups:          groups,
  6809  		umask:           umask,
  6810  		policy:          policy,
  6811  		capabilities:    &capabilities,
  6812  		seccomp:         seccomp,
  6813  		ctx:             gc.ctx,
  6814  	}, nil
  6815  }
  6816  
  6817  type regoFrameworkVersionTestConfig struct {
  6818  	policy    *regoEnforcer
  6819  	fragments []*regoFragment
  6820  }
  6821  
  6822  func setFrameworkVersion(code string, version string) string {
  6823  	template := `framework_version := "%s"`
  6824  	old := fmt.Sprintf(template, frameworkVersion)
  6825  	if version == "" {
  6826  		return strings.Replace(code, old, "", 1)
  6827  	}
  6828  
  6829  	new := fmt.Sprintf(template, version)
  6830  	return strings.Replace(code, old, new, 1)
  6831  }
  6832  
  6833  func setupFrameworkVersionSimpleTest(gc *generatedConstraints, policyVersion string, version string) (*regoFrameworkVersionTestConfig, error) {
  6834  	return setupFrameworkVersionTest(gc, policyVersion, version, 0, "", []string{})
  6835  }
  6836  
  6837  func setupFrameworkVersionTest(gc *generatedConstraints, policyVersion string, version string, numFragments int, fragmentVersion string, includes []string) (*regoFrameworkVersionTestConfig, error) {
  6838  	fragments := make([]*regoFragment, 0, numFragments)
  6839  	if numFragments > 0 {
  6840  		gc.fragments = generateFragments(testRand, int32(numFragments))
  6841  		fragments = selectFragmentsFromConstraints(gc, numFragments, includes, []string{}, false, fragmentVersion, false)
  6842  	}
  6843  
  6844  	securityPolicy := gc.toPolicy()
  6845  	policy, err := newRegoPolicy(setFrameworkVersion(securityPolicy.marshalRego(), policyVersion), []oci.Mount{}, []oci.Mount{})
  6846  	if err != nil {
  6847  		return nil, err
  6848  	}
  6849  
  6850  	code := strings.Replace(frameworkCodeTemplate, "@@FRAMEWORK_VERSION@@", version, 1)
  6851  	policy.rego.RemoveModule("framework.rego")
  6852  	policy.rego.AddModule("framework.rego", &rpi.RegoModule{Namespace: "framework", Code: code})
  6853  	err = policy.rego.Compile()
  6854  	if err != nil {
  6855  		return nil, err
  6856  	}
  6857  
  6858  	return &regoFrameworkVersionTestConfig{policy: policy, fragments: fragments}, nil
  6859  }
  6860  
  6861  type regoFragment struct {
  6862  	info        *fragment
  6863  	constraints *generatedConstraints
  6864  	code        string
  6865  }
  6866  
  6867  func (f *regoFragment) selectContainer() *securityPolicyContainer {
  6868  	return selectContainerFromContainerList(f.constraints.containers, testRand)
  6869  }
  6870  
  6871  func mustIncrementSVN(svn string) string {
  6872  	svn_semver, err := semver.Parse(svn)
  6873  
  6874  	if err == nil {
  6875  		svn_semver.IncrementMajor()
  6876  		return svn_semver.String()
  6877  	}
  6878  
  6879  	svn_int, err := strconv.Atoi(svn)
  6880  
  6881  	if err == nil {
  6882  		return strconv.Itoa(svn_int + 1)
  6883  	}
  6884  
  6885  	panic("Could not increment SVN")
  6886  }
  6887  
  6888  func selectFragmentsFromConstraints(gc *generatedConstraints, numFragments int, includes []string, excludes []string, svnError bool, frameworkVersion string, svnMismatch bool) []*regoFragment {
  6889  	choices := randChoices(testRand, numFragments, len(gc.fragments))
  6890  	fragments := make([]*regoFragment, numFragments)
  6891  	for i, choice := range choices {
  6892  		config := gc.fragments[choice]
  6893  		config.includes = addStringsToArray(config.includes, includes)
  6894  		// since we want to test that the policy cannot include an excluded
  6895  		// quantity, we must first ensure they are in the fragment
  6896  		config.includes = addStringsToArray(config.includes, excludes)
  6897  
  6898  		constraints := generateConstraints(testRand, maxContainersInGeneratedConstraints)
  6899  		for _, include := range config.includes {
  6900  			switch include {
  6901  			case "fragments":
  6902  				constraints.fragments = generateFragments(testRand, 1)
  6903  				for _, fragment := range constraints.fragments {
  6904  					fragment.includes = addStringsToArray(fragment.includes, []string{"containers"})
  6905  				}
  6906  				break
  6907  
  6908  			case "external_processes":
  6909  				constraints.externalProcesses = generateExternalProcesses(testRand)
  6910  				break
  6911  			}
  6912  		}
  6913  
  6914  		svn := config.minimumSVN
  6915  		if svnMismatch {
  6916  			if randBool(testRand) {
  6917  				svn = generateSemver(testRand)
  6918  			} else {
  6919  				config.minimumSVN = generateSemver(testRand)
  6920  			}
  6921  		}
  6922  
  6923  		constraints.svn = svn
  6924  		if svnError {
  6925  			config.minimumSVN = mustIncrementSVN(config.minimumSVN)
  6926  		}
  6927  
  6928  		code := constraints.toFragment().marshalRego()
  6929  		code = setFrameworkVersion(code, frameworkVersion)
  6930  
  6931  		fragments[i] = &regoFragment{
  6932  			info:        config,
  6933  			constraints: constraints,
  6934  			code:        code,
  6935  		}
  6936  	}
  6937  
  6938  	return fragments
  6939  }
  6940  
  6941  func generateSandboxID(r *rand.Rand) string {
  6942  	return randVariableString(r, maxGeneratedSandboxIDLength)
  6943  }
  6944  
  6945  func generateEnforcementPoint(r *rand.Rand) string {
  6946  	first := randChar(r)
  6947  	return first + randString(r, atMost(r, maxGeneratedEnforcementPointLength))
  6948  }
  6949  
  6950  func (gen *dataGenerator) uniqueSandboxID() string {
  6951  	return gen.sandboxIDs.randUnique(gen.rng, generateSandboxID)
  6952  }
  6953  
  6954  func (gen *dataGenerator) uniqueEnforcementPoint() string {
  6955  	return gen.enforcementPoints.randUnique(gen.rng, generateEnforcementPoint)
  6956  }
  6957  
  6958  func buildMountSpecFromMountArray(mounts []mountInternal, sandboxID string, r *rand.Rand) *oci.Spec {
  6959  	mountSpec := new(oci.Spec)
  6960  
  6961  	// Select some number of the valid, matching rules to be environment
  6962  	// variable
  6963  	numberOfMounts := int32(len(mounts))
  6964  	numberOfMatches := randMinMax(r, 1, numberOfMounts)
  6965  	usedIndexes := map[int]struct{}{}
  6966  	for numberOfMatches > 0 {
  6967  		anIndex := -1
  6968  		if (numberOfMatches * 2) > numberOfMounts {
  6969  			// if we have a lot of matches, randomly select
  6970  			exists := true
  6971  
  6972  			for exists {
  6973  				anIndex = int(randMinMax(r, 0, numberOfMounts-1))
  6974  				_, exists = usedIndexes[anIndex]
  6975  			}
  6976  		} else {
  6977  			// we have a "smaller set of rules. we'll just iterate and select from
  6978  			// available
  6979  			exists := true
  6980  
  6981  			for exists {
  6982  				anIndex++
  6983  				_, exists = usedIndexes[anIndex]
  6984  			}
  6985  		}
  6986  
  6987  		mount := mounts[anIndex]
  6988  
  6989  		source := substituteUVMPath(sandboxID, mount).Source
  6990  		mountSpec.Mounts = append(mountSpec.Mounts, oci.Mount{
  6991  			Source:      source,
  6992  			Destination: mount.Destination,
  6993  			Options:     mount.Options,
  6994  			Type:        mount.Type,
  6995  		})
  6996  		usedIndexes[anIndex] = struct{}{}
  6997  
  6998  		numberOfMatches--
  6999  	}
  7000  
  7001  	return mountSpec
  7002  }
  7003  
  7004  //go:embed api_test.rego
  7005  var apiTestCode string
  7006  
  7007  func (p *regoEnforcer) injectTestAPI() error {
  7008  	p.rego.RemoveModule("api.rego")
  7009  	p.rego.AddModule("api.rego", &rpi.RegoModule{Namespace: "api", Code: apiTestCode})
  7010  
  7011  	return p.rego.Compile()
  7012  }
  7013  
  7014  func selectContainerFromRunningContainers(containers []regoRunningContainer, r *rand.Rand) regoRunningContainer {
  7015  	numContainers := len(containers)
  7016  	return containers[r.Intn(numContainers)]
  7017  }
  7018  
  7019  func selectExecProcess(processes []containerExecProcess, r *rand.Rand) containerExecProcess {
  7020  	numProcesses := len(processes)
  7021  	return processes[r.Intn(numProcesses)]
  7022  }
  7023  
  7024  func idForRunningContainer(container *securityPolicyContainer, running []regoRunningContainer) (string, error) {
  7025  	for _, c := range running {
  7026  		if c.container == container {
  7027  			return c.containerID, nil
  7028  		}
  7029  	}
  7030  
  7031  	return "", errors.New("Container isn't running")
  7032  }
  7033  
  7034  func selectSignalFromSignals(r *rand.Rand, signals []syscall.Signal) syscall.Signal {
  7035  	numSignals := len(signals)
  7036  	return signals[r.Intn(numSignals)]
  7037  }
  7038  
  7039  func generateUVMPathForShare(r *rand.Rand, containerID string) string {
  7040  	return fmt.Sprintf("%s/%s%s",
  7041  		guestpath.LCOWRootPrefixInUVM,
  7042  		containerID,
  7043  		fmt.Sprintf(guestpath.LCOWMountPathPrefixFmt, atMost(r, maxPlan9MountIndex)))
  7044  }
  7045  
  7046  func generateFragments(r *rand.Rand, minFragments int32) []*fragment {
  7047  	numFragments := randMinMax(r, minFragments, maxFragmentsInGeneratedConstraints)
  7048  
  7049  	fragments := make([]*fragment, numFragments)
  7050  	for i := 0; i < int(numFragments); i++ {
  7051  		fragments[i] = generateFragment(r)
  7052  	}
  7053  
  7054  	return fragments
  7055  }
  7056  
  7057  func generateFragmentIssuer(r *rand.Rand) string {
  7058  	return randString(r, maxGeneratedFragmentIssuerLength)
  7059  }
  7060  
  7061  func generateFragmentFeed(r *rand.Rand) string {
  7062  	return randString(r, maxGeneratedFragmentFeedLength)
  7063  }
  7064  
  7065  func (gen *dataGenerator) uniqueFragmentNamespace() string {
  7066  	return gen.fragmentNamespaces.randUnique(gen.rng, generateFragmentNamespace)
  7067  }
  7068  
  7069  func (gen *dataGenerator) uniqueFragmentIssuer() string {
  7070  	return gen.fragmentIssuers.randUnique(gen.rng, generateFragmentIssuer)
  7071  }
  7072  
  7073  func (gen *dataGenerator) uniqueFragmentFeed() string {
  7074  	return gen.fragmentFeeds.randUnique(gen.rng, generateFragmentFeed)
  7075  }
  7076  
  7077  func generateFragment(r *rand.Rand) *fragment {
  7078  	possibleIncludes := []string{"containers", "fragments", "external_processes"}
  7079  	numChoices := int(atLeastOneAtMost(r, int32(len(possibleIncludes))))
  7080  	includes := randChooseStrings(r, possibleIncludes, numChoices)
  7081  	return &fragment{
  7082  		issuer:     testDataGenerator.uniqueFragmentIssuer(),
  7083  		feed:       testDataGenerator.uniqueFragmentFeed(),
  7084  		minimumSVN: generateSVN(r),
  7085  		includes:   includes,
  7086  	}
  7087  }
  7088  
  7089  func generateLinuxID(r *rand.Rand) uint32 {
  7090  	return r.Uint32()
  7091  }
  7092  
  7093  func addStringsToArray(values []string, valuesToAdd []string) []string {
  7094  	toAdd := []string{}
  7095  	for _, valueToAdd := range valuesToAdd {
  7096  		add := true
  7097  		for _, value := range values {
  7098  			if value == valueToAdd {
  7099  				add = false
  7100  				break
  7101  			}
  7102  		}
  7103  		if add {
  7104  			toAdd = append(toAdd, valueToAdd)
  7105  		}
  7106  	}
  7107  
  7108  	return append(values, toAdd...)
  7109  }
  7110  
  7111  func removeStringsFromArray(values []string, valuesToRemove []string) []string {
  7112  	remain := make([]string, 0, len(values))
  7113  	for _, value := range values {
  7114  		keep := true
  7115  		for _, toRemove := range valuesToRemove {
  7116  			if value == toRemove {
  7117  				keep = false
  7118  				break
  7119  			}
  7120  		}
  7121  		if keep {
  7122  			remain = append(remain, value)
  7123  		}
  7124  	}
  7125  
  7126  	return remain
  7127  }
  7128  
  7129  func areStringArraysEqual(lhs []string, rhs []string) bool {
  7130  	if len(lhs) != len(rhs) {
  7131  		return false
  7132  	}
  7133  
  7134  	sort.Strings(lhs)
  7135  	sort.Strings(rhs)
  7136  
  7137  	for i, a := range lhs {
  7138  		if a != rhs[i] {
  7139  			return false
  7140  		}
  7141  	}
  7142  
  7143  	return true
  7144  }
  7145  
  7146  func (c securityPolicyContainer) clone() (*securityPolicyContainer, error) {
  7147  	contents, err := json.Marshal(c)
  7148  	if err != nil {
  7149  		return nil, err
  7150  	}
  7151  
  7152  	var clone securityPolicyContainer
  7153  	err = json.Unmarshal(contents, &clone)
  7154  	if err != nil {
  7155  		return nil, err
  7156  	}
  7157  
  7158  	return &clone, nil
  7159  }
  7160  
  7161  func (p externalProcess) clone() *externalProcess {
  7162  	envRules := make([]EnvRuleConfig, len(p.envRules))
  7163  	copy(envRules, p.envRules)
  7164  
  7165  	return &externalProcess{
  7166  		command:          copyStrings(p.command),
  7167  		envRules:         envRules,
  7168  		workingDir:       p.workingDir,
  7169  		allowStdioAccess: p.allowStdioAccess,
  7170  	}
  7171  }
  7172  
  7173  func (p containerExecProcess) clone() containerExecProcess {
  7174  	return containerExecProcess{
  7175  		Command: copyStrings(p.Command),
  7176  		Signals: p.Signals,
  7177  	}
  7178  }
  7179  
  7180  func (c *securityPolicyContainer) toContainer() *Container {
  7181  	execProcesses := make([]ExecProcessConfig, len(c.ExecProcesses))
  7182  	for i, ep := range c.ExecProcesses {
  7183  		execProcesses[i] = ExecProcessConfig(ep)
  7184  	}
  7185  
  7186  	capabilities := CapabilitiesConfig{
  7187  		Bounding:    c.Capabilities.Bounding,
  7188  		Effective:   c.Capabilities.Effective,
  7189  		Inheritable: c.Capabilities.Inheritable,
  7190  		Permitted:   c.Capabilities.Permitted,
  7191  		Ambient:     c.Capabilities.Ambient,
  7192  	}
  7193  
  7194  	return &Container{
  7195  		Command:              CommandArgs(stringArrayToStringMap(c.Command)),
  7196  		EnvRules:             envRuleArrayToEnvRules(c.EnvRules),
  7197  		Layers:               Layers(stringArrayToStringMap(c.Layers)),
  7198  		WorkingDir:           c.WorkingDir,
  7199  		Mounts:               mountArrayToMounts(c.Mounts),
  7200  		AllowElevated:        c.AllowElevated,
  7201  		ExecProcesses:        execProcesses,
  7202  		Signals:              c.Signals,
  7203  		AllowStdioAccess:     c.AllowStdioAccess,
  7204  		NoNewPrivileges:      c.NoNewPrivileges,
  7205  		User:                 c.User,
  7206  		Capabilities:         &capabilities,
  7207  		SeccompProfileSHA256: c.SeccompProfileSHA256,
  7208  	}
  7209  }
  7210  
  7211  func envRuleArrayToEnvRules(envRules []EnvRuleConfig) EnvRules {
  7212  	elements := make(map[string]EnvRuleConfig)
  7213  	for i, envRule := range envRules {
  7214  		elements[strconv.Itoa(i)] = envRule
  7215  	}
  7216  	return EnvRules{
  7217  		Elements: elements,
  7218  		Length:   len(envRules),
  7219  	}
  7220  }
  7221  
  7222  func mountArrayToMounts(mounts []mountInternal) Mounts {
  7223  	elements := make(map[string]Mount)
  7224  	for i, mount := range mounts {
  7225  		elements[strconv.Itoa(i)] = Mount{
  7226  			Source:      mount.Source,
  7227  			Destination: mount.Destination,
  7228  			Type:        mount.Type,
  7229  			Options:     Options(stringArrayToStringMap(mount.Options)),
  7230  		}
  7231  	}
  7232  
  7233  	return Mounts{
  7234  		Elements: elements,
  7235  		Length:   len(mounts),
  7236  	}
  7237  }
  7238  
  7239  func (p externalProcess) toConfig() ExternalProcessConfig {
  7240  	return ExternalProcessConfig{
  7241  		Command:          p.command,
  7242  		WorkingDir:       p.workingDir,
  7243  		AllowStdioAccess: p.allowStdioAccess,
  7244  	}
  7245  }
  7246  
  7247  func (f fragment) toConfig() FragmentConfig {
  7248  	return FragmentConfig{
  7249  		Issuer:     f.issuer,
  7250  		Feed:       f.feed,
  7251  		MinimumSVN: f.minimumSVN,
  7252  		Includes:   f.includes,
  7253  	}
  7254  }
  7255  
  7256  func stringArrayToStringMap(values []string) StringArrayMap {
  7257  	elements := make(map[string]string)
  7258  	for i, value := range values {
  7259  		elements[strconv.Itoa(i)] = value
  7260  	}
  7261  
  7262  	return StringArrayMap{
  7263  		Elements: elements,
  7264  		Length:   len(values),
  7265  	}
  7266  }
  7267  
  7268  func (s *stringSet) randUniqueArray(r *rand.Rand, generator func(*rand.Rand) string, numItems int32) []string {
  7269  	items := make([]string, numItems)
  7270  	for i := 0; i < int(numItems); i++ {
  7271  		items[i] = s.randUnique(r, generator)
  7272  	}
  7273  	return items
  7274  }
  7275  
  7276  type regoScratchMountPolicyTestConfig struct {
  7277  	policy *regoEnforcer
  7278  }
  7279  
  7280  func setupRegoScratchMountTest(
  7281  	gc *generatedConstraints,
  7282  	unencryptedScratch bool,
  7283  ) (tc *regoScratchMountPolicyTestConfig, err error) {
  7284  	securityPolicy := gc.toPolicy()
  7285  	securityPolicy.AllowUnencryptedScratch = unencryptedScratch
  7286  
  7287  	defaultMounts := generateMounts(testRand)
  7288  	privilegedMounts := generateMounts(testRand)
  7289  	policy, err := newRegoPolicy(securityPolicy.marshalRego(), toOCIMounts(defaultMounts), toOCIMounts(privilegedMounts))
  7290  	if err != nil {
  7291  		return nil, err
  7292  	}
  7293  	return &regoScratchMountPolicyTestConfig{
  7294  		policy: policy,
  7295  	}, nil
  7296  }
  7297  
  7298  func verifyPolicyRules(apiVersion string, enforcementPoints map[string]interface{}, policyCode string) error {
  7299  	query := rego.New(
  7300  		rego.Query("data.policy"),
  7301  		rego.Module("policy.rego", policyCode),
  7302  		rego.Module("framework.rego", FrameworkCode),
  7303  	)
  7304  
  7305  	ctx := context.Background()
  7306  	resultSet, err := query.Eval(ctx)
  7307  	if err != nil {
  7308  		return fmt.Errorf("unable to query policy template rules: %w", err)
  7309  	}
  7310  
  7311  	policyTemplateRules := resultSet[0].Expressions[0].Value.(map[string]interface{})
  7312  	policyTemplateAPIVersion := policyTemplateRules["api_version"].(string)
  7313  
  7314  	if policyTemplateAPIVersion != apiVersion {
  7315  		return fmt.Errorf("Policy template version != api version: %s != %s", apiVersion, policyTemplateAPIVersion)
  7316  	}
  7317  
  7318  	for rule := range enforcementPoints {
  7319  		if _, ok := policyTemplateRules[rule]; !ok {
  7320  			return fmt.Errorf("Rule %s in API is missing from policy template", rule)
  7321  		}
  7322  	}
  7323  
  7324  	for rule := range policyTemplateRules {
  7325  		if rule == "api_version" || rule == "framework_version" || rule == "reason" {
  7326  			continue
  7327  		}
  7328  
  7329  		if _, ok := enforcementPoints[rule]; !ok {
  7330  			return fmt.Errorf("Rule %s in policy template is missing from API", rule)
  7331  		}
  7332  	}
  7333  
  7334  	return nil
  7335  }
  7336  
  7337  func buildIDNameFromConfig(config IDNameConfig, r *rand.Rand) IDName {
  7338  	switch config.Strategy {
  7339  	case IDNameStrategyName:
  7340  		return IDName{
  7341  			ID:   generateIDNameID(r),
  7342  			Name: config.Rule,
  7343  		}
  7344  
  7345  	case IDNameStrategyID:
  7346  		return IDName{
  7347  			ID:   config.Rule,
  7348  			Name: generateIDNameName(r),
  7349  		}
  7350  
  7351  	case IDNameStrategyAny:
  7352  		return generateIDName(r)
  7353  
  7354  	default:
  7355  		panic(fmt.Sprintf("unsupported ID Name strategy: %v", config.Strategy))
  7356  	}
  7357  }
  7358  
  7359  func buildGroupIDNamesFromUser(user UserConfig, r *rand.Rand) []IDName {
  7360  	groupIDNames := make([]IDName, 0)
  7361  
  7362  	// Select some number of the valid, matching rules to be groups
  7363  	numberOfGroups := int32(len(user.GroupIDNames))
  7364  	numberOfMatches := randMinMax(r, 1, numberOfGroups)
  7365  	usedIndexes := map[int]struct{}{}
  7366  	for numberOfMatches > 0 {
  7367  		anIndex := -1
  7368  		if (numberOfMatches * 2) > numberOfGroups {
  7369  			// if we have a lot of matches, randomly select
  7370  			exists := true
  7371  
  7372  			for exists {
  7373  				anIndex = int(randMinMax(r, 0, numberOfGroups-1))
  7374  				_, exists = usedIndexes[anIndex]
  7375  			}
  7376  		} else {
  7377  			// we have a "smaller set of rules. we'll just iterate and select from
  7378  			// available
  7379  			exists := true
  7380  
  7381  			for exists {
  7382  				anIndex++
  7383  				_, exists = usedIndexes[anIndex]
  7384  			}
  7385  		}
  7386  
  7387  		if user.GroupIDNames[anIndex].Strategy == IDNameStrategyRegex {
  7388  			// we don't match from regex groups or any groups
  7389  			numberOfMatches--
  7390  			continue
  7391  		}
  7392  
  7393  		groupIDName := buildIDNameFromConfig(user.GroupIDNames[anIndex], r)
  7394  		groupIDNames = append(groupIDNames, groupIDName)
  7395  		usedIndexes[anIndex] = struct{}{}
  7396  
  7397  		numberOfMatches--
  7398  	}
  7399  
  7400  	return groupIDNames
  7401  }
  7402  
  7403  func generateIDNameName(r *rand.Rand) string {
  7404  	return randVariableString(r, maxGeneratedNameLength)
  7405  }
  7406  
  7407  func generateIDNameID(r *rand.Rand) string {
  7408  	id := r.Uint32()
  7409  	return strconv.FormatUint(uint64(id), 10)
  7410  }
  7411  
  7412  func generateIDName(r *rand.Rand) IDName {
  7413  	return IDName{
  7414  		ID:   generateIDNameID(r),
  7415  		Name: generateIDNameName(r),
  7416  	}
  7417  }
  7418  
  7419  func generateCapabilities(r *rand.Rand) *oci.LinuxCapabilities {
  7420  	return &oci.LinuxCapabilities{
  7421  		Bounding:    generateCapabilitiesSet(r, 0),
  7422  		Effective:   generateCapabilitiesSet(r, 0),
  7423  		Inheritable: generateCapabilitiesSet(r, 0),
  7424  		Permitted:   generateCapabilitiesSet(r, 0),
  7425  		Ambient:     generateCapabilitiesSet(r, 0),
  7426  	}
  7427  }
  7428  
  7429  func generateSemver(r *rand.Rand) string {
  7430  	major := randMinMax(r, 0, maxGeneratedVersion)
  7431  	minor := randMinMax(r, 0, maxGeneratedVersion)
  7432  	patch := randMinMax(r, 0, maxGeneratedVersion)
  7433  	return fmt.Sprintf("%d.%d.%d", major, minor, patch)
  7434  }
  7435  
  7436  func alterCapabilitySet(r *rand.Rand, set []string) []string {
  7437  	newSet := copyStrings(set)
  7438  
  7439  	if len(newSet) == 0 {
  7440  		return generateCapabilitiesSet(r, 1)
  7441  	}
  7442  
  7443  	alterations := atLeastNAtMostM(r, 1, 4)
  7444  	for i := alterations; i > 0; i-- {
  7445  		if len(newSet) == 0 {
  7446  			newSet = generateCapabilitiesSet(r, 1)
  7447  		} else {
  7448  			action := atMost(r, 2)
  7449  			if action == 0 {
  7450  				newSet = superCapabilitySet(r, newSet)
  7451  			} else if action == 1 {
  7452  				newSet = subsetCapabilitySet(r, newSet)
  7453  			} else {
  7454  				replace := atMost(r, int32((len(newSet) - 1)))
  7455  				newSet[replace] = generateCapability(r)
  7456  			}
  7457  		}
  7458  	}
  7459  
  7460  	return newSet
  7461  }
  7462  
  7463  func subsetCapabilitySet(r *rand.Rand, set []string) []string {
  7464  	newSet := make([]string, 0)
  7465  
  7466  	setSize := int32(len(set))
  7467  	if setSize == 0 {
  7468  		// no subset is possible
  7469  		return newSet
  7470  	} else if setSize == 1 {
  7471  		// only one possibility
  7472  		return newSet
  7473  	}
  7474  
  7475  	// We need to remove at least 1 item, potentially all
  7476  	numberOfMatches := randMinMax(r, 0, setSize-1)
  7477  	usedIndexes := map[int]struct{}{}
  7478  	for i := numberOfMatches; i > 0; i-- {
  7479  		anIndex := -1
  7480  		if ((setSize - int32(len(usedIndexes))) * 2) > i {
  7481  			// the set is pretty large compared to our number to select,
  7482  			// we will gran randomly
  7483  			exists := true
  7484  
  7485  			for exists {
  7486  				anIndex = int(randMinMax(r, 0, setSize-1))
  7487  				_, exists = usedIndexes[anIndex]
  7488  			}
  7489  		} else {
  7490  			// we have a "smaller set of capabilities. we'll just iterate and
  7491  			// select from available
  7492  			exists := true
  7493  
  7494  			for exists {
  7495  				anIndex++
  7496  				_, exists = usedIndexes[anIndex]
  7497  			}
  7498  		}
  7499  
  7500  		newSet = append(newSet, set[anIndex])
  7501  		usedIndexes[anIndex] = struct{}{}
  7502  	}
  7503  
  7504  	return newSet
  7505  }
  7506  
  7507  func superCapabilitySet(r *rand.Rand, set []string) []string {
  7508  	newSet := copyStrings(set)
  7509  
  7510  	additions := atLeastNAtMostM(r, 1, 12)
  7511  	for i := additions; i > 0; i-- {
  7512  		newSet = append(newSet, generateCapability(r))
  7513  	}
  7514  
  7515  	return newSet
  7516  }
  7517  
  7518  func (c capabilitiesInternal) toExternal() oci.LinuxCapabilities {
  7519  	return oci.LinuxCapabilities{
  7520  		Bounding:    c.Bounding,
  7521  		Effective:   c.Effective,
  7522  		Inheritable: c.Inheritable,
  7523  		Permitted:   c.Permitted,
  7524  		Ambient:     c.Ambient,
  7525  	}
  7526  }
  7527  
  7528  func assertKeyValue(object map[string]interface{}, key string, expectedValue interface{}) error {
  7529  	if actualValue, ok := object[key]; ok {
  7530  		if actualValue != expectedValue {
  7531  			return fmt.Errorf("incorrect value for no_new_privileges: %t != %t (expected)", actualValue, expectedValue)
  7532  		}
  7533  	} else {
  7534  		return fmt.Errorf("missing value for %s", key)
  7535  	}
  7536  
  7537  	return nil
  7538  }
  7539  
  7540  func assertDecisionJSONContains(t *testing.T, err error, expectedValues ...string) bool {
  7541  	if err == nil {
  7542  		t.Errorf("expected error to contain %v but got nil", expectedValues)
  7543  		return false
  7544  	}
  7545  
  7546  	policyDecision, err := ExtractPolicyDecision(err.Error())
  7547  	if err != nil {
  7548  		t.Errorf("unable to extract policy decision from error: %v", err)
  7549  		return false
  7550  	}
  7551  
  7552  	for _, expected := range expectedValues {
  7553  		if !strings.Contains(policyDecision, expected) {
  7554  			t.Errorf("expected error to contain %q", expected)
  7555  			return false
  7556  		}
  7557  	}
  7558  
  7559  	return true
  7560  }
  7561  
  7562  func assertDecisionJSONDoesNotContain(t *testing.T, err error, expectedValues ...string) bool {
  7563  	if err == nil {
  7564  		t.Errorf("expected error to contain %v but got nil", expectedValues)
  7565  		return false
  7566  	}
  7567  
  7568  	policyDecision, err := ExtractPolicyDecision(err.Error())
  7569  	if err != nil {
  7570  		t.Errorf("unable to extract policy decision from error: %v", err)
  7571  		return false
  7572  	}
  7573  
  7574  	for _, expected := range expectedValues {
  7575  		if strings.Contains(policyDecision, expected) {
  7576  			t.Errorf("expected error to not contain %q", expected)
  7577  			return false
  7578  		}
  7579  	}
  7580  
  7581  	return true
  7582  }
  7583  

View as plain text