admission_test.go 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package podsecuritypolicy
  14. import (
  15. "context"
  16. "fmt"
  17. "reflect"
  18. "strings"
  19. "testing"
  20. "github.com/stretchr/testify/assert"
  21. v1 "k8s.io/api/core/v1"
  22. policy "k8s.io/api/policy/v1beta1"
  23. apiequality "k8s.io/apimachinery/pkg/api/equality"
  24. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  25. "k8s.io/apimachinery/pkg/util/diff"
  26. kadmission "k8s.io/apiserver/pkg/admission"
  27. admissiontesting "k8s.io/apiserver/pkg/admission/testing"
  28. "k8s.io/apiserver/pkg/authentication/serviceaccount"
  29. "k8s.io/apiserver/pkg/authentication/user"
  30. "k8s.io/apiserver/pkg/authorization/authorizer"
  31. "k8s.io/apiserver/pkg/authorization/authorizerfactory"
  32. utilfeature "k8s.io/apiserver/pkg/util/feature"
  33. "k8s.io/client-go/informers"
  34. featuregatetesting "k8s.io/component-base/featuregate/testing"
  35. "k8s.io/kubernetes/pkg/api/legacyscheme"
  36. kapi "k8s.io/kubernetes/pkg/apis/core"
  37. k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1"
  38. "k8s.io/kubernetes/pkg/controller"
  39. "k8s.io/kubernetes/pkg/features"
  40. "k8s.io/kubernetes/pkg/security/apparmor"
  41. kpsp "k8s.io/kubernetes/pkg/security/podsecuritypolicy"
  42. "k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp"
  43. psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
  44. utilpointer "k8s.io/utils/pointer"
  45. )
  46. const defaultContainerName = "test-c"
  47. // NewTestAdmission provides an admission plugin with test implementations of internal structs.
  48. func NewTestAdmission(psps []*policy.PodSecurityPolicy, authz authorizer.Authorizer) *Plugin {
  49. informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
  50. store := informerFactory.Policy().V1beta1().PodSecurityPolicies().Informer().GetStore()
  51. for _, psp := range psps {
  52. store.Add(psp)
  53. }
  54. lister := informerFactory.Policy().V1beta1().PodSecurityPolicies().Lister()
  55. if authz == nil {
  56. authz = &TestAuthorizer{}
  57. }
  58. return &Plugin{
  59. Handler: kadmission.NewHandler(kadmission.Create, kadmission.Update),
  60. strategyFactory: kpsp.NewSimpleStrategyFactory(),
  61. authz: authz,
  62. lister: lister,
  63. }
  64. }
  65. // TestAuthorizer is a testing struct for testing that fulfills the authorizer interface.
  66. type TestAuthorizer struct {
  67. // usernameToNamespaceToAllowedPSPs contains the map of allowed PSPs.
  68. // if nil, all PSPs are allowed.
  69. usernameToNamespaceToAllowedPSPs map[string]map[string]map[string]bool
  70. // allowedAPIGroupName specifies an API Group name that contains PSP resources.
  71. // In order to be authorized, AttributesRecord must have this group name.
  72. // When empty, API Group name isn't taken into account.
  73. // TODO: remove this when PSP will be completely moved out of the extensions and we'll lookup only in "policy" group.
  74. allowedAPIGroupName string
  75. }
  76. func (t *TestAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
  77. if t.usernameToNamespaceToAllowedPSPs == nil {
  78. return authorizer.DecisionAllow, "", nil
  79. }
  80. allowedInNamespace := t.usernameToNamespaceToAllowedPSPs[a.GetUser().GetName()][a.GetNamespace()][a.GetName()]
  81. allowedClusterWide := t.usernameToNamespaceToAllowedPSPs[a.GetUser().GetName()][""][a.GetName()]
  82. allowedAPIGroup := len(t.allowedAPIGroupName) == 0 || a.GetAPIGroup() == t.allowedAPIGroupName
  83. if allowedAPIGroup && (allowedInNamespace || allowedClusterWide) {
  84. return authorizer.DecisionAllow, "", nil
  85. }
  86. return authorizer.DecisionNoOpinion, "", nil
  87. }
  88. var _ authorizer.Authorizer = &TestAuthorizer{}
  89. func useInitContainers(pod *kapi.Pod) *kapi.Pod {
  90. pod.Spec.InitContainers = pod.Spec.Containers
  91. pod.Spec.Containers = []kapi.Container{}
  92. return pod
  93. }
  94. func TestAdmitSeccomp(t *testing.T) {
  95. containerName := "container"
  96. tests := map[string]struct {
  97. pspAnnotations map[string]string
  98. podAnnotations map[string]string
  99. shouldPassAdmit bool
  100. shouldPassValidate bool
  101. }{
  102. "no seccomp, no pod annotations": {
  103. pspAnnotations: nil,
  104. podAnnotations: nil,
  105. shouldPassAdmit: true,
  106. shouldPassValidate: true,
  107. },
  108. "no seccomp, pod annotations": {
  109. pspAnnotations: nil,
  110. podAnnotations: map[string]string{
  111. kapi.SeccompPodAnnotationKey: "foo",
  112. },
  113. shouldPassAdmit: false,
  114. shouldPassValidate: false,
  115. },
  116. "no seccomp, container annotations": {
  117. pspAnnotations: nil,
  118. podAnnotations: map[string]string{
  119. kapi.SeccompContainerAnnotationKeyPrefix + containerName: "foo",
  120. },
  121. shouldPassAdmit: false,
  122. shouldPassValidate: false,
  123. },
  124. "seccomp, allow any no pod annotation": {
  125. pspAnnotations: map[string]string{
  126. seccomp.AllowedProfilesAnnotationKey: seccomp.AllowAny,
  127. },
  128. podAnnotations: nil,
  129. shouldPassAdmit: true,
  130. shouldPassValidate: true,
  131. },
  132. "seccomp, allow any pod annotation": {
  133. pspAnnotations: map[string]string{
  134. seccomp.AllowedProfilesAnnotationKey: seccomp.AllowAny,
  135. },
  136. podAnnotations: map[string]string{
  137. kapi.SeccompPodAnnotationKey: "foo",
  138. },
  139. shouldPassAdmit: true,
  140. shouldPassValidate: true,
  141. },
  142. "seccomp, allow any container annotation": {
  143. pspAnnotations: map[string]string{
  144. seccomp.AllowedProfilesAnnotationKey: seccomp.AllowAny,
  145. },
  146. podAnnotations: map[string]string{
  147. kapi.SeccompContainerAnnotationKeyPrefix + containerName: "foo",
  148. },
  149. shouldPassAdmit: true,
  150. shouldPassValidate: true,
  151. },
  152. "seccomp, allow specific pod annotation failure": {
  153. pspAnnotations: map[string]string{
  154. seccomp.AllowedProfilesAnnotationKey: "foo",
  155. },
  156. podAnnotations: map[string]string{
  157. kapi.SeccompPodAnnotationKey: "bar",
  158. },
  159. shouldPassAdmit: false,
  160. shouldPassValidate: false,
  161. },
  162. "seccomp, allow specific container annotation failure": {
  163. pspAnnotations: map[string]string{
  164. // provide a default so we don't have to give the pod annotation
  165. seccomp.DefaultProfileAnnotationKey: "foo",
  166. seccomp.AllowedProfilesAnnotationKey: "foo",
  167. },
  168. podAnnotations: map[string]string{
  169. kapi.SeccompContainerAnnotationKeyPrefix + containerName: "bar",
  170. },
  171. shouldPassAdmit: false,
  172. shouldPassValidate: false,
  173. },
  174. "seccomp, allow specific pod annotation pass": {
  175. pspAnnotations: map[string]string{
  176. seccomp.AllowedProfilesAnnotationKey: "foo",
  177. },
  178. podAnnotations: map[string]string{
  179. kapi.SeccompPodAnnotationKey: "foo",
  180. },
  181. shouldPassAdmit: true,
  182. shouldPassValidate: true,
  183. },
  184. "seccomp, allow specific container annotation pass": {
  185. pspAnnotations: map[string]string{
  186. // provide a default so we don't have to give the pod annotation
  187. seccomp.DefaultProfileAnnotationKey: "foo",
  188. seccomp.AllowedProfilesAnnotationKey: "foo,bar",
  189. },
  190. podAnnotations: map[string]string{
  191. kapi.SeccompContainerAnnotationKeyPrefix + containerName: "bar",
  192. },
  193. shouldPassAdmit: true,
  194. shouldPassValidate: true,
  195. },
  196. }
  197. for k, v := range tests {
  198. psp := restrictivePSP()
  199. psp.Annotations = v.pspAnnotations
  200. pod := &kapi.Pod{
  201. ObjectMeta: metav1.ObjectMeta{
  202. Annotations: v.podAnnotations,
  203. },
  204. Spec: kapi.PodSpec{
  205. Containers: []kapi.Container{
  206. {Name: containerName},
  207. },
  208. },
  209. }
  210. testPSPAdmit(k, []*policy.PodSecurityPolicy{psp}, pod, v.shouldPassAdmit, v.shouldPassValidate, psp.Name, t)
  211. }
  212. }
  213. func TestAdmitPrivileged(t *testing.T) {
  214. createPodWithPriv := func(priv bool) *kapi.Pod {
  215. pod := goodPod()
  216. pod.Spec.Containers[0].SecurityContext.Privileged = &priv
  217. return pod
  218. }
  219. nonPrivilegedPSP := restrictivePSP()
  220. nonPrivilegedPSP.Name = "non-priv"
  221. nonPrivilegedPSP.Spec.Privileged = false
  222. privilegedPSP := restrictivePSP()
  223. privilegedPSP.Name = "priv"
  224. privilegedPSP.Spec.Privileged = true
  225. trueValue := true
  226. falseValue := false
  227. tests := map[string]struct {
  228. pod *kapi.Pod
  229. psps []*policy.PodSecurityPolicy
  230. shouldPassAdmit bool
  231. shouldPassValidate bool
  232. expectedPriv *bool
  233. expectedPSP string
  234. }{
  235. "pod with priv=nil allowed under non priv PSP": {
  236. pod: goodPod(),
  237. psps: []*policy.PodSecurityPolicy{nonPrivilegedPSP},
  238. shouldPassAdmit: true,
  239. shouldPassValidate: true,
  240. expectedPriv: nil,
  241. expectedPSP: nonPrivilegedPSP.Name,
  242. },
  243. "pod with priv=nil allowed under priv PSP": {
  244. pod: goodPod(),
  245. psps: []*policy.PodSecurityPolicy{privilegedPSP},
  246. shouldPassAdmit: true,
  247. shouldPassValidate: true,
  248. expectedPriv: nil,
  249. expectedPSP: privilegedPSP.Name,
  250. },
  251. "pod with priv=false allowed under non priv PSP": {
  252. pod: createPodWithPriv(false),
  253. psps: []*policy.PodSecurityPolicy{nonPrivilegedPSP},
  254. shouldPassAdmit: true,
  255. shouldPassValidate: true,
  256. expectedPriv: &falseValue,
  257. expectedPSP: nonPrivilegedPSP.Name,
  258. },
  259. "pod with priv=false allowed under priv PSP": {
  260. pod: createPodWithPriv(false),
  261. psps: []*policy.PodSecurityPolicy{privilegedPSP},
  262. shouldPassAdmit: true,
  263. shouldPassValidate: true,
  264. expectedPriv: &falseValue,
  265. expectedPSP: privilegedPSP.Name,
  266. },
  267. "pod with priv=true denied by non priv PSP": {
  268. pod: createPodWithPriv(true),
  269. psps: []*policy.PodSecurityPolicy{nonPrivilegedPSP},
  270. shouldPassAdmit: false,
  271. shouldPassValidate: false,
  272. },
  273. "pod with priv=true allowed by priv PSP": {
  274. pod: createPodWithPriv(true),
  275. psps: []*policy.PodSecurityPolicy{nonPrivilegedPSP, privilegedPSP},
  276. shouldPassAdmit: true,
  277. shouldPassValidate: true,
  278. expectedPriv: &trueValue,
  279. expectedPSP: privilegedPSP.Name,
  280. },
  281. }
  282. for k, v := range tests {
  283. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  284. if v.shouldPassAdmit {
  285. priv := v.pod.Spec.Containers[0].SecurityContext.Privileged
  286. if (priv == nil) != (v.expectedPriv == nil) {
  287. t.Errorf("%s expected privileged to be %v, got %v", k, v.expectedPriv, priv)
  288. } else if priv != nil && *priv != *v.expectedPriv {
  289. t.Errorf("%s expected privileged to be %v, got %v", k, *v.expectedPriv, *priv)
  290. }
  291. }
  292. }
  293. }
  294. func defaultPod(t *testing.T, pod *kapi.Pod) *kapi.Pod {
  295. v1Pod := &v1.Pod{}
  296. if err := legacyscheme.Scheme.Convert(pod, v1Pod, nil); err != nil {
  297. t.Fatal(err)
  298. }
  299. legacyscheme.Scheme.Default(v1Pod)
  300. apiPod := &kapi.Pod{}
  301. if err := legacyscheme.Scheme.Convert(v1Pod, apiPod, nil); err != nil {
  302. t.Fatal(err)
  303. }
  304. return apiPod
  305. }
  306. func TestAdmitPreferNonmutating(t *testing.T) {
  307. mutating1 := restrictivePSP()
  308. mutating1.Name = "mutating1"
  309. mutating1.Spec.RunAsUser.Ranges = []policy.IDRange{{Min: int64(1), Max: int64(1)}}
  310. mutating2 := restrictivePSP()
  311. mutating2.Name = "mutating2"
  312. mutating2.Spec.RunAsUser.Ranges = []policy.IDRange{{Min: int64(2), Max: int64(2)}}
  313. privilegedPSP := permissivePSP()
  314. privilegedPSP.Name = "privileged"
  315. unprivilegedRunAsAnyPod := defaultPod(t, &kapi.Pod{
  316. ObjectMeta: metav1.ObjectMeta{},
  317. Spec: kapi.PodSpec{
  318. ServiceAccountName: "default",
  319. Containers: []kapi.Container{{Name: "mycontainer", Image: "myimage"}},
  320. },
  321. })
  322. changedPod := unprivilegedRunAsAnyPod.DeepCopy()
  323. changedPod.Spec.Containers[0].Image = "myimage2"
  324. podWithSC := unprivilegedRunAsAnyPod.DeepCopy()
  325. podWithSC.Annotations = map[string]string{psputil.ValidatedPSPAnnotation: privilegedPSP.Name}
  326. changedPodWithSC := changedPod.DeepCopy()
  327. changedPodWithSC.Annotations = map[string]string{psputil.ValidatedPSPAnnotation: privilegedPSP.Name}
  328. gcChangedPod := unprivilegedRunAsAnyPod.DeepCopy()
  329. gcChangedPod.OwnerReferences = []metav1.OwnerReference{{Kind: "Foo", Name: "bar"}}
  330. gcChangedPod.Finalizers = []string{"foo"}
  331. podWithAnnotation := unprivilegedRunAsAnyPod.DeepCopy()
  332. podWithAnnotation.ObjectMeta.Annotations = map[string]string{
  333. // "mutating2" is lexicographically behind "mutating1", so "mutating1" should be
  334. // chosen because it's the canonical PSP order.
  335. psputil.ValidatedPSPAnnotation: mutating2.Name,
  336. }
  337. tests := map[string]struct {
  338. operation kadmission.Operation
  339. pod *kapi.Pod
  340. podBeforeUpdate *kapi.Pod
  341. psps []*policy.PodSecurityPolicy
  342. shouldPassValidate bool
  343. expectMutation bool
  344. expectedContainerUser *int64
  345. expectedPSP string
  346. }{
  347. "pod should not be mutated by allow-all strategies": {
  348. operation: kadmission.Create,
  349. pod: unprivilegedRunAsAnyPod.DeepCopy(),
  350. psps: []*policy.PodSecurityPolicy{privilegedPSP},
  351. shouldPassValidate: true,
  352. expectMutation: false,
  353. expectedContainerUser: nil,
  354. expectedPSP: privilegedPSP.Name,
  355. },
  356. "pod should prefer non-mutating PSP on create": {
  357. operation: kadmission.Create,
  358. pod: unprivilegedRunAsAnyPod.DeepCopy(),
  359. psps: []*policy.PodSecurityPolicy{mutating2, mutating1, privilegedPSP},
  360. shouldPassValidate: true,
  361. expectMutation: false,
  362. expectedContainerUser: nil,
  363. expectedPSP: privilegedPSP.Name,
  364. },
  365. "pod should use deterministic mutating PSP on create": {
  366. operation: kadmission.Create,
  367. pod: unprivilegedRunAsAnyPod.DeepCopy(),
  368. psps: []*policy.PodSecurityPolicy{mutating2, mutating1},
  369. shouldPassValidate: true,
  370. expectMutation: true,
  371. expectedContainerUser: &mutating1.Spec.RunAsUser.Ranges[0].Min,
  372. expectedPSP: mutating1.Name,
  373. },
  374. "pod should use deterministic mutating PSP on create even if ValidatedPSPAnnotation is set": {
  375. operation: kadmission.Create,
  376. pod: podWithAnnotation,
  377. psps: []*policy.PodSecurityPolicy{mutating2, mutating1},
  378. shouldPassValidate: true,
  379. expectMutation: true,
  380. expectedContainerUser: &mutating1.Spec.RunAsUser.Ranges[0].Min,
  381. expectedPSP: mutating1.Name,
  382. },
  383. "pod should prefer non-mutating PSP on update": {
  384. operation: kadmission.Update,
  385. pod: changedPodWithSC.DeepCopy(),
  386. podBeforeUpdate: podWithSC.DeepCopy(),
  387. psps: []*policy.PodSecurityPolicy{mutating2, mutating1, privilegedPSP},
  388. shouldPassValidate: true,
  389. expectMutation: false,
  390. expectedContainerUser: nil,
  391. expectedPSP: privilegedPSP.Name,
  392. },
  393. "pod should not mutate on update, but fail validation": {
  394. operation: kadmission.Update,
  395. pod: changedPod.DeepCopy(),
  396. podBeforeUpdate: unprivilegedRunAsAnyPod.DeepCopy(),
  397. psps: []*policy.PodSecurityPolicy{mutating2, mutating1},
  398. shouldPassValidate: false,
  399. expectMutation: false,
  400. expectedContainerUser: nil,
  401. expectedPSP: "",
  402. },
  403. "pod should be allowed if completely unchanged on update": {
  404. operation: kadmission.Update,
  405. pod: unprivilegedRunAsAnyPod.DeepCopy(),
  406. podBeforeUpdate: unprivilegedRunAsAnyPod.DeepCopy(),
  407. psps: []*policy.PodSecurityPolicy{mutating2, mutating1},
  408. shouldPassValidate: true,
  409. expectMutation: false,
  410. expectedContainerUser: nil,
  411. expectedPSP: "",
  412. },
  413. "pod should be allowed if unchanged on update except finalizers,ownerrefs": {
  414. operation: kadmission.Update,
  415. pod: gcChangedPod.DeepCopy(),
  416. podBeforeUpdate: unprivilegedRunAsAnyPod.DeepCopy(),
  417. psps: []*policy.PodSecurityPolicy{mutating2, mutating1},
  418. shouldPassValidate: true,
  419. expectMutation: false,
  420. expectedContainerUser: nil,
  421. expectedPSP: "",
  422. },
  423. }
  424. for k, v := range tests {
  425. testPSPAdmitAdvanced(k, v.operation, v.psps, nil, &user.DefaultInfo{}, v.pod, v.podBeforeUpdate, true, v.shouldPassValidate, v.expectMutation, v.expectedPSP, t)
  426. actualPodUser := (*int64)(nil)
  427. if v.pod.Spec.SecurityContext != nil {
  428. actualPodUser = v.pod.Spec.SecurityContext.RunAsUser
  429. }
  430. if actualPodUser != nil {
  431. t.Errorf("%s expected pod user nil, got %v", k, *actualPodUser)
  432. }
  433. actualContainerUser := (*int64)(nil)
  434. if v.pod.Spec.Containers[0].SecurityContext != nil {
  435. actualContainerUser = v.pod.Spec.Containers[0].SecurityContext.RunAsUser
  436. }
  437. if (actualContainerUser == nil) != (v.expectedContainerUser == nil) {
  438. t.Errorf("%s expected container user %v, got %v", k, v.expectedContainerUser, actualContainerUser)
  439. } else if actualContainerUser != nil && *actualContainerUser != *v.expectedContainerUser {
  440. t.Errorf("%s expected container user %v, got %v", k, *v.expectedContainerUser, *actualContainerUser)
  441. }
  442. }
  443. }
  444. func TestFailClosedOnInvalidPod(t *testing.T) {
  445. plugin := NewTestAdmission(nil, nil)
  446. pod := &v1.Pod{}
  447. attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
  448. err := plugin.Admit(context.TODO(), attrs, nil)
  449. if err == nil {
  450. t.Fatalf("expected versioned pod object to fail mutating admission")
  451. }
  452. if !strings.Contains(err.Error(), "unexpected type") {
  453. t.Errorf("expected type error on Admit but got: %v", err)
  454. }
  455. err = plugin.Validate(context.TODO(), attrs, nil)
  456. if err == nil {
  457. t.Fatalf("expected versioned pod object to fail validating admission")
  458. }
  459. if !strings.Contains(err.Error(), "unexpected type") {
  460. t.Errorf("expected type error on Validate but got: %v", err)
  461. }
  462. }
  463. func TestAdmitCaps(t *testing.T) {
  464. createPodWithCaps := func(caps *kapi.Capabilities) *kapi.Pod {
  465. pod := goodPod()
  466. pod.Spec.Containers[0].SecurityContext.Capabilities = caps
  467. return pod
  468. }
  469. restricted := restrictivePSP()
  470. allowsFooInAllowed := restrictivePSP()
  471. allowsFooInAllowed.Name = "allowCapInAllowed"
  472. allowsFooInAllowed.Spec.AllowedCapabilities = []v1.Capability{"foo"}
  473. allowsFooInRequired := restrictivePSP()
  474. allowsFooInRequired.Name = "allowCapInRequired"
  475. allowsFooInRequired.Spec.DefaultAddCapabilities = []v1.Capability{"foo"}
  476. requiresFooToBeDropped := restrictivePSP()
  477. requiresFooToBeDropped.Name = "requireDrop"
  478. requiresFooToBeDropped.Spec.RequiredDropCapabilities = []v1.Capability{"foo"}
  479. allowAllInAllowed := restrictivePSP()
  480. allowAllInAllowed.Name = "allowAllCapsInAllowed"
  481. allowAllInAllowed.Spec.AllowedCapabilities = []v1.Capability{policy.AllowAllCapabilities}
  482. tc := map[string]struct {
  483. pod *kapi.Pod
  484. psps []*policy.PodSecurityPolicy
  485. shouldPassAdmit bool
  486. shouldPassValidate bool
  487. expectedCapabilities *kapi.Capabilities
  488. expectedPSP string
  489. }{
  490. // UC 1: if a PSP does not define allowed or required caps then a pod requesting a cap
  491. // should be rejected.
  492. "should reject cap add when not allowed or required": {
  493. pod: createPodWithCaps(&kapi.Capabilities{Add: []kapi.Capability{"foo"}}),
  494. psps: []*policy.PodSecurityPolicy{restricted},
  495. shouldPassAdmit: false,
  496. shouldPassValidate: false,
  497. },
  498. // UC 2: if a PSP allows a cap in the allowed field it should accept the pod request
  499. // to add the cap.
  500. "should accept cap add when in allowed": {
  501. pod: createPodWithCaps(&kapi.Capabilities{Add: []kapi.Capability{"foo"}}),
  502. psps: []*policy.PodSecurityPolicy{restricted, allowsFooInAllowed},
  503. shouldPassAdmit: true,
  504. shouldPassValidate: true,
  505. expectedPSP: allowsFooInAllowed.Name,
  506. },
  507. // UC 3: if a PSP requires a cap then it should accept the pod request
  508. // to add the cap.
  509. "should accept cap add when in required": {
  510. pod: createPodWithCaps(&kapi.Capabilities{Add: []kapi.Capability{"foo"}}),
  511. psps: []*policy.PodSecurityPolicy{restricted, allowsFooInRequired},
  512. shouldPassAdmit: true,
  513. shouldPassValidate: true,
  514. expectedPSP: allowsFooInRequired.Name,
  515. },
  516. // UC 4: if a PSP requires a cap to be dropped then it should fail both
  517. // in the verification of adds and verification of drops
  518. "should reject cap add when requested cap is required to be dropped": {
  519. pod: createPodWithCaps(&kapi.Capabilities{Add: []kapi.Capability{"foo"}}),
  520. psps: []*policy.PodSecurityPolicy{restricted, requiresFooToBeDropped},
  521. shouldPassAdmit: false,
  522. shouldPassValidate: false,
  523. },
  524. // UC 5: if a PSP requires a cap to be dropped it should accept
  525. // a manual request to drop the cap.
  526. "should accept cap drop when cap is required to be dropped": {
  527. pod: createPodWithCaps(&kapi.Capabilities{Drop: []kapi.Capability{"foo"}}),
  528. psps: []*policy.PodSecurityPolicy{requiresFooToBeDropped},
  529. shouldPassAdmit: true,
  530. shouldPassValidate: true,
  531. expectedPSP: requiresFooToBeDropped.Name,
  532. },
  533. // UC 6: required add is defaulted
  534. "required add is defaulted": {
  535. pod: goodPod(),
  536. psps: []*policy.PodSecurityPolicy{allowsFooInRequired},
  537. shouldPassAdmit: true,
  538. shouldPassValidate: true,
  539. expectedCapabilities: &kapi.Capabilities{
  540. Add: []kapi.Capability{"foo"},
  541. },
  542. expectedPSP: allowsFooInRequired.Name,
  543. },
  544. // UC 7: required drop is defaulted
  545. "required drop is defaulted": {
  546. pod: goodPod(),
  547. psps: []*policy.PodSecurityPolicy{requiresFooToBeDropped},
  548. shouldPassAdmit: true,
  549. shouldPassValidate: true,
  550. expectedCapabilities: &kapi.Capabilities{
  551. Drop: []kapi.Capability{"foo"},
  552. },
  553. expectedPSP: requiresFooToBeDropped.Name,
  554. },
  555. // UC 8: using '*' in allowed caps
  556. "should accept cap add when all caps are allowed": {
  557. pod: createPodWithCaps(&kapi.Capabilities{Add: []kapi.Capability{"foo"}}),
  558. psps: []*policy.PodSecurityPolicy{restricted, allowAllInAllowed},
  559. shouldPassAdmit: true,
  560. shouldPassValidate: true,
  561. expectedPSP: allowAllInAllowed.Name,
  562. },
  563. }
  564. for k, v := range tc {
  565. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  566. if v.expectedCapabilities != nil {
  567. if !reflect.DeepEqual(v.expectedCapabilities, v.pod.Spec.Containers[0].SecurityContext.Capabilities) {
  568. t.Errorf("%s resulted in caps that were not expected - expected: %v, received: %v", k, v.expectedCapabilities, v.pod.Spec.Containers[0].SecurityContext.Capabilities)
  569. }
  570. }
  571. }
  572. for k, v := range tc {
  573. useInitContainers(v.pod)
  574. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  575. if v.expectedCapabilities != nil {
  576. if !reflect.DeepEqual(v.expectedCapabilities, v.pod.Spec.InitContainers[0].SecurityContext.Capabilities) {
  577. t.Errorf("%s resulted in caps that were not expected - expected: %v, received: %v", k, v.expectedCapabilities, v.pod.Spec.InitContainers[0].SecurityContext.Capabilities)
  578. }
  579. }
  580. }
  581. }
  582. func TestAdmitVolumes(t *testing.T) {
  583. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
  584. val := reflect.ValueOf(kapi.VolumeSource{})
  585. for i := 0; i < val.NumField(); i++ {
  586. // reflectively create the volume source
  587. fieldVal := val.Type().Field(i)
  588. volumeSource := kapi.VolumeSource{}
  589. volumeSourceVolume := reflect.New(fieldVal.Type.Elem())
  590. reflect.ValueOf(&volumeSource).Elem().FieldByName(fieldVal.Name).Set(volumeSourceVolume)
  591. volume := kapi.Volume{VolumeSource: volumeSource}
  592. // sanity check before moving on
  593. fsType, err := psputil.GetVolumeFSType(volume)
  594. if err != nil {
  595. t.Errorf("error getting FSType for %s: %s", fieldVal.Name, err.Error())
  596. continue
  597. }
  598. // add the volume to the pod
  599. pod := goodPod()
  600. pod.Spec.Volumes = []kapi.Volume{volume}
  601. // create a PSP that allows no volumes
  602. psp := restrictivePSP()
  603. // expect a denial for this PSP
  604. testPSPAdmit(fmt.Sprintf("%s denial", string(fsType)), []*policy.PodSecurityPolicy{psp}, pod, false, false, "", t)
  605. // also expect a denial for this PSP if it's an init container
  606. useInitContainers(pod)
  607. testPSPAdmit(fmt.Sprintf("%s denial", string(fsType)), []*policy.PodSecurityPolicy{psp}, pod, false, false, "", t)
  608. // now add the fstype directly to the psp and it should validate
  609. psp.Spec.Volumes = []policy.FSType{fsType}
  610. testPSPAdmit(fmt.Sprintf("%s direct accept", string(fsType)), []*policy.PodSecurityPolicy{psp}, pod, true, true, psp.Name, t)
  611. // now change the psp to allow any volumes and the pod should still validate
  612. psp.Spec.Volumes = []policy.FSType{policy.All}
  613. testPSPAdmit(fmt.Sprintf("%s wildcard accept", string(fsType)), []*policy.PodSecurityPolicy{psp}, pod, true, true, psp.Name, t)
  614. }
  615. }
  616. func TestAdmitHostNetwork(t *testing.T) {
  617. createPodWithHostNetwork := func(hostNetwork bool) *kapi.Pod {
  618. pod := goodPod()
  619. pod.Spec.SecurityContext.HostNetwork = hostNetwork
  620. return pod
  621. }
  622. noHostNetwork := restrictivePSP()
  623. noHostNetwork.Name = "no-hostnetwork"
  624. noHostNetwork.Spec.HostNetwork = false
  625. hostNetwork := restrictivePSP()
  626. hostNetwork.Name = "hostnetwork"
  627. hostNetwork.Spec.HostNetwork = true
  628. tests := map[string]struct {
  629. pod *kapi.Pod
  630. psps []*policy.PodSecurityPolicy
  631. shouldPassAdmit bool
  632. shouldPassValidate bool
  633. expectedHostNetwork bool
  634. expectedPSP string
  635. }{
  636. "pod without hostnetwork request allowed under noHostNetwork PSP": {
  637. pod: goodPod(),
  638. psps: []*policy.PodSecurityPolicy{noHostNetwork},
  639. shouldPassAdmit: true,
  640. shouldPassValidate: true,
  641. expectedHostNetwork: false,
  642. expectedPSP: noHostNetwork.Name,
  643. },
  644. "pod without hostnetwork request allowed under hostNetwork PSP": {
  645. pod: goodPod(),
  646. psps: []*policy.PodSecurityPolicy{hostNetwork},
  647. shouldPassAdmit: true,
  648. shouldPassValidate: true,
  649. expectedHostNetwork: false,
  650. expectedPSP: hostNetwork.Name,
  651. },
  652. "pod with hostnetwork request denied by noHostNetwork PSP": {
  653. pod: createPodWithHostNetwork(true),
  654. psps: []*policy.PodSecurityPolicy{noHostNetwork},
  655. shouldPassAdmit: false,
  656. shouldPassValidate: false,
  657. },
  658. "pod with hostnetwork request allowed by hostNetwork PSP": {
  659. pod: createPodWithHostNetwork(true),
  660. psps: []*policy.PodSecurityPolicy{noHostNetwork, hostNetwork},
  661. shouldPassAdmit: true,
  662. shouldPassValidate: true,
  663. expectedHostNetwork: true,
  664. expectedPSP: hostNetwork.Name,
  665. },
  666. }
  667. for k, v := range tests {
  668. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  669. if v.shouldPassAdmit {
  670. if v.pod.Spec.SecurityContext.HostNetwork != v.expectedHostNetwork {
  671. t.Errorf("%s expected hostNetwork to be %t", k, v.expectedHostNetwork)
  672. }
  673. }
  674. }
  675. // test again with init containers
  676. for k, v := range tests {
  677. useInitContainers(v.pod)
  678. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  679. if v.shouldPassAdmit {
  680. if v.pod.Spec.SecurityContext.HostNetwork != v.expectedHostNetwork {
  681. t.Errorf("%s expected hostNetwork to be %t", k, v.expectedHostNetwork)
  682. }
  683. }
  684. }
  685. }
  686. func TestAdmitHostPorts(t *testing.T) {
  687. createPodWithHostPorts := func(port int32) *kapi.Pod {
  688. pod := goodPod()
  689. pod.Spec.Containers[0].Ports = []kapi.ContainerPort{
  690. {HostPort: port},
  691. }
  692. return pod
  693. }
  694. noHostPorts := restrictivePSP()
  695. noHostPorts.Name = "noHostPorts"
  696. hostPorts := restrictivePSP()
  697. hostPorts.Name = "hostPorts"
  698. hostPorts.Spec.HostPorts = []policy.HostPortRange{
  699. {Min: 1, Max: 10},
  700. }
  701. tests := map[string]struct {
  702. pod *kapi.Pod
  703. psps []*policy.PodSecurityPolicy
  704. shouldPassAdmit bool
  705. shouldPassValidate bool
  706. expectedPSP string
  707. }{
  708. "host port out of range": {
  709. pod: createPodWithHostPorts(11),
  710. psps: []*policy.PodSecurityPolicy{hostPorts},
  711. shouldPassAdmit: false,
  712. shouldPassValidate: false,
  713. },
  714. "host port in range": {
  715. pod: createPodWithHostPorts(5),
  716. psps: []*policy.PodSecurityPolicy{hostPorts},
  717. shouldPassAdmit: true,
  718. shouldPassValidate: true,
  719. expectedPSP: hostPorts.Name,
  720. },
  721. "no host ports with range": {
  722. pod: goodPod(),
  723. psps: []*policy.PodSecurityPolicy{hostPorts},
  724. shouldPassAdmit: true,
  725. shouldPassValidate: true,
  726. expectedPSP: hostPorts.Name,
  727. },
  728. "no host ports without range": {
  729. pod: goodPod(),
  730. psps: []*policy.PodSecurityPolicy{noHostPorts},
  731. shouldPassAdmit: true,
  732. shouldPassValidate: true,
  733. expectedPSP: noHostPorts.Name,
  734. },
  735. "host ports without range": {
  736. pod: createPodWithHostPorts(5),
  737. psps: []*policy.PodSecurityPolicy{noHostPorts},
  738. shouldPassAdmit: false,
  739. shouldPassValidate: false,
  740. },
  741. }
  742. for i := 0; i < 2; i++ {
  743. for k, v := range tests {
  744. v.pod.Spec.Containers, v.pod.Spec.InitContainers = v.pod.Spec.InitContainers, v.pod.Spec.Containers
  745. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  746. }
  747. }
  748. }
  749. func TestAdmitHostPID(t *testing.T) {
  750. createPodWithHostPID := func(hostPID bool) *kapi.Pod {
  751. pod := goodPod()
  752. pod.Spec.SecurityContext.HostPID = hostPID
  753. return pod
  754. }
  755. noHostPID := restrictivePSP()
  756. noHostPID.Name = "no-hostpid"
  757. noHostPID.Spec.HostPID = false
  758. hostPID := restrictivePSP()
  759. hostPID.Name = "hostpid"
  760. hostPID.Spec.HostPID = true
  761. tests := map[string]struct {
  762. pod *kapi.Pod
  763. psps []*policy.PodSecurityPolicy
  764. shouldPassAdmit bool
  765. shouldPassValidate bool
  766. expectedHostPID bool
  767. expectedPSP string
  768. }{
  769. "pod without hostpid request allowed under noHostPID PSP": {
  770. pod: goodPod(),
  771. psps: []*policy.PodSecurityPolicy{noHostPID},
  772. shouldPassAdmit: true,
  773. shouldPassValidate: true,
  774. expectedHostPID: false,
  775. expectedPSP: noHostPID.Name,
  776. },
  777. "pod without hostpid request allowed under hostPID PSP": {
  778. pod: goodPod(),
  779. psps: []*policy.PodSecurityPolicy{hostPID},
  780. shouldPassAdmit: true,
  781. shouldPassValidate: true,
  782. expectedHostPID: false,
  783. expectedPSP: hostPID.Name,
  784. },
  785. "pod with hostpid request denied by noHostPID PSP": {
  786. pod: createPodWithHostPID(true),
  787. psps: []*policy.PodSecurityPolicy{noHostPID},
  788. shouldPassAdmit: false,
  789. },
  790. "pod with hostpid request allowed by hostPID PSP": {
  791. pod: createPodWithHostPID(true),
  792. psps: []*policy.PodSecurityPolicy{noHostPID, hostPID},
  793. shouldPassAdmit: true,
  794. shouldPassValidate: true,
  795. expectedHostPID: true,
  796. expectedPSP: hostPID.Name,
  797. },
  798. }
  799. for k, v := range tests {
  800. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  801. if v.shouldPassAdmit {
  802. if v.pod.Spec.SecurityContext.HostPID != v.expectedHostPID {
  803. t.Errorf("%s expected hostPID to be %t", k, v.expectedHostPID)
  804. }
  805. }
  806. }
  807. }
  808. func TestAdmitHostIPC(t *testing.T) {
  809. createPodWithHostIPC := func(hostIPC bool) *kapi.Pod {
  810. pod := goodPod()
  811. pod.Spec.SecurityContext.HostIPC = hostIPC
  812. return pod
  813. }
  814. noHostIPC := restrictivePSP()
  815. noHostIPC.Name = "no-hostIPC"
  816. noHostIPC.Spec.HostIPC = false
  817. hostIPC := restrictivePSP()
  818. hostIPC.Name = "hostIPC"
  819. hostIPC.Spec.HostIPC = true
  820. tests := map[string]struct {
  821. pod *kapi.Pod
  822. psps []*policy.PodSecurityPolicy
  823. shouldPassAdmit bool
  824. shouldPassValidate bool
  825. expectedHostIPC bool
  826. expectedPSP string
  827. }{
  828. "pod without hostIPC request allowed under noHostIPC PSP": {
  829. pod: goodPod(),
  830. psps: []*policy.PodSecurityPolicy{noHostIPC},
  831. shouldPassAdmit: true,
  832. shouldPassValidate: true,
  833. expectedHostIPC: false,
  834. expectedPSP: noHostIPC.Name,
  835. },
  836. "pod without hostIPC request allowed under hostIPC PSP": {
  837. pod: goodPod(),
  838. psps: []*policy.PodSecurityPolicy{hostIPC},
  839. shouldPassAdmit: true,
  840. shouldPassValidate: true,
  841. expectedHostIPC: false,
  842. expectedPSP: hostIPC.Name,
  843. },
  844. "pod with hostIPC request denied by noHostIPC PSP": {
  845. pod: createPodWithHostIPC(true),
  846. psps: []*policy.PodSecurityPolicy{noHostIPC},
  847. shouldPassAdmit: false,
  848. shouldPassValidate: false,
  849. },
  850. "pod with hostIPC request allowed by hostIPC PSP": {
  851. pod: createPodWithHostIPC(true),
  852. psps: []*policy.PodSecurityPolicy{noHostIPC, hostIPC},
  853. shouldPassAdmit: true,
  854. shouldPassValidate: true,
  855. expectedHostIPC: true,
  856. expectedPSP: hostIPC.Name,
  857. },
  858. }
  859. for k, v := range tests {
  860. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  861. if v.shouldPassAdmit {
  862. if v.pod.Spec.SecurityContext.HostIPC != v.expectedHostIPC {
  863. t.Errorf("%s expected hostIPC to be %t", k, v.expectedHostIPC)
  864. }
  865. }
  866. }
  867. }
  868. func createPodWithSecurityContexts(podSC *kapi.PodSecurityContext, containerSC *kapi.SecurityContext) *kapi.Pod {
  869. pod := goodPod()
  870. pod.Spec.SecurityContext = podSC
  871. pod.Spec.Containers[0].SecurityContext = containerSC
  872. return pod
  873. }
  874. func TestAdmitSELinux(t *testing.T) {
  875. runAsAny := permissivePSP()
  876. runAsAny.Name = "runAsAny"
  877. runAsAny.Spec.SELinux.Rule = policy.SELinuxStrategyRunAsAny
  878. runAsAny.Spec.SELinux.SELinuxOptions = nil
  879. mustRunAs := permissivePSP()
  880. mustRunAs.Name = "mustRunAs"
  881. mustRunAs.Spec.SELinux.Rule = policy.SELinuxStrategyMustRunAs
  882. mustRunAs.Spec.SELinux.SELinuxOptions = &v1.SELinuxOptions{}
  883. mustRunAs.Spec.SELinux.SELinuxOptions.Level = "level"
  884. mustRunAs.Spec.SELinux.SELinuxOptions.Role = "role"
  885. mustRunAs.Spec.SELinux.SELinuxOptions.Type = "type"
  886. mustRunAs.Spec.SELinux.SELinuxOptions.User = "user"
  887. getInternalSEOptions := func(policy *policy.PodSecurityPolicy) *kapi.SELinuxOptions {
  888. opt := kapi.SELinuxOptions{}
  889. k8s_api_v1.Convert_v1_SELinuxOptions_To_core_SELinuxOptions(policy.Spec.SELinux.SELinuxOptions, &opt, nil)
  890. return &opt
  891. }
  892. tests := map[string]struct {
  893. pod *kapi.Pod
  894. psps []*policy.PodSecurityPolicy
  895. shouldPassAdmit bool
  896. shouldPassValidate bool
  897. expectedPodSC *kapi.PodSecurityContext
  898. expectedContainerSC *kapi.SecurityContext
  899. expectedPSP string
  900. }{
  901. "runAsAny with no request": {
  902. pod: createPodWithSecurityContexts(nil, nil),
  903. psps: []*policy.PodSecurityPolicy{runAsAny},
  904. shouldPassAdmit: true,
  905. shouldPassValidate: true,
  906. expectedPodSC: nil,
  907. expectedContainerSC: nil,
  908. expectedPSP: runAsAny.Name,
  909. },
  910. "runAsAny with empty pod request": {
  911. pod: createPodWithSecurityContexts(&kapi.PodSecurityContext{}, nil),
  912. psps: []*policy.PodSecurityPolicy{runAsAny},
  913. shouldPassAdmit: true,
  914. shouldPassValidate: true,
  915. expectedPodSC: &kapi.PodSecurityContext{},
  916. expectedContainerSC: nil,
  917. expectedPSP: runAsAny.Name,
  918. },
  919. "runAsAny with empty container request": {
  920. pod: createPodWithSecurityContexts(nil, &kapi.SecurityContext{}),
  921. psps: []*policy.PodSecurityPolicy{runAsAny},
  922. shouldPassAdmit: true,
  923. shouldPassValidate: true,
  924. expectedPodSC: nil,
  925. expectedContainerSC: &kapi.SecurityContext{},
  926. expectedPSP: runAsAny.Name,
  927. },
  928. "runAsAny with pod request": {
  929. pod: createPodWithSecurityContexts(&kapi.PodSecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "foo"}}, nil),
  930. psps: []*policy.PodSecurityPolicy{runAsAny},
  931. shouldPassAdmit: true,
  932. shouldPassValidate: true,
  933. expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "foo"}},
  934. expectedContainerSC: nil,
  935. expectedPSP: runAsAny.Name,
  936. },
  937. "runAsAny with container request": {
  938. pod: createPodWithSecurityContexts(nil, &kapi.SecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "foo"}}),
  939. psps: []*policy.PodSecurityPolicy{runAsAny},
  940. shouldPassAdmit: true,
  941. shouldPassValidate: true,
  942. expectedPodSC: nil,
  943. expectedContainerSC: &kapi.SecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "foo"}},
  944. expectedPSP: runAsAny.Name,
  945. },
  946. "runAsAny with pod and container request": {
  947. pod: createPodWithSecurityContexts(&kapi.PodSecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "bar"}}, &kapi.SecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "foo"}}),
  948. psps: []*policy.PodSecurityPolicy{runAsAny},
  949. shouldPassAdmit: true,
  950. shouldPassValidate: true,
  951. expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "bar"}},
  952. expectedContainerSC: &kapi.SecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "foo"}},
  953. expectedPSP: runAsAny.Name,
  954. },
  955. "mustRunAs with bad pod request": {
  956. pod: createPodWithSecurityContexts(&kapi.PodSecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "foo"}}, nil),
  957. psps: []*policy.PodSecurityPolicy{mustRunAs},
  958. shouldPassAdmit: false,
  959. shouldPassValidate: false,
  960. },
  961. "mustRunAs with bad container request": {
  962. pod: createPodWithSecurityContexts(nil, &kapi.SecurityContext{SELinuxOptions: &kapi.SELinuxOptions{User: "foo"}}),
  963. psps: []*policy.PodSecurityPolicy{mustRunAs},
  964. shouldPassAdmit: false,
  965. shouldPassValidate: false,
  966. },
  967. "mustRunAs with no request": {
  968. pod: createPodWithSecurityContexts(nil, nil),
  969. psps: []*policy.PodSecurityPolicy{mustRunAs},
  970. shouldPassAdmit: true,
  971. shouldPassValidate: true,
  972. expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: getInternalSEOptions(mustRunAs)},
  973. expectedContainerSC: nil,
  974. expectedPSP: mustRunAs.Name,
  975. },
  976. "mustRunAs with good pod request": {
  977. pod: createPodWithSecurityContexts(
  978. &kapi.PodSecurityContext{SELinuxOptions: &kapi.SELinuxOptions{Level: "level", Role: "role", Type: "type", User: "user"}},
  979. nil,
  980. ),
  981. psps: []*policy.PodSecurityPolicy{mustRunAs},
  982. shouldPassAdmit: true,
  983. shouldPassValidate: true,
  984. expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: getInternalSEOptions(mustRunAs)},
  985. expectedContainerSC: nil,
  986. expectedPSP: mustRunAs.Name,
  987. },
  988. "mustRunAs with good container request": {
  989. pod: createPodWithSecurityContexts(
  990. &kapi.PodSecurityContext{SELinuxOptions: &kapi.SELinuxOptions{Level: "level", Role: "role", Type: "type", User: "user"}},
  991. nil,
  992. ),
  993. psps: []*policy.PodSecurityPolicy{mustRunAs},
  994. shouldPassAdmit: true,
  995. shouldPassValidate: true,
  996. expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: getInternalSEOptions(mustRunAs)},
  997. expectedContainerSC: nil,
  998. expectedPSP: mustRunAs.Name,
  999. },
  1000. }
  1001. for k, v := range tests {
  1002. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  1003. if v.shouldPassAdmit {
  1004. if !reflect.DeepEqual(v.expectedPodSC, v.pod.Spec.SecurityContext) {
  1005. t.Errorf("%s unexpected diff:\n%s", k, diff.ObjectGoPrintSideBySide(v.expectedPodSC, v.pod.Spec.SecurityContext))
  1006. }
  1007. if !reflect.DeepEqual(v.expectedContainerSC, v.pod.Spec.Containers[0].SecurityContext) {
  1008. t.Errorf("%s unexpected diff:\n%s", k, diff.ObjectGoPrintSideBySide(v.expectedContainerSC, v.pod.Spec.Containers[0].SecurityContext))
  1009. }
  1010. }
  1011. }
  1012. }
  1013. func TestAdmitAppArmor(t *testing.T) {
  1014. createPodWithAppArmor := func(profile string) *kapi.Pod {
  1015. pod := goodPod()
  1016. apparmor.SetProfileNameFromPodAnnotations(pod.Annotations, defaultContainerName, profile)
  1017. return pod
  1018. }
  1019. unconstrainedPSP := restrictivePSP()
  1020. defaultedPSP := restrictivePSP()
  1021. defaultedPSP.Annotations = map[string]string{
  1022. apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault,
  1023. }
  1024. appArmorPSP := restrictivePSP()
  1025. appArmorPSP.Annotations = map[string]string{
  1026. apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault,
  1027. }
  1028. appArmorDefaultPSP := restrictivePSP()
  1029. appArmorDefaultPSP.Annotations = map[string]string{
  1030. apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault,
  1031. apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault + "," + apparmor.ProfileNamePrefix + "foo",
  1032. }
  1033. tests := map[string]struct {
  1034. pod *kapi.Pod
  1035. psp *policy.PodSecurityPolicy
  1036. shouldPassAdmit bool
  1037. shouldPassValidate bool
  1038. expectedProfile string
  1039. }{
  1040. "unconstrained with no profile": {
  1041. pod: goodPod(),
  1042. psp: unconstrainedPSP,
  1043. shouldPassAdmit: true,
  1044. shouldPassValidate: true,
  1045. expectedProfile: "",
  1046. },
  1047. "unconstrained with profile": {
  1048. pod: createPodWithAppArmor(apparmor.ProfileRuntimeDefault),
  1049. psp: unconstrainedPSP,
  1050. shouldPassAdmit: true,
  1051. shouldPassValidate: true,
  1052. expectedProfile: apparmor.ProfileRuntimeDefault,
  1053. },
  1054. "unconstrained with default profile": {
  1055. pod: goodPod(),
  1056. psp: defaultedPSP,
  1057. shouldPassAdmit: true,
  1058. shouldPassValidate: true,
  1059. expectedProfile: apparmor.ProfileRuntimeDefault,
  1060. },
  1061. "AppArmor enforced with no profile": {
  1062. pod: goodPod(),
  1063. psp: appArmorPSP,
  1064. shouldPassAdmit: false,
  1065. shouldPassValidate: false,
  1066. },
  1067. "AppArmor enforced with default profile": {
  1068. pod: goodPod(),
  1069. psp: appArmorDefaultPSP,
  1070. shouldPassAdmit: true,
  1071. shouldPassValidate: true,
  1072. expectedProfile: apparmor.ProfileRuntimeDefault,
  1073. },
  1074. "AppArmor enforced with good profile": {
  1075. pod: createPodWithAppArmor(apparmor.ProfileNamePrefix + "foo"),
  1076. psp: appArmorDefaultPSP,
  1077. shouldPassAdmit: true,
  1078. shouldPassValidate: true,
  1079. expectedProfile: apparmor.ProfileNamePrefix + "foo",
  1080. },
  1081. "AppArmor enforced with local profile": {
  1082. pod: createPodWithAppArmor(apparmor.ProfileNamePrefix + "bar"),
  1083. psp: appArmorPSP,
  1084. shouldPassAdmit: false,
  1085. shouldPassValidate: false,
  1086. },
  1087. }
  1088. for k, v := range tests {
  1089. testPSPAdmit(k, []*policy.PodSecurityPolicy{v.psp}, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.psp.Name, t)
  1090. if v.shouldPassAdmit {
  1091. assert.Equal(t, v.expectedProfile, apparmor.GetProfileNameFromPodAnnotations(v.pod.Annotations, defaultContainerName), k)
  1092. }
  1093. }
  1094. }
  1095. func TestAdmitRunAsUser(t *testing.T) {
  1096. podSC := func(user *int64) *kapi.PodSecurityContext {
  1097. return &kapi.PodSecurityContext{RunAsUser: user}
  1098. }
  1099. containerSC := func(user *int64) *kapi.SecurityContext {
  1100. return &kapi.SecurityContext{RunAsUser: user}
  1101. }
  1102. runAsAny := permissivePSP()
  1103. runAsAny.Name = "runAsAny"
  1104. runAsAny.Spec.RunAsUser.Rule = policy.RunAsUserStrategyRunAsAny
  1105. mustRunAs := permissivePSP()
  1106. mustRunAs.Name = "mustRunAs"
  1107. mustRunAs.Spec.RunAsUser.Rule = policy.RunAsUserStrategyMustRunAs
  1108. mustRunAs.Spec.RunAsUser.Ranges = []policy.IDRange{
  1109. {Min: int64(999), Max: int64(1000)},
  1110. }
  1111. runAsNonRoot := permissivePSP()
  1112. runAsNonRoot.Name = "runAsNonRoot"
  1113. runAsNonRoot.Spec.RunAsUser.Rule = policy.RunAsUserStrategyMustRunAsNonRoot
  1114. trueValue := true
  1115. tests := map[string]struct {
  1116. pod *kapi.Pod
  1117. psps []*policy.PodSecurityPolicy
  1118. shouldPassAdmit bool
  1119. shouldPassValidate bool
  1120. expectedPodSC *kapi.PodSecurityContext
  1121. expectedContainerSC *kapi.SecurityContext
  1122. expectedPSP string
  1123. }{
  1124. "runAsAny no pod request": {
  1125. pod: createPodWithSecurityContexts(nil, nil),
  1126. psps: []*policy.PodSecurityPolicy{runAsAny},
  1127. shouldPassAdmit: true,
  1128. shouldPassValidate: true,
  1129. expectedPodSC: nil,
  1130. expectedContainerSC: nil,
  1131. expectedPSP: runAsAny.Name,
  1132. },
  1133. "runAsAny pod request": {
  1134. pod: createPodWithSecurityContexts(podSC(utilpointer.Int64Ptr(1)), nil),
  1135. psps: []*policy.PodSecurityPolicy{runAsAny},
  1136. shouldPassAdmit: true,
  1137. shouldPassValidate: true,
  1138. expectedPodSC: podSC(utilpointer.Int64Ptr(1)),
  1139. expectedContainerSC: nil,
  1140. expectedPSP: runAsAny.Name,
  1141. },
  1142. "runAsAny container request": {
  1143. pod: createPodWithSecurityContexts(nil, containerSC(utilpointer.Int64Ptr(1))),
  1144. psps: []*policy.PodSecurityPolicy{runAsAny},
  1145. shouldPassAdmit: true,
  1146. shouldPassValidate: true,
  1147. expectedPodSC: nil,
  1148. expectedContainerSC: containerSC(utilpointer.Int64Ptr(1)),
  1149. expectedPSP: runAsAny.Name,
  1150. },
  1151. "mustRunAs pod request out of range": {
  1152. pod: createPodWithSecurityContexts(podSC(utilpointer.Int64Ptr(1)), nil),
  1153. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1154. shouldPassAdmit: false,
  1155. shouldPassValidate: false,
  1156. },
  1157. "mustRunAs container request out of range": {
  1158. pod: createPodWithSecurityContexts(podSC(utilpointer.Int64Ptr(999)), containerSC(utilpointer.Int64Ptr(1))),
  1159. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1160. shouldPassAdmit: false,
  1161. shouldPassValidate: false,
  1162. },
  1163. "mustRunAs pod request in range": {
  1164. pod: createPodWithSecurityContexts(podSC(utilpointer.Int64Ptr(999)), nil),
  1165. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1166. shouldPassAdmit: true,
  1167. shouldPassValidate: true,
  1168. expectedPodSC: podSC(&mustRunAs.Spec.RunAsUser.Ranges[0].Min),
  1169. expectedContainerSC: nil,
  1170. expectedPSP: mustRunAs.Name,
  1171. },
  1172. "mustRunAs container request in range": {
  1173. pod: createPodWithSecurityContexts(nil, containerSC(utilpointer.Int64Ptr(999))),
  1174. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1175. shouldPassAdmit: true,
  1176. shouldPassValidate: true,
  1177. expectedPodSC: nil,
  1178. expectedContainerSC: containerSC(&mustRunAs.Spec.RunAsUser.Ranges[0].Min),
  1179. expectedPSP: mustRunAs.Name,
  1180. },
  1181. "mustRunAs pod and container request in range": {
  1182. pod: createPodWithSecurityContexts(podSC(utilpointer.Int64Ptr(999)), containerSC(utilpointer.Int64Ptr(1000))),
  1183. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1184. shouldPassAdmit: true,
  1185. shouldPassValidate: true,
  1186. expectedPodSC: podSC(utilpointer.Int64Ptr(999)),
  1187. expectedContainerSC: containerSC(utilpointer.Int64Ptr(1000)),
  1188. expectedPSP: mustRunAs.Name,
  1189. },
  1190. "mustRunAs no request": {
  1191. pod: createPodWithSecurityContexts(nil, nil),
  1192. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1193. shouldPassAdmit: true,
  1194. shouldPassValidate: true,
  1195. expectedPodSC: nil,
  1196. expectedContainerSC: containerSC(&mustRunAs.Spec.RunAsUser.Ranges[0].Min),
  1197. expectedPSP: mustRunAs.Name,
  1198. },
  1199. "runAsNonRoot no request": {
  1200. pod: createPodWithSecurityContexts(nil, nil),
  1201. psps: []*policy.PodSecurityPolicy{runAsNonRoot},
  1202. shouldPassAdmit: true,
  1203. shouldPassValidate: true,
  1204. expectedPodSC: nil,
  1205. expectedContainerSC: &kapi.SecurityContext{RunAsNonRoot: &trueValue},
  1206. expectedPSP: runAsNonRoot.Name,
  1207. },
  1208. "runAsNonRoot pod request root": {
  1209. pod: createPodWithSecurityContexts(podSC(utilpointer.Int64Ptr(0)), nil),
  1210. psps: []*policy.PodSecurityPolicy{runAsNonRoot},
  1211. shouldPassAdmit: false,
  1212. shouldPassValidate: false,
  1213. },
  1214. "runAsNonRoot pod request non-root": {
  1215. pod: createPodWithSecurityContexts(podSC(utilpointer.Int64Ptr(1)), nil),
  1216. psps: []*policy.PodSecurityPolicy{runAsNonRoot},
  1217. shouldPassAdmit: true,
  1218. shouldPassValidate: true,
  1219. expectedPodSC: podSC(utilpointer.Int64Ptr(1)),
  1220. expectedPSP: runAsNonRoot.Name,
  1221. },
  1222. "runAsNonRoot container request root": {
  1223. pod: createPodWithSecurityContexts(podSC(utilpointer.Int64Ptr(1)), containerSC(utilpointer.Int64Ptr(0))),
  1224. psps: []*policy.PodSecurityPolicy{runAsNonRoot},
  1225. shouldPassAdmit: false,
  1226. shouldPassValidate: false,
  1227. },
  1228. "runAsNonRoot container request non-root": {
  1229. pod: createPodWithSecurityContexts(podSC(utilpointer.Int64Ptr(1)), containerSC(utilpointer.Int64Ptr(2))),
  1230. psps: []*policy.PodSecurityPolicy{runAsNonRoot},
  1231. shouldPassAdmit: true,
  1232. shouldPassValidate: true,
  1233. expectedPodSC: podSC(utilpointer.Int64Ptr(1)),
  1234. expectedContainerSC: containerSC(utilpointer.Int64Ptr(2)),
  1235. expectedPSP: runAsNonRoot.Name,
  1236. },
  1237. }
  1238. for k, v := range tests {
  1239. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  1240. if v.shouldPassAdmit {
  1241. if !reflect.DeepEqual(v.expectedPodSC, v.pod.Spec.SecurityContext) {
  1242. t.Errorf("%s unexpected pod sc diff:\n%s", k, diff.ObjectGoPrintSideBySide(v.expectedPodSC, v.pod.Spec.SecurityContext))
  1243. }
  1244. if !reflect.DeepEqual(v.expectedContainerSC, v.pod.Spec.Containers[0].SecurityContext) {
  1245. t.Errorf("%s unexpected container sc diff:\n%s", k, diff.ObjectGoPrintSideBySide(v.expectedContainerSC, v.pod.Spec.Containers[0].SecurityContext))
  1246. }
  1247. }
  1248. }
  1249. }
  1250. func TestAdmitSupplementalGroups(t *testing.T) {
  1251. podSC := func(group int64) *kapi.PodSecurityContext {
  1252. return &kapi.PodSecurityContext{SupplementalGroups: []int64{group}}
  1253. }
  1254. runAsAny := permissivePSP()
  1255. runAsAny.Name = "runAsAny"
  1256. runAsAny.Spec.SupplementalGroups.Rule = policy.SupplementalGroupsStrategyRunAsAny
  1257. mustRunAs := permissivePSP()
  1258. mustRunAs.Name = "mustRunAs"
  1259. mustRunAs.Spec.SupplementalGroups.Rule = policy.SupplementalGroupsStrategyMustRunAs
  1260. mustRunAs.Spec.SupplementalGroups.Ranges = []policy.IDRange{{Min: int64(999), Max: int64(1000)}}
  1261. tests := map[string]struct {
  1262. pod *kapi.Pod
  1263. psps []*policy.PodSecurityPolicy
  1264. shouldPassAdmit bool
  1265. shouldPassValidate bool
  1266. expectedPodSC *kapi.PodSecurityContext
  1267. expectedPSP string
  1268. }{
  1269. "runAsAny no pod request": {
  1270. pod: createPodWithSecurityContexts(nil, nil),
  1271. psps: []*policy.PodSecurityPolicy{runAsAny},
  1272. shouldPassAdmit: true,
  1273. shouldPassValidate: true,
  1274. expectedPodSC: nil,
  1275. expectedPSP: runAsAny.Name,
  1276. },
  1277. "runAsAny empty pod request": {
  1278. pod: createPodWithSecurityContexts(&kapi.PodSecurityContext{}, nil),
  1279. psps: []*policy.PodSecurityPolicy{runAsAny},
  1280. shouldPassAdmit: true,
  1281. shouldPassValidate: true,
  1282. expectedPodSC: &kapi.PodSecurityContext{},
  1283. expectedPSP: runAsAny.Name,
  1284. },
  1285. "runAsAny empty pod request empty supplemental groups": {
  1286. pod: createPodWithSecurityContexts(&kapi.PodSecurityContext{SupplementalGroups: []int64{}}, nil),
  1287. psps: []*policy.PodSecurityPolicy{runAsAny},
  1288. shouldPassAdmit: true,
  1289. shouldPassValidate: true,
  1290. expectedPodSC: &kapi.PodSecurityContext{SupplementalGroups: []int64{}},
  1291. expectedPSP: runAsAny.Name,
  1292. },
  1293. "runAsAny pod request": {
  1294. pod: createPodWithSecurityContexts(podSC(1), nil),
  1295. psps: []*policy.PodSecurityPolicy{runAsAny},
  1296. shouldPassAdmit: true,
  1297. shouldPassValidate: true,
  1298. expectedPodSC: &kapi.PodSecurityContext{SupplementalGroups: []int64{1}},
  1299. expectedPSP: runAsAny.Name,
  1300. },
  1301. "mustRunAs no pod request": {
  1302. pod: createPodWithSecurityContexts(nil, nil),
  1303. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1304. shouldPassAdmit: true,
  1305. shouldPassValidate: true,
  1306. expectedPodSC: podSC(mustRunAs.Spec.SupplementalGroups.Ranges[0].Min),
  1307. expectedPSP: mustRunAs.Name,
  1308. },
  1309. "mustRunAs bad pod request": {
  1310. pod: createPodWithSecurityContexts(podSC(1), nil),
  1311. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1312. shouldPassAdmit: false,
  1313. shouldPassValidate: false,
  1314. },
  1315. "mustRunAs good pod request": {
  1316. pod: createPodWithSecurityContexts(podSC(999), nil),
  1317. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1318. shouldPassAdmit: true,
  1319. shouldPassValidate: true,
  1320. expectedPodSC: podSC(999),
  1321. expectedPSP: mustRunAs.Name,
  1322. },
  1323. }
  1324. for k, v := range tests {
  1325. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  1326. if v.shouldPassAdmit {
  1327. if !reflect.DeepEqual(v.expectedPodSC, v.pod.Spec.SecurityContext) {
  1328. t.Errorf("%s unexpected pod sc diff:\n%s", k, diff.ObjectGoPrintSideBySide(v.expectedPodSC, v.pod.Spec.SecurityContext))
  1329. }
  1330. }
  1331. }
  1332. }
  1333. func TestAdmitFSGroup(t *testing.T) {
  1334. createPodWithFSGroup := func(group int64) *kapi.Pod {
  1335. pod := goodPod()
  1336. // doesn't matter if we set it here or on the container, the
  1337. // admission controller uses DetermineEffectiveSC to get the defaulting
  1338. // behavior so it can validate what will be applied at runtime
  1339. pod.Spec.SecurityContext.FSGroup = utilpointer.Int64Ptr(group)
  1340. return pod
  1341. }
  1342. runAsAny := restrictivePSP()
  1343. runAsAny.Name = "runAsAny"
  1344. runAsAny.Spec.FSGroup.Rule = policy.FSGroupStrategyRunAsAny
  1345. mustRunAs := restrictivePSP()
  1346. mustRunAs.Name = "mustRunAs"
  1347. tests := map[string]struct {
  1348. pod *kapi.Pod
  1349. psps []*policy.PodSecurityPolicy
  1350. shouldPassAdmit bool
  1351. shouldPassValidate bool
  1352. expectedFSGroup *int64
  1353. expectedPSP string
  1354. }{
  1355. "runAsAny no pod request": {
  1356. pod: goodPod(),
  1357. psps: []*policy.PodSecurityPolicy{runAsAny},
  1358. shouldPassAdmit: true,
  1359. shouldPassValidate: true,
  1360. expectedFSGroup: nil,
  1361. expectedPSP: runAsAny.Name,
  1362. },
  1363. "runAsAny pod request": {
  1364. pod: createPodWithFSGroup(1),
  1365. psps: []*policy.PodSecurityPolicy{runAsAny},
  1366. shouldPassAdmit: true,
  1367. shouldPassValidate: true,
  1368. expectedFSGroup: utilpointer.Int64Ptr(1),
  1369. expectedPSP: runAsAny.Name,
  1370. },
  1371. "mustRunAs no pod request": {
  1372. pod: goodPod(),
  1373. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1374. shouldPassAdmit: true,
  1375. shouldPassValidate: true,
  1376. expectedFSGroup: &mustRunAs.Spec.SupplementalGroups.Ranges[0].Min,
  1377. expectedPSP: mustRunAs.Name,
  1378. },
  1379. "mustRunAs bad pod request": {
  1380. pod: createPodWithFSGroup(1),
  1381. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1382. shouldPassAdmit: false,
  1383. shouldPassValidate: false,
  1384. },
  1385. "mustRunAs good pod request": {
  1386. pod: createPodWithFSGroup(999),
  1387. psps: []*policy.PodSecurityPolicy{mustRunAs},
  1388. shouldPassAdmit: true,
  1389. shouldPassValidate: true,
  1390. expectedFSGroup: utilpointer.Int64Ptr(999),
  1391. expectedPSP: mustRunAs.Name,
  1392. },
  1393. }
  1394. for k, v := range tests {
  1395. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  1396. if v.shouldPassAdmit {
  1397. if v.pod.Spec.SecurityContext.FSGroup == nil && v.expectedFSGroup == nil {
  1398. // ok, don't need to worry about identifying specific diffs
  1399. continue
  1400. }
  1401. if v.pod.Spec.SecurityContext.FSGroup == nil && v.expectedFSGroup != nil {
  1402. t.Errorf("%s expected FSGroup to be: %v but found nil", k, *v.expectedFSGroup)
  1403. continue
  1404. }
  1405. if v.pod.Spec.SecurityContext.FSGroup != nil && v.expectedFSGroup == nil {
  1406. t.Errorf("%s expected FSGroup to be nil but found: %v", k, *v.pod.Spec.SecurityContext.FSGroup)
  1407. continue
  1408. }
  1409. if *v.expectedFSGroup != *v.pod.Spec.SecurityContext.FSGroup {
  1410. t.Errorf("%s expected FSGroup to be: %v but found %v", k, *v.expectedFSGroup, *v.pod.Spec.SecurityContext.FSGroup)
  1411. }
  1412. }
  1413. }
  1414. }
  1415. func TestAdmitReadOnlyRootFilesystem(t *testing.T) {
  1416. createPodWithRORFS := func(rorfs bool) *kapi.Pod {
  1417. pod := goodPod()
  1418. pod.Spec.Containers[0].SecurityContext.ReadOnlyRootFilesystem = &rorfs
  1419. return pod
  1420. }
  1421. noRORFS := restrictivePSP()
  1422. noRORFS.Name = "no-rorfs"
  1423. noRORFS.Spec.ReadOnlyRootFilesystem = false
  1424. rorfs := restrictivePSP()
  1425. rorfs.Name = "rorfs"
  1426. rorfs.Spec.ReadOnlyRootFilesystem = true
  1427. tests := map[string]struct {
  1428. pod *kapi.Pod
  1429. psps []*policy.PodSecurityPolicy
  1430. shouldPassAdmit bool
  1431. shouldPassValidate bool
  1432. expectedRORFS bool
  1433. expectedPSP string
  1434. }{
  1435. "no-rorfs allows pod request with rorfs": {
  1436. pod: createPodWithRORFS(true),
  1437. psps: []*policy.PodSecurityPolicy{noRORFS},
  1438. shouldPassAdmit: true,
  1439. shouldPassValidate: true,
  1440. expectedRORFS: true,
  1441. expectedPSP: noRORFS.Name,
  1442. },
  1443. "no-rorfs allows pod request without rorfs": {
  1444. pod: createPodWithRORFS(false),
  1445. psps: []*policy.PodSecurityPolicy{noRORFS},
  1446. shouldPassAdmit: true,
  1447. shouldPassValidate: true,
  1448. expectedRORFS: false,
  1449. expectedPSP: noRORFS.Name,
  1450. },
  1451. "rorfs rejects pod request without rorfs": {
  1452. pod: createPodWithRORFS(false),
  1453. psps: []*policy.PodSecurityPolicy{rorfs},
  1454. shouldPassAdmit: false,
  1455. shouldPassValidate: false,
  1456. },
  1457. "rorfs defaults nil pod request": {
  1458. pod: goodPod(),
  1459. psps: []*policy.PodSecurityPolicy{rorfs},
  1460. shouldPassAdmit: true,
  1461. shouldPassValidate: true,
  1462. expectedRORFS: true,
  1463. expectedPSP: rorfs.Name,
  1464. },
  1465. "rorfs accepts pod request with rorfs": {
  1466. pod: createPodWithRORFS(true),
  1467. psps: []*policy.PodSecurityPolicy{rorfs},
  1468. shouldPassAdmit: true,
  1469. shouldPassValidate: true,
  1470. expectedRORFS: true,
  1471. expectedPSP: rorfs.Name,
  1472. },
  1473. }
  1474. for k, v := range tests {
  1475. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  1476. if v.shouldPassAdmit {
  1477. if v.pod.Spec.Containers[0].SecurityContext.ReadOnlyRootFilesystem == nil ||
  1478. *v.pod.Spec.Containers[0].SecurityContext.ReadOnlyRootFilesystem != v.expectedRORFS {
  1479. t.Errorf("%s expected ReadOnlyRootFilesystem to be %t but found %#v", k, v.expectedRORFS, v.pod.Spec.Containers[0].SecurityContext.ReadOnlyRootFilesystem)
  1480. }
  1481. }
  1482. }
  1483. }
  1484. func TestAdmitSysctls(t *testing.T) {
  1485. podWithSysctls := func(safeSysctls []string, unsafeSysctls []string) *kapi.Pod {
  1486. pod := goodPod()
  1487. dummySysctls := func(names []string) []kapi.Sysctl {
  1488. sysctls := make([]kapi.Sysctl, len(names))
  1489. for i, n := range names {
  1490. sysctls[i].Name = n
  1491. sysctls[i].Value = "dummy"
  1492. }
  1493. return sysctls
  1494. }
  1495. pod.Spec.SecurityContext = &kapi.PodSecurityContext{
  1496. Sysctls: dummySysctls(append(safeSysctls, unsafeSysctls...)),
  1497. }
  1498. return pod
  1499. }
  1500. safeSysctls := restrictivePSP()
  1501. safeSysctls.Name = "no sysctls"
  1502. noSysctls := restrictivePSP()
  1503. noSysctls.Name = "empty sysctls"
  1504. noSysctls.Spec.ForbiddenSysctls = []string{"*"}
  1505. mixedSysctls := restrictivePSP()
  1506. mixedSysctls.Name = "wildcard sysctls"
  1507. mixedSysctls.Spec.ForbiddenSysctls = []string{"net.*"}
  1508. mixedSysctls.Spec.AllowedUnsafeSysctls = []string{"a.*", "b.*"}
  1509. aUnsafeSysctl := restrictivePSP()
  1510. aUnsafeSysctl.Name = "a sysctl"
  1511. aUnsafeSysctl.Spec.AllowedUnsafeSysctls = []string{"a"}
  1512. bUnsafeSysctl := restrictivePSP()
  1513. bUnsafeSysctl.Name = "b sysctl"
  1514. bUnsafeSysctl.Spec.AllowedUnsafeSysctls = []string{"b"}
  1515. cUnsafeSysctl := restrictivePSP()
  1516. cUnsafeSysctl.Name = "c sysctl"
  1517. cUnsafeSysctl.Spec.AllowedUnsafeSysctls = []string{"c"}
  1518. catchallSysctls := restrictivePSP()
  1519. catchallSysctls.Name = "catchall sysctl"
  1520. catchallSysctls.Spec.AllowedUnsafeSysctls = []string{"*"}
  1521. tests := map[string]struct {
  1522. pod *kapi.Pod
  1523. psps []*policy.PodSecurityPolicy
  1524. shouldPassAdmit bool
  1525. shouldPassValidate bool
  1526. expectedPSP string
  1527. }{
  1528. "pod without any sysctls request allowed under safeSysctls PSP": {
  1529. pod: goodPod(),
  1530. psps: []*policy.PodSecurityPolicy{safeSysctls},
  1531. shouldPassAdmit: true,
  1532. shouldPassValidate: true,
  1533. expectedPSP: safeSysctls.Name,
  1534. },
  1535. "pod without any sysctls request allowed under noSysctls PSP": {
  1536. pod: goodPod(),
  1537. psps: []*policy.PodSecurityPolicy{noSysctls},
  1538. shouldPassAdmit: true,
  1539. shouldPassValidate: true,
  1540. expectedPSP: noSysctls.Name,
  1541. },
  1542. "pod with safe sysctls request allowed under safeSysctls PSP": {
  1543. pod: podWithSysctls([]string{"kernel.shm_rmid_forced", "net.ipv4.tcp_syncookies"}, []string{}),
  1544. psps: []*policy.PodSecurityPolicy{safeSysctls},
  1545. shouldPassAdmit: true,
  1546. shouldPassValidate: true,
  1547. expectedPSP: safeSysctls.Name,
  1548. },
  1549. "pod with unsafe sysctls request disallowed under noSysctls PSP": {
  1550. pod: podWithSysctls([]string{}, []string{"a", "b"}),
  1551. psps: []*policy.PodSecurityPolicy{noSysctls},
  1552. shouldPassAdmit: false,
  1553. shouldPassValidate: false,
  1554. expectedPSP: noSysctls.Name,
  1555. },
  1556. "pod with unsafe sysctls a, b request disallowed under aUnsafeSysctl SCC": {
  1557. pod: podWithSysctls([]string{}, []string{"a", "b"}),
  1558. psps: []*policy.PodSecurityPolicy{aUnsafeSysctl},
  1559. shouldPassAdmit: false,
  1560. shouldPassValidate: false,
  1561. },
  1562. "pod with unsafe sysctls b request disallowed under aUnsafeSysctl SCC": {
  1563. pod: podWithSysctls([]string{}, []string{"b"}),
  1564. psps: []*policy.PodSecurityPolicy{aUnsafeSysctl},
  1565. shouldPassAdmit: false,
  1566. shouldPassValidate: false,
  1567. },
  1568. "pod with unsafe sysctls a request allowed under aUnsafeSysctl SCC": {
  1569. pod: podWithSysctls([]string{}, []string{"a"}),
  1570. psps: []*policy.PodSecurityPolicy{aUnsafeSysctl},
  1571. shouldPassAdmit: true,
  1572. shouldPassValidate: true,
  1573. expectedPSP: aUnsafeSysctl.Name,
  1574. },
  1575. "pod with safe net sysctl request allowed under aUnsafeSysctl SCC": {
  1576. pod: podWithSysctls([]string{"net.ipv4.ip_local_port_range"}, []string{}),
  1577. psps: []*policy.PodSecurityPolicy{aUnsafeSysctl},
  1578. shouldPassAdmit: true,
  1579. shouldPassValidate: true,
  1580. expectedPSP: aUnsafeSysctl.Name,
  1581. },
  1582. "pod with safe sysctls request disallowed under noSysctls PSP": {
  1583. pod: podWithSysctls([]string{"net.ipv4.ip_local_port_range"}, []string{}),
  1584. psps: []*policy.PodSecurityPolicy{noSysctls},
  1585. shouldPassAdmit: false,
  1586. shouldPassValidate: false,
  1587. },
  1588. "pod with matching sysctls request allowed under mixedSysctls PSP": {
  1589. pod: podWithSysctls([]string{"kernel.shm_rmid_forced"}, []string{"a.b", "b.a"}),
  1590. psps: []*policy.PodSecurityPolicy{mixedSysctls},
  1591. shouldPassAdmit: true,
  1592. shouldPassValidate: true,
  1593. expectedPSP: mixedSysctls.Name,
  1594. },
  1595. "pod with not-matching unsafe sysctls request disallowed under mixedSysctls PSP": {
  1596. pod: podWithSysctls([]string{}, []string{"e"}),
  1597. psps: []*policy.PodSecurityPolicy{mixedSysctls},
  1598. shouldPassAdmit: false,
  1599. shouldPassValidate: false,
  1600. },
  1601. "pod with not-matching safe sysctls request disallowed under mixedSysctls PSP": {
  1602. pod: podWithSysctls([]string{"net.ipv4.ip_local_port_range"}, []string{}),
  1603. psps: []*policy.PodSecurityPolicy{mixedSysctls},
  1604. shouldPassAdmit: false,
  1605. shouldPassValidate: false,
  1606. },
  1607. "pod with sysctls request allowed under catchallSysctls PSP": {
  1608. pod: podWithSysctls([]string{"net.ipv4.ip_local_port_range"}, []string{"f"}),
  1609. psps: []*policy.PodSecurityPolicy{catchallSysctls},
  1610. shouldPassAdmit: true,
  1611. shouldPassValidate: true,
  1612. expectedPSP: catchallSysctls.Name,
  1613. },
  1614. }
  1615. for k, v := range tests {
  1616. origSysctl := v.pod.Spec.SecurityContext.Sysctls
  1617. testPSPAdmit(k, v.psps, v.pod, v.shouldPassAdmit, v.shouldPassValidate, v.expectedPSP, t)
  1618. if v.shouldPassAdmit {
  1619. if !reflect.DeepEqual(v.pod.Spec.SecurityContext.Sysctls, origSysctl) {
  1620. t.Errorf("%s: wrong sysctls: expected=%v, got=%v", k, origSysctl, v.pod.Spec.SecurityContext.Sysctls)
  1621. }
  1622. }
  1623. }
  1624. }
  1625. func testPSPAdmit(testCaseName string, psps []*policy.PodSecurityPolicy, pod *kapi.Pod, shouldPassAdmit, shouldPassValidate bool, expectedPSP string, t *testing.T) {
  1626. testPSPAdmitAdvanced(testCaseName, kadmission.Create, psps, nil, &user.DefaultInfo{}, pod, nil, shouldPassAdmit, shouldPassValidate, true, expectedPSP, t)
  1627. }
  1628. // fakeAttributes decorate kadmission.Attributes. It's used to trace the added annotations.
  1629. type fakeAttributes struct {
  1630. kadmission.Attributes
  1631. annotations map[string]string
  1632. }
  1633. func (f fakeAttributes) AddAnnotation(k, v string) error {
  1634. f.annotations[k] = v
  1635. return f.Attributes.AddAnnotation(k, v)
  1636. }
  1637. func testPSPAdmitAdvanced(testCaseName string, op kadmission.Operation, psps []*policy.PodSecurityPolicy, authz authorizer.Authorizer, userInfo user.Info, pod, oldPod *kapi.Pod, shouldPassAdmit, shouldPassValidate bool, canMutate bool, expectedPSP string, t *testing.T) {
  1638. originalPod := pod.DeepCopy()
  1639. plugin := NewTestAdmission(psps, authz)
  1640. attrs := kadmission.NewAttributesRecord(pod, oldPod, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, "", kapi.Resource("pods").WithVersion("version"), "", op, nil, false, userInfo)
  1641. annotations := make(map[string]string)
  1642. attrs = &fakeAttributes{attrs, annotations}
  1643. err := admissiontesting.WithReinvocationTesting(t, plugin).Admit(context.TODO(), attrs, nil)
  1644. if shouldPassAdmit && err != nil {
  1645. t.Errorf("%s: expected no errors on Admit but received %v", testCaseName, err)
  1646. }
  1647. if shouldPassAdmit && err == nil {
  1648. if pod.Annotations[psputil.ValidatedPSPAnnotation] != expectedPSP {
  1649. t.Errorf("%s: expected to be admitted under %q PSP but found %q", testCaseName, expectedPSP, pod.Annotations[psputil.ValidatedPSPAnnotation])
  1650. }
  1651. if !canMutate {
  1652. podWithoutPSPAnnotation := pod.DeepCopy()
  1653. delete(podWithoutPSPAnnotation.Annotations, psputil.ValidatedPSPAnnotation)
  1654. originalPodWithoutPSPAnnotation := originalPod.DeepCopy()
  1655. delete(originalPodWithoutPSPAnnotation.Annotations, psputil.ValidatedPSPAnnotation)
  1656. if !apiequality.Semantic.DeepEqual(originalPodWithoutPSPAnnotation.Spec, podWithoutPSPAnnotation.Spec) {
  1657. t.Errorf("%s: expected no mutation on Admit, got %s", testCaseName, diff.ObjectGoPrintSideBySide(originalPodWithoutPSPAnnotation.Spec, podWithoutPSPAnnotation.Spec))
  1658. }
  1659. }
  1660. }
  1661. if !shouldPassAdmit && err == nil {
  1662. t.Errorf("%s: expected errors on Admit but received none", testCaseName)
  1663. }
  1664. err = plugin.Validate(context.TODO(), attrs, nil)
  1665. psp := ""
  1666. if shouldPassAdmit && op == kadmission.Create {
  1667. psp = expectedPSP
  1668. }
  1669. validateAuditAnnotation(t, testCaseName, annotations, "podsecuritypolicy.policy.k8s.io/admit-policy", psp)
  1670. if shouldPassValidate && err != nil {
  1671. t.Errorf("%s: expected no errors on Validate but received %v", testCaseName, err)
  1672. } else if !shouldPassValidate && err == nil {
  1673. t.Errorf("%s: expected errors on Validate but received none", testCaseName)
  1674. }
  1675. if shouldPassValidate {
  1676. validateAuditAnnotation(t, testCaseName, annotations, "podsecuritypolicy.policy.k8s.io/validate-policy", expectedPSP)
  1677. } else {
  1678. validateAuditAnnotation(t, testCaseName, annotations, "podsecuritypolicy.policy.k8s.io/validate-policy", "")
  1679. }
  1680. }
  1681. func validateAuditAnnotation(t *testing.T, testCaseName string, annotations map[string]string, key, value string) {
  1682. if annotations[key] != value {
  1683. t.Errorf("%s: expected to have annotations[%s] set to %q, got %q", testCaseName, key, value, annotations[key])
  1684. }
  1685. }
  1686. func TestAssignSecurityContext(t *testing.T) {
  1687. // psp that will deny privileged container requests and has a default value for a field (uid)
  1688. psp := restrictivePSP()
  1689. provider, err := kpsp.NewSimpleProvider(psp, "namespace", kpsp.NewSimpleStrategyFactory())
  1690. if err != nil {
  1691. t.Fatalf("failed to create provider: %v", err)
  1692. }
  1693. createContainer := func(priv bool) kapi.Container {
  1694. return kapi.Container{
  1695. SecurityContext: &kapi.SecurityContext{
  1696. Privileged: &priv,
  1697. },
  1698. }
  1699. }
  1700. testCases := map[string]struct {
  1701. pod *kapi.Pod
  1702. shouldValidate bool
  1703. expectedUID *int64
  1704. }{
  1705. "pod and container SC is not changed when invalid": {
  1706. pod: &kapi.Pod{
  1707. Spec: kapi.PodSpec{
  1708. SecurityContext: &kapi.PodSecurityContext{},
  1709. Containers: []kapi.Container{createContainer(true)},
  1710. },
  1711. },
  1712. shouldValidate: false,
  1713. },
  1714. "must validate all containers": {
  1715. pod: &kapi.Pod{
  1716. Spec: kapi.PodSpec{
  1717. // good container and bad container
  1718. SecurityContext: &kapi.PodSecurityContext{},
  1719. Containers: []kapi.Container{createContainer(false), createContainer(true)},
  1720. },
  1721. },
  1722. shouldValidate: false,
  1723. },
  1724. "pod validates": {
  1725. pod: &kapi.Pod{
  1726. Spec: kapi.PodSpec{
  1727. SecurityContext: &kapi.PodSecurityContext{},
  1728. Containers: []kapi.Container{createContainer(false)},
  1729. },
  1730. },
  1731. shouldValidate: true,
  1732. },
  1733. }
  1734. for k, v := range testCases {
  1735. errs := assignSecurityContext(provider, v.pod)
  1736. if v.shouldValidate && len(errs) > 0 {
  1737. t.Errorf("%s expected to validate but received errors %v", k, errs)
  1738. continue
  1739. }
  1740. if !v.shouldValidate && len(errs) == 0 {
  1741. t.Errorf("%s expected validation errors but received none", k)
  1742. continue
  1743. }
  1744. }
  1745. }
  1746. func TestCreateProvidersFromConstraints(t *testing.T) {
  1747. testCases := map[string]struct {
  1748. // use a generating function so we can test for non-mutation
  1749. psp func() *policy.PodSecurityPolicy
  1750. expectedErr string
  1751. }{
  1752. "valid psp": {
  1753. psp: func() *policy.PodSecurityPolicy {
  1754. return &policy.PodSecurityPolicy{
  1755. ObjectMeta: metav1.ObjectMeta{
  1756. Name: "valid psp",
  1757. },
  1758. Spec: policy.PodSecurityPolicySpec{
  1759. SELinux: policy.SELinuxStrategyOptions{
  1760. Rule: policy.SELinuxStrategyRunAsAny,
  1761. },
  1762. RunAsUser: policy.RunAsUserStrategyOptions{
  1763. Rule: policy.RunAsUserStrategyRunAsAny,
  1764. },
  1765. RunAsGroup: &policy.RunAsGroupStrategyOptions{
  1766. Rule: policy.RunAsGroupStrategyRunAsAny,
  1767. },
  1768. FSGroup: policy.FSGroupStrategyOptions{
  1769. Rule: policy.FSGroupStrategyRunAsAny,
  1770. },
  1771. SupplementalGroups: policy.SupplementalGroupsStrategyOptions{
  1772. Rule: policy.SupplementalGroupsStrategyRunAsAny,
  1773. },
  1774. },
  1775. }
  1776. },
  1777. },
  1778. "bad psp strategy options": {
  1779. psp: func() *policy.PodSecurityPolicy {
  1780. return &policy.PodSecurityPolicy{
  1781. ObjectMeta: metav1.ObjectMeta{
  1782. Name: "bad psp user options",
  1783. },
  1784. Spec: policy.PodSecurityPolicySpec{
  1785. SELinux: policy.SELinuxStrategyOptions{
  1786. Rule: policy.SELinuxStrategyRunAsAny,
  1787. },
  1788. RunAsUser: policy.RunAsUserStrategyOptions{
  1789. Rule: policy.RunAsUserStrategyMustRunAs,
  1790. },
  1791. RunAsGroup: &policy.RunAsGroupStrategyOptions{
  1792. Rule: policy.RunAsGroupStrategyRunAsAny,
  1793. },
  1794. FSGroup: policy.FSGroupStrategyOptions{
  1795. Rule: policy.FSGroupStrategyRunAsAny,
  1796. },
  1797. SupplementalGroups: policy.SupplementalGroupsStrategyOptions{
  1798. Rule: policy.SupplementalGroupsStrategyRunAsAny,
  1799. },
  1800. },
  1801. }
  1802. },
  1803. expectedErr: "MustRunAs requires at least one range",
  1804. },
  1805. }
  1806. for k, v := range testCases {
  1807. admit := &Plugin{
  1808. Handler: kadmission.NewHandler(kadmission.Create, kadmission.Update),
  1809. strategyFactory: kpsp.NewSimpleStrategyFactory(),
  1810. }
  1811. psp := v.psp()
  1812. _, errs := admit.createProvidersFromPolicies([]*policy.PodSecurityPolicy{psp}, "namespace")
  1813. if !reflect.DeepEqual(psp, v.psp()) {
  1814. diff := diff.ObjectDiff(psp, v.psp())
  1815. t.Errorf("%s createProvidersFromPolicies mutated policy. diff:\n%s", k, diff)
  1816. }
  1817. if len(v.expectedErr) > 0 && len(errs) != 1 {
  1818. t.Errorf("%s expected a single error '%s' but received %v", k, v.expectedErr, errs)
  1819. continue
  1820. }
  1821. if len(v.expectedErr) == 0 && len(errs) != 0 {
  1822. t.Errorf("%s did not expect an error but received %v", k, errs)
  1823. continue
  1824. }
  1825. // check that we got the error we expected
  1826. if len(v.expectedErr) > 0 {
  1827. if !strings.Contains(errs[0].Error(), v.expectedErr) {
  1828. t.Errorf("%s expected error '%s' but received %v", k, v.expectedErr, errs[0])
  1829. }
  1830. }
  1831. }
  1832. }
  1833. func TestPolicyAuthorization(t *testing.T) {
  1834. policyWithName := func(name string) *policy.PodSecurityPolicy {
  1835. p := permissivePSP()
  1836. p.Name = name
  1837. return p
  1838. }
  1839. tests := map[string]struct {
  1840. user user.Info
  1841. sa string
  1842. ns string
  1843. expectedPolicy string
  1844. inPolicies []*policy.PodSecurityPolicy
  1845. allowed map[string]map[string]map[string]bool
  1846. allowedGroup string
  1847. }{
  1848. "policy allowed by user (extensions API Group)": {
  1849. user: &user.DefaultInfo{Name: "user"},
  1850. sa: "sa",
  1851. ns: "test",
  1852. allowed: map[string]map[string]map[string]bool{
  1853. "user": {
  1854. "test": {"policy": true},
  1855. },
  1856. },
  1857. inPolicies: []*policy.PodSecurityPolicy{policyWithName("policy")},
  1858. expectedPolicy: "policy",
  1859. },
  1860. "policy allowed by sa (extensions API Group)": {
  1861. user: &user.DefaultInfo{Name: "user"},
  1862. sa: "sa",
  1863. ns: "test",
  1864. allowed: map[string]map[string]map[string]bool{
  1865. serviceaccount.MakeUsername("test", "sa"): {
  1866. "test": {"policy": true},
  1867. },
  1868. },
  1869. inPolicies: []*policy.PodSecurityPolicy{policyWithName("policy")},
  1870. expectedPolicy: "policy",
  1871. },
  1872. "policy allowed by user (policy API Group)": {
  1873. user: &user.DefaultInfo{Name: "user"},
  1874. sa: "sa",
  1875. ns: "test",
  1876. allowed: map[string]map[string]map[string]bool{
  1877. "user": {
  1878. "test": {"policy": true},
  1879. },
  1880. },
  1881. inPolicies: []*policy.PodSecurityPolicy{policyWithName("policy")},
  1882. expectedPolicy: "policy",
  1883. allowedGroup: policy.GroupName,
  1884. },
  1885. "policy allowed by sa (policy API Group)": {
  1886. user: &user.DefaultInfo{Name: "user"},
  1887. sa: "sa",
  1888. ns: "test",
  1889. allowed: map[string]map[string]map[string]bool{
  1890. serviceaccount.MakeUsername("test", "sa"): {
  1891. "test": {"policy": true},
  1892. },
  1893. },
  1894. inPolicies: []*policy.PodSecurityPolicy{policyWithName("policy")},
  1895. expectedPolicy: "policy",
  1896. allowedGroup: policy.GroupName,
  1897. },
  1898. "no policies allowed": {
  1899. user: &user.DefaultInfo{Name: "user"},
  1900. sa: "sa",
  1901. ns: "test",
  1902. allowed: map[string]map[string]map[string]bool{},
  1903. inPolicies: []*policy.PodSecurityPolicy{policyWithName("policy")},
  1904. expectedPolicy: "",
  1905. },
  1906. "multiple policies allowed": {
  1907. user: &user.DefaultInfo{Name: "user"},
  1908. sa: "sa",
  1909. ns: "test",
  1910. allowed: map[string]map[string]map[string]bool{
  1911. serviceaccount.MakeUsername("test", "sa"): {
  1912. "test": {"policy1": true},
  1913. "": {"policy4": true},
  1914. "other": {"policy6": true},
  1915. },
  1916. "user": {
  1917. "test": {"policy2": true},
  1918. "": {"policy5": true},
  1919. "other": {"policy7": true},
  1920. },
  1921. },
  1922. inPolicies: []*policy.PodSecurityPolicy{
  1923. // Prefix to force checking these policies first.
  1924. policyWithName("a_policy1"), // not allowed in this namespace
  1925. policyWithName("a_policy2"), // not allowed in this namespace
  1926. policyWithName("policy2"), // allowed by sa
  1927. policyWithName("policy3"), // allowed by user
  1928. policyWithName("policy4"), // not allowed
  1929. policyWithName("policy5"), // allowed by sa at cluster level
  1930. policyWithName("policy6"), // allowed by user at cluster level
  1931. },
  1932. expectedPolicy: "policy2",
  1933. },
  1934. "policies are not allowed for nil user info": {
  1935. user: nil,
  1936. sa: "sa",
  1937. ns: "test",
  1938. allowed: map[string]map[string]map[string]bool{
  1939. serviceaccount.MakeUsername("test", "sa"): {
  1940. "test": {"policy1": true},
  1941. },
  1942. "user": {
  1943. "test": {"policy2": true},
  1944. },
  1945. },
  1946. inPolicies: []*policy.PodSecurityPolicy{
  1947. policyWithName("policy1"),
  1948. policyWithName("policy2"),
  1949. policyWithName("policy3"),
  1950. },
  1951. // only the policies for the sa are allowed when user info is nil
  1952. expectedPolicy: "policy1",
  1953. },
  1954. "policies are not allowed for nil sa info": {
  1955. user: &user.DefaultInfo{Name: "user"},
  1956. sa: "",
  1957. ns: "test",
  1958. allowed: map[string]map[string]map[string]bool{
  1959. serviceaccount.MakeUsername("test", "sa"): {
  1960. "test": {"policy1": true},
  1961. },
  1962. "user": {
  1963. "test": {"policy2": true},
  1964. },
  1965. },
  1966. inPolicies: []*policy.PodSecurityPolicy{
  1967. policyWithName("policy1"),
  1968. policyWithName("policy2"),
  1969. policyWithName("policy3"),
  1970. },
  1971. // only the policies for the user are allowed when sa info is nil
  1972. expectedPolicy: "policy2",
  1973. },
  1974. "policies are not allowed for nil sa and user info": {
  1975. user: nil,
  1976. sa: "",
  1977. ns: "test",
  1978. allowed: map[string]map[string]map[string]bool{
  1979. serviceaccount.MakeUsername("test", "sa"): {
  1980. "test": {"policy1": true},
  1981. },
  1982. "user": {
  1983. "test": {"policy2": true},
  1984. },
  1985. },
  1986. inPolicies: []*policy.PodSecurityPolicy{
  1987. policyWithName("policy1"),
  1988. policyWithName("policy2"),
  1989. policyWithName("policy3"),
  1990. },
  1991. // no policies are allowed if sa and user are both nil
  1992. expectedPolicy: "",
  1993. },
  1994. }
  1995. for k, v := range tests {
  1996. var (
  1997. oldPod *kapi.Pod
  1998. shouldPass = v.expectedPolicy != ""
  1999. authz = &TestAuthorizer{usernameToNamespaceToAllowedPSPs: v.allowed, allowedAPIGroupName: v.allowedGroup}
  2000. canMutate = true
  2001. )
  2002. pod := goodPod()
  2003. pod.Namespace = v.ns
  2004. pod.Spec.ServiceAccountName = v.sa
  2005. testPSPAdmitAdvanced(k, kadmission.Create, v.inPolicies, authz, v.user,
  2006. pod, oldPod, shouldPass, shouldPass, canMutate, v.expectedPolicy, t)
  2007. }
  2008. }
  2009. func TestPolicyAuthorizationErrors(t *testing.T) {
  2010. policyWithName := func(name string) *policy.PodSecurityPolicy {
  2011. p := restrictivePSP()
  2012. p.Name = name
  2013. return p
  2014. }
  2015. const (
  2016. sa = "sa"
  2017. ns = "test"
  2018. userName = "user"
  2019. )
  2020. tests := map[string]struct {
  2021. inPolicies []*policy.PodSecurityPolicy
  2022. allowed map[string]map[string]map[string]bool
  2023. expectValidationErrs int
  2024. }{
  2025. "policies not allowed": {
  2026. allowed: map[string]map[string]map[string]bool{},
  2027. inPolicies: []*policy.PodSecurityPolicy{
  2028. policyWithName("policy1"),
  2029. policyWithName("policy2"),
  2030. },
  2031. expectValidationErrs: 0,
  2032. },
  2033. "policy allowed by user": {
  2034. allowed: map[string]map[string]map[string]bool{
  2035. "user": {
  2036. "test": {"policy1": true},
  2037. },
  2038. },
  2039. inPolicies: []*policy.PodSecurityPolicy{
  2040. policyWithName("policy1"),
  2041. policyWithName("policy2"),
  2042. },
  2043. expectValidationErrs: 1,
  2044. },
  2045. "policy allowed by service account": {
  2046. allowed: map[string]map[string]map[string]bool{
  2047. serviceaccount.MakeUsername("test", "sa"): {
  2048. "test": {"policy2": true},
  2049. },
  2050. },
  2051. inPolicies: []*policy.PodSecurityPolicy{
  2052. policyWithName("policy1"),
  2053. policyWithName("policy2"),
  2054. },
  2055. expectValidationErrs: 1,
  2056. },
  2057. "multiple policies allowed": {
  2058. allowed: map[string]map[string]map[string]bool{
  2059. "user": {
  2060. "test": {"policy1": true},
  2061. },
  2062. serviceaccount.MakeUsername("test", "sa"): {
  2063. "test": {"policy2": true},
  2064. },
  2065. },
  2066. inPolicies: []*policy.PodSecurityPolicy{
  2067. policyWithName("policy1"),
  2068. policyWithName("policy2"),
  2069. },
  2070. expectValidationErrs: 2,
  2071. },
  2072. }
  2073. for desc, tc := range tests {
  2074. t.Run(desc, func(t *testing.T) {
  2075. authz := &TestAuthorizer{usernameToNamespaceToAllowedPSPs: tc.allowed}
  2076. pod := goodPod()
  2077. pod.Namespace = ns
  2078. pod.Spec.ServiceAccountName = sa
  2079. pod.Spec.SecurityContext.HostPID = true
  2080. plugin := NewTestAdmission(tc.inPolicies, authz)
  2081. attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), ns, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{Name: userName})
  2082. allowedPod, _, validationErrs, err := plugin.computeSecurityContext(context.Background(), attrs, pod, true, "")
  2083. assert.Nil(t, allowedPod)
  2084. assert.NoError(t, err)
  2085. assert.Len(t, validationErrs, tc.expectValidationErrs)
  2086. })
  2087. }
  2088. }
  2089. func TestPreferValidatedPSP(t *testing.T) {
  2090. restrictivePSPWithName := func(name string) *policy.PodSecurityPolicy {
  2091. p := restrictivePSP()
  2092. p.Name = name
  2093. return p
  2094. }
  2095. permissivePSPWithName := func(name string) *policy.PodSecurityPolicy {
  2096. p := permissivePSP()
  2097. p.Name = name
  2098. return p
  2099. }
  2100. tests := map[string]struct {
  2101. inPolicies []*policy.PodSecurityPolicy
  2102. expectValidationErrs int
  2103. validatedPSPHint string
  2104. expectedPSP string
  2105. }{
  2106. "no policy saved in annotations, PSPs are ordered lexicographically": {
  2107. inPolicies: []*policy.PodSecurityPolicy{
  2108. restrictivePSPWithName("001restrictive"),
  2109. restrictivePSPWithName("002restrictive"),
  2110. permissivePSPWithName("002permissive"),
  2111. permissivePSPWithName("001permissive"),
  2112. permissivePSPWithName("003permissive"),
  2113. },
  2114. expectValidationErrs: 0,
  2115. validatedPSPHint: "",
  2116. expectedPSP: "001permissive",
  2117. },
  2118. "policy saved in annotations is preferred": {
  2119. inPolicies: []*policy.PodSecurityPolicy{
  2120. restrictivePSPWithName("001restrictive"),
  2121. restrictivePSPWithName("002restrictive"),
  2122. permissivePSPWithName("001permissive"),
  2123. permissivePSPWithName("002permissive"),
  2124. permissivePSPWithName("003permissive"),
  2125. },
  2126. expectValidationErrs: 0,
  2127. validatedPSPHint: "002permissive",
  2128. expectedPSP: "002permissive",
  2129. },
  2130. "policy saved in annotations is invalid": {
  2131. inPolicies: []*policy.PodSecurityPolicy{
  2132. restrictivePSPWithName("001restrictive"),
  2133. restrictivePSPWithName("002restrictive"),
  2134. },
  2135. expectValidationErrs: 2,
  2136. validatedPSPHint: "foo",
  2137. expectedPSP: "",
  2138. },
  2139. "policy saved in annotations is disallowed anymore": {
  2140. inPolicies: []*policy.PodSecurityPolicy{
  2141. restrictivePSPWithName("001restrictive"),
  2142. restrictivePSPWithName("002restrictive"),
  2143. },
  2144. expectValidationErrs: 2,
  2145. validatedPSPHint: "001restrictive",
  2146. expectedPSP: "",
  2147. },
  2148. "policy saved in annotations is disallowed anymore, but find another one": {
  2149. inPolicies: []*policy.PodSecurityPolicy{
  2150. restrictivePSPWithName("001restrictive"),
  2151. restrictivePSPWithName("002restrictive"),
  2152. permissivePSPWithName("002permissive"),
  2153. permissivePSPWithName("001permissive"),
  2154. },
  2155. expectValidationErrs: 0,
  2156. validatedPSPHint: "001restrictive",
  2157. expectedPSP: "001permissive",
  2158. },
  2159. }
  2160. for desc, tc := range tests {
  2161. t.Run(desc, func(t *testing.T) {
  2162. authz := authorizerfactory.NewAlwaysAllowAuthorizer()
  2163. allowPrivilegeEscalation := true
  2164. pod := goodPod()
  2165. pod.Namespace = "ns"
  2166. pod.Spec.ServiceAccountName = "sa"
  2167. pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &allowPrivilegeEscalation
  2168. plugin := NewTestAdmission(tc.inPolicies, authz)
  2169. attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "ns", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Update, &metav1.UpdateOptions{}, false, &user.DefaultInfo{Name: "test"})
  2170. _, pspName, validationErrs, err := plugin.computeSecurityContext(context.Background(), attrs, pod, false, tc.validatedPSPHint)
  2171. assert.NoError(t, err)
  2172. assert.Len(t, validationErrs, tc.expectValidationErrs)
  2173. assert.Equal(t, tc.expectedPSP, pspName)
  2174. })
  2175. }
  2176. }
  2177. func restrictivePSP() *policy.PodSecurityPolicy {
  2178. allowPrivilegeEscalation := false
  2179. return &policy.PodSecurityPolicy{
  2180. ObjectMeta: metav1.ObjectMeta{
  2181. Name: "restrictive",
  2182. Annotations: map[string]string{},
  2183. },
  2184. Spec: policy.PodSecurityPolicySpec{
  2185. AllowPrivilegeEscalation: &allowPrivilegeEscalation,
  2186. RunAsUser: policy.RunAsUserStrategyOptions{
  2187. Rule: policy.RunAsUserStrategyMustRunAs,
  2188. Ranges: []policy.IDRange{
  2189. {Min: int64(999), Max: int64(999)},
  2190. },
  2191. },
  2192. RunAsGroup: &policy.RunAsGroupStrategyOptions{
  2193. Rule: policy.RunAsGroupStrategyMustRunAs,
  2194. Ranges: []policy.IDRange{
  2195. {Min: int64(999), Max: int64(999)},
  2196. },
  2197. },
  2198. SELinux: policy.SELinuxStrategyOptions{
  2199. Rule: policy.SELinuxStrategyMustRunAs,
  2200. SELinuxOptions: &v1.SELinuxOptions{
  2201. Level: "s9:z0,z1",
  2202. },
  2203. },
  2204. FSGroup: policy.FSGroupStrategyOptions{
  2205. Rule: policy.FSGroupStrategyMustRunAs,
  2206. Ranges: []policy.IDRange{
  2207. {Min: int64(999), Max: int64(999)},
  2208. },
  2209. },
  2210. SupplementalGroups: policy.SupplementalGroupsStrategyOptions{
  2211. Rule: policy.SupplementalGroupsStrategyMustRunAs,
  2212. Ranges: []policy.IDRange{
  2213. {Min: int64(999), Max: int64(999)},
  2214. },
  2215. },
  2216. },
  2217. }
  2218. }
  2219. func permissivePSP() *policy.PodSecurityPolicy {
  2220. allowPrivilegeEscalation := true
  2221. return &policy.PodSecurityPolicy{
  2222. ObjectMeta: metav1.ObjectMeta{
  2223. Name: "privileged",
  2224. Annotations: map[string]string{},
  2225. },
  2226. Spec: policy.PodSecurityPolicySpec{
  2227. AllowPrivilegeEscalation: &allowPrivilegeEscalation,
  2228. HostIPC: true,
  2229. HostNetwork: true,
  2230. HostPID: true,
  2231. HostPorts: []policy.HostPortRange{{Min: 0, Max: 65536}},
  2232. Volumes: []policy.FSType{policy.All},
  2233. AllowedCapabilities: []v1.Capability{policy.AllowAllCapabilities},
  2234. RunAsUser: policy.RunAsUserStrategyOptions{
  2235. Rule: policy.RunAsUserStrategyRunAsAny,
  2236. },
  2237. RunAsGroup: &policy.RunAsGroupStrategyOptions{
  2238. Rule: policy.RunAsGroupStrategyRunAsAny,
  2239. },
  2240. SELinux: policy.SELinuxStrategyOptions{
  2241. Rule: policy.SELinuxStrategyRunAsAny,
  2242. },
  2243. FSGroup: policy.FSGroupStrategyOptions{
  2244. Rule: policy.FSGroupStrategyRunAsAny,
  2245. },
  2246. SupplementalGroups: policy.SupplementalGroupsStrategyOptions{
  2247. Rule: policy.SupplementalGroupsStrategyRunAsAny,
  2248. },
  2249. },
  2250. }
  2251. }
  2252. // goodPod is empty and should not be used directly for testing since we're providing
  2253. // two different PSPs. Since no values are specified it would be allowed to match any
  2254. // psp when defaults are filled in.
  2255. func goodPod() *kapi.Pod {
  2256. return &kapi.Pod{
  2257. ObjectMeta: metav1.ObjectMeta{
  2258. Name: "pod",
  2259. Namespace: "namespace",
  2260. Annotations: map[string]string{},
  2261. },
  2262. Spec: kapi.PodSpec{
  2263. ServiceAccountName: "default",
  2264. SecurityContext: &kapi.PodSecurityContext{},
  2265. Containers: []kapi.Container{
  2266. {
  2267. Name: defaultContainerName,
  2268. SecurityContext: &kapi.SecurityContext{},
  2269. },
  2270. },
  2271. },
  2272. }
  2273. }