Replace usage of Whitelist with Allowlist within Kubelet's sysctl package (#102298)

* Change uses of whitelist to allowlist in kubelet sysctl

* Rename whitelist files to allowlist in Kubelet sysctl

* Further renames of whitelist to allowlist in Kubelet

* Rename podsecuritypolicy uses of whitelist to allowlist

* Update pkg/kubelet/kubelet.go

Co-authored-by: Danielle <dani@builds.terrible.systems>

Co-authored-by: Danielle <dani@builds.terrible.systems>
This commit is contained in:
Wesley Williams 2021-08-05 02:59:35 +01:00 committed by GitHub
parent 9c5cefb230
commit ff165c8823
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 49 additions and 49 deletions

View File

@ -340,7 +340,7 @@ type KubeletConfiguration struct {
ContainerLogMaxFiles int32
// ConfigMapAndSecretChangeDetectionStrategy is a mode in which config map and secret managers are running.
ConfigMapAndSecretChangeDetectionStrategy ResourceChangeDetectionStrategy
// A comma separated whitelist of unsafe sysctls or sysctl patterns (ending in *).
// A comma separated allowlist of unsafe sysctls or sysctl patterns (ending in *).
// Unsafe sysctl groups are kernel.shm*, kernel.msg*, kernel.sem, fs.mqueue.*, and net.*.
// These sysctls are namespaced but not allowed by default. For example: "kernel.msg*,net.ipv4.route.min_pmtu"
// +optional

View File

@ -279,16 +279,16 @@ func (m *cgroupManagerImpl) Exists(name CgroupName) bool {
// scoped to the set control groups it understands. this is being discussed
// in https://github.com/opencontainers/runc/issues/1440
// once resolved, we can remove this code.
whitelistControllers := sets.NewString("cpu", "cpuacct", "cpuset", "memory", "systemd", "pids")
allowlistControllers := sets.NewString("cpu", "cpuacct", "cpuset", "memory", "systemd", "pids")
if _, ok := m.subsystems.MountPoints["hugetlb"]; ok {
whitelistControllers.Insert("hugetlb")
allowlistControllers.Insert("hugetlb")
}
var missingPaths []string
// If even one cgroup path doesn't exist, then the cgroup doesn't exist.
for controller, path := range cgroupPaths {
// ignore mounts we don't care about
if !whitelistControllers.Has(controller) {
if !allowlistControllers.Has(controller) {
continue
}
if !libcontainercgroups.PathExists(path) {

View File

@ -112,7 +112,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/util/sliceutils"
"k8s.io/kubernetes/pkg/kubelet/volumemanager"
"k8s.io/kubernetes/pkg/security/apparmor"
sysctlwhitelist "k8s.io/kubernetes/pkg/security/podsecuritypolicy/sysctl"
sysctlallowlist "k8s.io/kubernetes/pkg/security/podsecuritypolicy/sysctl"
"k8s.io/kubernetes/pkg/util/oom"
"k8s.io/kubernetes/pkg/util/selinux"
"k8s.io/kubernetes/pkg/volume"
@ -820,14 +820,14 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
klet.evictionManager = evictionManager
klet.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
// Safe, whitelisted sysctls can always be used as unsafe sysctls in the spec.
// Safe, allowed sysctls can always be used as unsafe sysctls in the spec.
// Hence, we concatenate those two lists.
safeAndUnsafeSysctls := append(sysctlwhitelist.SafeSysctlWhitelist(), allowedUnsafeSysctls...)
sysctlsWhitelist, err := sysctl.NewWhitelist(safeAndUnsafeSysctls)
safeAndUnsafeSysctls := append(sysctlallowlist.SafeSysctlAllowlist(), allowedUnsafeSysctls...)
sysctlsAllowlist, err := sysctl.NewAllowlist(safeAndUnsafeSysctls)
if err != nil {
return nil, err
}
klet.admitHandlers.AddPodAdmitHandler(sysctlsWhitelist)
klet.admitHandlers.AddPodAdmitHandler(sysctlsAllowlist)
// enable active deadline handler
activeDeadlineHandler, err := newActiveDeadlineHandler(klet.statusManager, kubeDeps.Recorder, klet.clock)

View File

@ -1791,7 +1791,7 @@ func (kl *Kubelet) convertToAPIContainerStatuses(pod *v1.Pod, podStatus *kubecon
// ServeLogs returns logs of current machine.
func (kl *Kubelet) ServeLogs(w http.ResponseWriter, req *http.Request) {
// TODO: whitelist logs we are willing to serve
// TODO: allowlist logs we are willing to serve
kl.logServer.ServeHTTP(w, req)
}

View File

@ -30,19 +30,19 @@ const (
ForbiddenReason = "SysctlForbidden"
)
// patternWhitelist takes a list of sysctls or sysctl patterns (ending in *) and
// patternAllowlist takes a list of sysctls or sysctl patterns (ending in *) and
// checks validity via a sysctl and prefix map, rejecting those which are not known
// to be namespaced.
type patternWhitelist struct {
type patternAllowlist struct {
sysctls map[string]Namespace
prefixes map[string]Namespace
}
var _ lifecycle.PodAdmitHandler = &patternWhitelist{}
var _ lifecycle.PodAdmitHandler = &patternAllowlist{}
// NewWhitelist creates a new Whitelist from a list of sysctls and sysctl pattern (ending in *).
func NewWhitelist(patterns []string) (*patternWhitelist, error) {
w := &patternWhitelist{
// NewAllowlist creates a new Allowlist from a list of sysctls and sysctl pattern (ending in *).
func NewAllowlist(patterns []string) (*patternAllowlist, error) {
w := &patternAllowlist{
sysctls: map[string]Namespace{},
prefixes: map[string]Namespace{},
}
@ -73,14 +73,14 @@ func NewWhitelist(patterns []string) (*patternWhitelist, error) {
return w, nil
}
// validateSysctl checks that a sysctl is whitelisted because it is known
// to be namespaced by the Linux kernel. Note that being whitelisted is required, but not
// validateSysctl checks that a sysctl is allowlisted because it is known
// to be namespaced by the Linux kernel. Note that being allowlisted is required, but not
// sufficient: the container runtime might have a stricter check and refuse to launch a pod.
//
// The parameters hostNet and hostIPC are used to forbid sysctls for pod sharing the
// respective namespaces with the host. This check is only possible for sysctls on
// the static default whitelist, not those on the custom whitelist provided by the admin.
func (w *patternWhitelist) validateSysctl(sysctl string, hostNet, hostIPC bool) error {
// the static default allowlist, not those on the custom allowlist provided by the admin.
func (w *patternAllowlist) validateSysctl(sysctl string, hostNet, hostIPC bool) error {
nsErrorFmt := "%q not allowed with host %s enabled"
if ns, found := w.sysctls[sysctl]; found {
if ns == ipcNamespace && hostIPC {
@ -102,12 +102,12 @@ func (w *patternWhitelist) validateSysctl(sysctl string, hostNet, hostIPC bool)
return nil
}
}
return fmt.Errorf("%q not whitelisted", sysctl)
return fmt.Errorf("%q not allowlisted", sysctl)
}
// Admit checks that all sysctls given in pod's security context
// are valid according to the whitelist.
func (w *patternWhitelist) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult {
// are valid according to the allowlist.
func (w *patternAllowlist) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult {
pod := attrs.Pod
if pod.Spec.SecurityContext == nil || len(pod.Spec.SecurityContext.Sysctls) == 0 {
return lifecycle.PodAdmitResult{

View File

@ -22,7 +22,7 @@ import (
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/sysctl"
)
func TestNewWhitelist(t *testing.T) {
func TestNewAllowlist(t *testing.T) {
type Test struct {
sysctls []string
err bool
@ -35,16 +35,16 @@ func TestNewWhitelist(t *testing.T) {
{sysctls: []string{"net.*.foo"}, err: true},
{sysctls: []string{"foo"}, err: true},
} {
_, err := NewWhitelist(append(sysctl.SafeSysctlWhitelist(), test.sysctls...))
_, err := NewAllowlist(append(sysctl.SafeSysctlAllowlist(), test.sysctls...))
if test.err && err == nil {
t.Errorf("expected an error creating a whitelist for %v", test.sysctls)
t.Errorf("expected an error creating a allowlist for %v", test.sysctls)
} else if !test.err && err != nil {
t.Errorf("got unexpected error creating a whitelist for %v: %v", test.sysctls, err)
t.Errorf("got unexpected error creating a allowlist for %v: %v", test.sysctls, err)
}
}
}
func TestWhitelist(t *testing.T) {
func TestAllowlist(t *testing.T) {
type Test struct {
sysctl string
hostNet, hostIPC bool
@ -65,14 +65,14 @@ func TestWhitelist(t *testing.T) {
{sysctl: "kernel.sem", hostIPC: true},
}
w, err := NewWhitelist(append(sysctl.SafeSysctlWhitelist(), "kernel.msg*", "kernel.sem"))
w, err := NewAllowlist(append(sysctl.SafeSysctlAllowlist(), "kernel.msg*", "kernel.sem"))
if err != nil {
t.Fatalf("failed to create whitelist: %v", err)
t.Fatalf("failed to create allowlist: %v", err)
}
for _, test := range valid {
if err := w.validateSysctl(test.sysctl, test.hostNet, test.hostIPC); err != nil {
t.Errorf("expected to be whitelisted: %+v, got: %v", test, err)
t.Errorf("expected to be allowlisted: %+v, got: %v", test, err)
}
}

View File

@ -83,7 +83,7 @@ func (f *simpleStrategyFactory) CreateStrategies(psp *policy.PodSecurityPolicy,
errs = append(errs, err)
}
sysctlsStrat := createSysctlsStrategy(sysctl.SafeSysctlWhitelist(), psp.Spec.AllowedUnsafeSysctls, psp.Spec.ForbiddenSysctls)
sysctlsStrat := createSysctlsStrategy(sysctl.SafeSysctlAllowlist(), psp.Spec.AllowedUnsafeSysctls, psp.Spec.ForbiddenSysctls)
if len(errs) > 0 {
return nil, errors.NewAggregate(errs)
@ -191,6 +191,6 @@ func createCapabilitiesStrategy(defaultAddCaps, requiredDropCaps, allowedCaps []
}
// createSysctlsStrategy creates a new sysctls strategy.
func createSysctlsStrategy(safeWhitelist, allowedUnsafeSysctls, forbiddenSysctls []string) sysctl.SysctlsStrategy {
return sysctl.NewMustMatchPatterns(safeWhitelist, allowedUnsafeSysctls, forbiddenSysctls)
func createSysctlsStrategy(safeAllowlist, allowedUnsafeSysctls, forbiddenSysctls []string) sysctl.SysctlsStrategy {
return sysctl.NewMustMatchPatterns(safeAllowlist, allowedUnsafeSysctls, forbiddenSysctls)
}

View File

@ -1006,19 +1006,19 @@ func TestValidatePodSuccess(t *testing.T) {
pod: seccompPod,
psp: seccompPSP,
},
"flex volume driver in a whitelist (all volumes are allowed)": {
"flex volume driver in a allowlist (all volumes are allowed)": {
pod: flexVolumePod,
psp: allowFlexVolumesPSP(false, true),
},
"flex volume driver with empty whitelist (all volumes are allowed)": {
"flex volume driver with empty allowlist (all volumes are allowed)": {
pod: flexVolumePod,
psp: allowFlexVolumesPSP(true, true),
},
"flex volume driver in a whitelist (only flex volumes are allowed)": {
"flex volume driver in a allowlist (only flex volumes are allowed)": {
pod: flexVolumePod,
psp: allowFlexVolumesPSP(false, false),
},
"flex volume driver with empty whitelist (only flex volumes volumes are allowed)": {
"flex volume driver with empty allowlist (only flex volumes volumes are allowed)": {
pod: flexVolumePod,
psp: allowFlexVolumesPSP(true, false),
},

View File

@ -24,12 +24,12 @@ import (
api "k8s.io/kubernetes/pkg/apis/core"
)
// SafeSysctlWhitelist returns the whitelist of safe sysctls and safe sysctl patterns (ending in *).
// SafeSysctlAllowlist returns the allowlist of safe sysctls and safe sysctl patterns (ending in *).
//
// A sysctl is called safe iff
// - it is namespaced in the container or the pod
// - it is isolated, i.e. has no influence on any other pod on the same node.
func SafeSysctlWhitelist() []string {
func SafeSysctlAllowlist() []string {
return []string{
"kernel.shm_rmid_forced",
"net.ipv4.ip_local_port_range",
@ -41,7 +41,7 @@ func SafeSysctlWhitelist() []string {
// mustMatchPatterns implements the SysctlsStrategy interface
type mustMatchPatterns struct {
safeWhitelist []string
safeAllowlist []string
allowedUnsafeSysctls []string
forbiddenSysctls []string
}
@ -52,9 +52,9 @@ var (
// NewMustMatchPatterns creates a new mustMatchPatterns strategy that will provide validation.
// Passing nil means the default pattern, passing an empty list means to disallow all sysctls.
func NewMustMatchPatterns(safeWhitelist, allowedUnsafeSysctls, forbiddenSysctls []string) SysctlsStrategy {
func NewMustMatchPatterns(safeAllowlist, allowedUnsafeSysctls, forbiddenSysctls []string) SysctlsStrategy {
return &mustMatchPatterns{
safeWhitelist: safeWhitelist,
safeAllowlist: safeAllowlist,
allowedUnsafeSysctls: allowedUnsafeSysctls,
forbiddenSysctls: forbiddenSysctls,
}
@ -76,7 +76,7 @@ func (s *mustMatchPatterns) isForbidden(sysctlName string) bool {
}
func (s *mustMatchPatterns) isSafe(sysctlName string) bool {
for _, ws := range s.safeWhitelist {
for _, ws := range s.safeAllowlist {
if sysctlName == ws {
return true
}

View File

@ -24,7 +24,7 @@ import (
func TestValidate(t *testing.T) {
tests := map[string]struct {
whitelist []string
allowlist []string
forbiddenSafe []string
allowedUnsafe []string
allowed []string
@ -32,16 +32,16 @@ func TestValidate(t *testing.T) {
}{
// no container requests
"with allow all": {
whitelist: []string{"foo"},
allowlist: []string{"foo"},
allowed: []string{"foo"},
},
"empty": {
whitelist: []string{"foo"},
allowlist: []string{"foo"},
forbiddenSafe: []string{"*"},
disallowed: []string{"foo"},
},
"without wildcard": {
whitelist: []string{"a", "a.b"},
allowlist: []string{"a", "a.b"},
allowed: []string{"a", "a.b"},
disallowed: []string{"b"},
},
@ -57,7 +57,7 @@ func TestValidate(t *testing.T) {
}
for k, v := range tests {
strategy := NewMustMatchPatterns(v.whitelist, v.allowedUnsafe, v.forbiddenSafe)
strategy := NewMustMatchPatterns(v.allowlist, v.allowedUnsafe, v.forbiddenSafe)
pod := &api.Pod{}
errs := strategy.Validate(pod)