Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for the false positive of access-control's capabilities tcs. #2352

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion tests/accesscontrol/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"github.com/redhat-best-practices-for-k8s/certsuite/tests/identifiers"
"github.com/redhat-best-practices-for-k8s/certsuite/tests/networking/netutil"
"github.com/redhat-best-practices-for-k8s/certsuite/tests/networking/services"
v1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
)

Expand Down Expand Up @@ -263,6 +264,25 @@ func LoadChecks() {
}))
}

// isContainerCapabilitySet checks whether a container capability was explicitly set
// in securityContext.capabilities.add list.
func isContainerCapabilitySet(containerCapabilities *v1.Capabilities, capability string) bool {
if containerCapabilities == nil {
return false
}

if len(containerCapabilities.Add) == 0 {
return false
}

if stringhelper.StringInSlice(containerCapabilities.Add, v1.Capability("ALL"), true) ||
stringhelper.StringInSlice(containerCapabilities.Add, v1.Capability(capability), true) {
return true
}

return false
}

// checkForbiddenCapability checks if containers use a forbidden capability.
// Returns:
// - compliantObjects []*testhelper.ReportObject : Slice containing report objects for containers compliant with the capability restrictions.
Expand All @@ -275,7 +295,7 @@ func checkForbiddenCapability(containers []*provider.Container, capability strin
switch {
case cut.SecurityContext == nil:
case cut.SecurityContext.Capabilities == nil:
case strings.Contains(cut.SecurityContext.Capabilities.String(), capability):
case isContainerCapabilitySet(cut.SecurityContext.Capabilities, capability):
edcdavid marked this conversation as resolved.
Show resolved Hide resolved
compliant = false
}

Expand Down
109 changes: 109 additions & 0 deletions tests/accesscontrol/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,112 @@
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

package accesscontrol

import (
"testing"

"github.com/stretchr/testify/assert"
v1 "k8s.io/api/core/v1"
sebrandon1 marked this conversation as resolved.
Show resolved Hide resolved
)

func Test_isContainerCapabilitySet(t *testing.T) {
type args struct {
containerCapabilities *v1.Capabilities
capability string
}
tests := []struct {
name string
args args
want bool
}{
{
name: "nil capabilities",
args: args{
capability: "IPC_LOCK",
containerCapabilities: nil,
},
want: false,
},
{
name: "empty capabilities",
args: args{
capability: "IPC_LOCK",
containerCapabilities: &v1.Capabilities{},
},
want: false,
},
{
name: "explicitly empty add list",
args: args{
capability: "IPC_LOCK",
containerCapabilities: &v1.Capabilities{Add: []v1.Capability{}},
},
want: false,
},
{
name: "explicitly empty drop list",
args: args{
capability: "IPC_LOCK",
containerCapabilities: &v1.Capabilities{Drop: []v1.Capability{}},
},
want: false,
},
{
name: "IPC_LOCK not found in any list",
args: args{
capability: "IPC_LOCK",
containerCapabilities: &v1.Capabilities{
Add: []v1.Capability{"NET_CAP_BINDING"},
Drop: []v1.Capability{"SYS_ADMIN", "NET_ADMIN"},
},
},
want: false,
},
{
name: "IPC_LOCK found in the add list",
args: args{
capability: "IPC_LOCK",
containerCapabilities: &v1.Capabilities{
Add: []v1.Capability{"NET_ADMIN", "IPC_LOCK"},
Drop: []v1.Capability{"SYS_ADMIN"}},
},
want: true,
},
{
name: "IPC_LOCK appears in the drop list only",
args: args{
capability: "IPC_LOCK",
containerCapabilities: &v1.Capabilities{Drop: []v1.Capability{"SYS_ADMIN", "IPC_LOCK", "NET_ADMIN"}},
},
want: false,
},
{
// When set in both add and drop lists, k8s/openshift will compute drop first, then add, which results
// in the capability to be finally set.
name: "IPC_LOCK set in both add and drop lists.",
args: args{
capability: "IPC_LOCK",
containerCapabilities: &v1.Capabilities{
Add: []v1.Capability{"IPC_LOCK"},
Drop: []v1.Capability{"SYS_ADMIN", "IPC_LOCK", "NET_ADMIN"},
},
},
want: true,
},
{
name: "ALL capabilities in the add list",
args: args{
capability: "IPC_LOCK",
containerCapabilities: &v1.Capabilities{Add: []v1.Capability{"ALL"}},
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := isContainerCapabilitySet(tt.args.containerCapabilities, tt.args.capability); got != tt.want {
assert.Equal(t, tt.want, got)
}
})
}
}
Loading