From c02db7e90eea8aee234c4dd0a0c1c9941791eec0 Mon Sep 17 00:00:00 2001 From: daemon1024 Date: Wed, 22 Jun 2022 12:02:58 +0530 Subject: [PATCH] enforcer: update Container Rules on K8s events Signed-off-by: daemon1024 --- KubeArmor/BPF/enforcer.bpf.c | 7 ++ KubeArmor/common/hash.go | 121 +++++++++++++++++++++ KubeArmor/enforcer/bpflsm/enforcer.go | 13 +++ KubeArmor/enforcer/bpflsm/enforcer_bpfeb.o | Bin 32808 -> 35128 bytes KubeArmor/enforcer/bpflsm/enforcer_bpfel.o | Bin 32808 -> 35128 bytes KubeArmor/enforcer/bpflsm/rulesHandling.go | 27 +++++ KubeArmor/enforcer/runtimeEnforcer.go | 4 +- 7 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 KubeArmor/common/hash.go create mode 100644 KubeArmor/enforcer/bpflsm/rulesHandling.go diff --git a/KubeArmor/BPF/enforcer.bpf.c b/KubeArmor/BPF/enforcer.bpf.c index f0e7209168..eb13890375 100644 --- a/KubeArmor/BPF/enforcer.bpf.c +++ b/KubeArmor/BPF/enforcer.bpf.c @@ -35,6 +35,11 @@ static struct file *get_task_file(struct task_struct *task) { return BPF_CORE_READ(task, mm, exe_file); } +static u64 cb_check_path(struct bpf_map *map, u32 *key, char *path, int t) { + bpf_printk("Found key %u", *key); + return 0; +} + SEC("lsm/bprm_check_security") int BPF_PROG(enforce_proc, struct linux_binprm *bprm, int ret) { struct task_struct *t = (struct task_struct *)bpf_get_current_task(); @@ -54,5 +59,7 @@ int BPF_PROG(enforce_proc, struct linux_binprm *bprm, int ret) { bpf_printk("monitoring %u,%u", okey.pid_ns, okey.mnt_ns); + bpf_for_each_map_elem(inner, cb_check_path, 0, 0); + return ret; } diff --git a/KubeArmor/common/hash.go b/KubeArmor/common/hash.go new file mode 100644 index 0000000000..f617b20afb --- /dev/null +++ b/KubeArmor/common/hash.go @@ -0,0 +1,121 @@ +package common + +import "unsafe" + +/* + * This contains Jenkins hash algorithm modified to mactch the hashing in ebpf land. + * Inspiration sources: + * + * https://en.wikipedia.org/wiki/Jenkins_hash_function + * http://burtleburtle.net/bob/c/lookup3.c + * https://github.com/torvalds/linux/blob/master/tools/include/linux/jhash.h + * https://github.com/tildeleb/hashland/blob/46daf2d89bba924a4269f30949050748548effb1/jenkins/jenkins.go + */ + +func rot(x, k uint32) uint32 { + return x<>(32-k) +} + +func mix(a, b, c uint32) (uint32, uint32, uint32) { + a -= c + a ^= rot(c, 4) + c += b + b -= a + b ^= rot(a, 6) + a += c + c -= b + c ^= rot(b, 8) + b += a + a -= c + a ^= rot(c, 16) + c += b + b -= a + b ^= rot(a, 19) + a += c + c -= b + c ^= rot(b, 4) + b += a + + return a, b, c +} + +func final(a, b, c uint32) uint32 { + c ^= b + c -= rot(b, 14) + a ^= c + a -= rot(c, 11) + b ^= a + b -= rot(a, 25) + c ^= b + c -= rot(b, 16) + a ^= c + a -= rot(c, 4) + b ^= a + b -= rot(a, 14) + c ^= b + c -= rot(b, 24) + + return c +} + +func JHash(k []byte, seed uint32) uint32 { + var a, b, c uint32 + + var length int + length = len(k) + a = 0xdeadbeef + uint32(length) + seed + b, c = a, a + + for ; length > 12; length -= 12 { + a += *(*uint32)(unsafe.Pointer(&k[0])) + b += *(*uint32)(unsafe.Pointer(&k[4])) + c += *(*uint32)(unsafe.Pointer(&k[8])) + a, b, c = mix(a, b, c) + k = k[12:] + } + + switch length { + case 12: + a += *(*uint32)(unsafe.Pointer(&k[0])) + b += *(*uint32)(unsafe.Pointer(&k[4])) + c += *(*uint32)(unsafe.Pointer(&k[8])) + case 11: + c += uint32(k[10]) << 16 + fallthrough + case 10: + c += uint32(k[9]) << 8 + fallthrough + case 9: + c += uint32(k[8]) + fallthrough + case 8: + a += *(*uint32)(unsafe.Pointer(&k[0])) + b += *(*uint32)(unsafe.Pointer(&k[4])) + // break + case 7: + b += uint32(k[6]) << 16 + fallthrough + case 6: + b += uint32(k[5]) << 8 + fallthrough + case 5: + b += uint32(k[4]) + fallthrough + case 4: + a += *(*uint32)(unsafe.Pointer(&k[0])) + // break + case 3: + a += uint32(k[2]) << 16 + fallthrough + case 2: + a += uint32(k[1]) << 8 + fallthrough + case 1: + a += uint32(k[0]) + // break + case 0: + return c /* zero length strings require no mixing */ + } + c = final(a, b, c) + return c +} diff --git a/KubeArmor/enforcer/bpflsm/enforcer.go b/KubeArmor/enforcer/bpflsm/enforcer.go index 1ed96b3f63..f4f323dca4 100644 --- a/KubeArmor/enforcer/bpflsm/enforcer.go +++ b/KubeArmor/enforcer/bpflsm/enforcer.go @@ -88,6 +88,19 @@ func NewBPFEnforcer(node tp.Node, logger *fd.Feeder) *BPFEnforcer { return be } +func (be *BPFEnforcer) UpdateSecurityPolicies(endPoint tp.EndPoint) { + // skip if BPFEnforcer is not active + if be == nil { + return + } + + for _, cid := range endPoint.Containers { + be.Logger.Printf("Updating container rules for %s", cid) + be.UpdateContainerRules(cid, endPoint.SecurityPolicies) + } + +} + func (be *BPFEnforcer) DestroyBPFEnforcer() error { if be == nil { return nil diff --git a/KubeArmor/enforcer/bpflsm/enforcer_bpfeb.o b/KubeArmor/enforcer/bpflsm/enforcer_bpfeb.o index fd271de664a3cd668e82c7eeb514840aec6d6cc5..7674b31aa863ea050514722e25882c09bb902620 100644 GIT binary patch delta 5479 zcmai13s79u89rwN2}Ceh4J0gymmr3agVtS;}Zpp4JqYO&&jzjNxA}jx3bSmxFrzv z?>{*=OPK6vgip?WMbuqOZ^ovIb-D!lxw*O72}R@c59{K^6FOy&5pBmabdco`HVn$9 zb`zIOaM|oKx6V)9snaDvE%3}#kMl_ z({mRn*8k5SZsbTI_HgTwKUG)@4fm6Cza#ev6h?zO_Qjmu72;PNVI@SxPE$o*a(2si zv*qHbX+xgW$1laZrt4}7$re!*jePT(u<3B3L8rzf#-;|vzf9Y&_XYfYkwB==-;1@g zlt;C-qIILSgvX_)Ir**7o!bzMo;s0;FIr!~A4t4-bE>EnZ7OIV-kLbG4r*0 zVtqM{qO~vC!0(IkirC6uNnVE}d~c#{-935yCGqR)>iH3ov+))FLSk~`6we=*tX@nU zy8brKUlubr)Qd}{dHL^3%8|r|8(U2)e;|o&lJG0y=%zCMcw%x>M;1Ss$Z1^9^M4`f zpA-$7i&p+vlKfo4-%kWLFX82*lIW;}(fM!o=X>HrQzw5-%r-p{drp%37+e2w7GpS! zXx~>}4eBR7)d2sjQo zb@;dNBYYAVHj9C^>hb0Q!b|DJIO18JU(6V~N-c0 z*Meq)zXcTjRrCoj0Ywq?PoRp5L-(ql0Y$E=DbUM6KL*VMrFi*_RZ|_8gRTZ$23iLi zD*$K(xB~Px&~JfKd#(h12=pq@mqC|<{st7St-c6~C93`hD9%PJg3*4kR)AvfSQ|ji zpy(}!f`AEiXLixU1yjMxifHA_;Wnq?9$k#MDitrFfO;U)>UOL&)rzbD}# z4U6)YRsNa>CHdnLK9$1O_foiKLc;Gz_>m=MJVOI)gA57ue?i5}*oWivc3Gdf19bt^sKAckI^rvvGv?*$z z6Qiw#vD(*DYEym+*S;^|k0t!6g#Vhtb##6hqpm>0W(iBXVV%AzO`1zxy=2rX;T;n0 zk+3xJy89D@Z6)i)hv5ffin1rzqxJ+ss@Lt=tNPqQ)!Xm&RrLA&-jGG{>`^^?y`Ft) z&>h)pQEd2ISI@`=mP|9!e0<)Bn~`&5DCpIIcQ6vtMLqrQ-Y^RX`}}Hu0HFdsJuK4a z^M-(8J0k%x5nS$?vHxYCBFVXe{@itr(r&?&(q8NZXZGo z1>NDW8V-6r>K!#Kd%6%)o+sPcIp2<)=a+0WpwrdiY;4UaJm$1_b=n;r zPM1o~3-s0K#QzHNoi2Mf4@J^SrtI4HyI5Jx5+_JrO zb5~1x_$}Kzn(Yf@Kmu3eg1MpD9NX5>(XO^^+2*o4*+3w)PYp*xQBQ<*yYWG5f}W_~ zqekePX81T69Rw`G(hdez9l__$!V!0*&!a>)Zb&~jD)gAzNrNy-C0-UKT34%7wjm@= znZ53iQmG#?eg23NS*Pr0`pFc;@50EwiZ%56J^7n(jYX-19}Xf#33(&YkYBNhosnCY z&;b+(hQ;%de-^r(#O~VT<3V);Av7AwfOPzV!MhlnA^ohucQZDNOPR@G@S}`9g=)G}Dcn{=peM{h-kjC;3g_$v4TqRw1l$$ zTn2w3gZ~?NBOm2wCR!V*026(MGJj15zafKf&fr~1ep&Vv1*|&c?e7o!tb2kXpK-4V zdp%M7{~uyPIZ&OScB+Z?15Yhx2M}QqHhtmJ!^w@45Cy}x@SqqOHj913CAs4;!N6`F z8Q!?`?oo|nOcCdY&AeB9j(3~Lx$Bl(+R-#B$d!+Y{=3Y%aZQ4sWMbqlbM^>0u4P*^ zsw?(?A{@i!Y})L(qG7nuboaE#iQT+3MulORx`iW#tTP(NOo|wZnfWg9Vyt-SVO@qT dkBZINhsd0QuQ_N~vuTKE!IGy3oftG${0Cerry2kN delta 3129 zcmZ9Odr(wW9LLY^0`kZed@T#R>B@?%ExU+1=m_RgmKaXiXb;oIMMN<{Rvsd{x+}?o zMv44NEm6TIK1%9ZKB9sCDEq^in6jy9Xkwabn9)i8aGWxx?VNir-XHhQ+;czQ@9%e> zd+t4ZtySs_NiCi=flekauU3v@P0LX`uLQ#XCD9gMvposyY{Wfc=tnd}2?I@E@((7<^T7PMXYEqA=Bd z7^~`t{Ef}hTI53p&<3OIxPQyg%zb?OS(Ew7xqL^1_Q6D`;| zZ4Mm9{%H=l+?wWC7$(8Jgx@B-itxvTyU>?*0IF~(trkAQQiq&!i9~A%Z^Nz(^K7Ul zRx{xpIwQvg8 zJ9C#FB^5p)+(Z}|v(8YvQGZKq5zmvHt2pQkrgRghmT;XMn)&8fIF8XdxloVZoXeP- zHdg*O=L(oQNZv8Id;V&G6KGkGo3fn*J|(6|Iy@&eC{%p_u^5Oxus zi`@lj!Avi)UL?Fp=P^I%oLNmcKzJYF!-U%ipC{a%mvrBw?r3#ycy5va*$*BvZ_h({pwQ+Tzs|p5t)Cw&)tjAZ z%8`RbwKH*eTQe>Vyo47552TVh`S`A1V6JxH*p(&Z?+}0T8V6I=_OSQuIy3~`IwPw*EtFo#zZpGKjx8SAui-LC0D#;)*5 zL6@ps6Bz4_;s+9c;YGfSkK!ACCQDvT^AAxU&zF{K`Z!|)BEMJF>4Q7yFt$~XspW2f|iZg~Pl|LQCVKc)Q~B0}g%MJA{EoYkYy`*|ELR8dJ{| zD1Anis)1@74m4U}H+F|pr5$#(G(DM6yH}0DF#4K!k6umoVtbPn3bDH>RSK}yMl*WC ZrkHI!Dv37J>OyMbqYX7OuQ<)O{0~f|ur~kz diff --git a/KubeArmor/enforcer/bpflsm/enforcer_bpfel.o b/KubeArmor/enforcer/bpflsm/enforcer_bpfel.o index 26844f269d945c47af8059b1a2ea40b638ba8fd0..de255b52928d9abec4724a118feb41b3e56fada0 100644 GIT binary patch delta 5454 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 X1(&uPAwy;)t%nX0) delta 3101 zcmZ9OdrVYE6vk(EL6Ew*ATBOYUMtx}5Q-YKqU~xQJ|I?OZR0Dl60E2^6c9ml7nEJJ z_&lwOQl%;uAFbGHMeGCmhkYb%gKdn(+SWF)p;aqQjIl<$Ju~+%d$N&38fd=zHNV;-BJB5^v($lpQHQaDE&d*4KG6bXha`Y53Dx#gBo*mXmUbjQEgn zBVmBgZPA94#OZ`vHmCU$;#3i?RyL(>8O9F-&(7iXFg5!uOiCW6Jj_1N4eye?ca*M4 zi#b06BPZvWH;}+bgzJ=|$uo4^1Lvkh^H%tJiiN+a+@11D5Z|jzotDO@ULwgm39ll2 zfbe<3wMyIc5FWmVSPdM$vzhn>xbnh$egaZnJjC}w-;CHr*VE+F6}|?OMgH%o@habn zaP7gf;kBRm#oELM^as@O@@2aiB?m~>rNf+=87anezhx$zMtA~r&9pe}#Fnkm2d&!wS?;kHxWKW z_;RX$$uq>isIvNOd`SY=2;U<7C`0)rH$E+5dD)6(Wq3wZthOb~^8*}JsqlDx6U?ez z0Hcv)!Dr6ch!!<+6eIs( z&uWFgoXdDS%yvz8x-eG+ipMZE9_J7rJ)yHu$Ko;Fs_A~zA?F$E&~zle%K9G0Y2_voN8Q*vBN+0vGU-{ zMgpz(&uhVwh+f;at!)B^!pn&|loGKwmRP7Kh` z1ZaDJo;#?W>W=dV4ebsDXx}mHE1)GHekMTs4oqMEHv#b*J{^O*5PZjHXxcD59D*8h zVQIs`;1cxo!0V$zwg0|tV0J$bEA>X`_ZVS=dlbxdhw@%%c268?tifz-M(A@Vm=_|6 znf=d{h>2)~=Xst8^E}p}`%sIValk#%=rwy1g6o9`4*iI*mD{ zr!BDtA{(Cz+ghcXk2x%A%nq|_#q@AE*chLbi$Q&!w-hffHBbB1_NB*tB?PZWQzzE8 UxvJH;?|Jj>MEzp2!M~XQ10^$}umAu6 diff --git a/KubeArmor/enforcer/bpflsm/rulesHandling.go b/KubeArmor/enforcer/bpflsm/rulesHandling.go new file mode 100644 index 0000000000..4fe649c683 --- /dev/null +++ b/KubeArmor/enforcer/bpflsm/rulesHandling.go @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2022 Authors of KubeArmor + +package bpflsm + +import ( + cm "github.com/kubearmor/KubeArmor/KubeArmor/common" + tp "github.com/kubearmor/KubeArmor/KubeArmor/types" +) + +func (be *BPFEnforcer) UpdateContainerRules(id string, securityPolicies []tp.SecurityPolicy) { + for _, secPolicy := range securityPolicies { + if len(secPolicy.Spec.Process.MatchPaths) > 0 { + for _, path := range secPolicy.Spec.Process.MatchPaths { + if len(path.FromSource) == 0 { + be.Logger.Printf("Rule %d for %s - %s", cm.JHash([]byte(path.Path), 0), path.Path, id) + be.ContainerMap[id].Map.Put(cm.JHash([]byte(path.Path), 0), [8]byte{}) + } else { + for _, src := range path.FromSource { + be.Logger.Printf("Rule %d for %s (%s) - %s", cm.JHash(append([]byte(path.Path), []byte(src.Path)...), 0), path.Path, src.Path, id) + be.ContainerMap[id].Map.Put(cm.JHash(append([]byte(path.Path), []byte(src.Path)...), 0), [8]byte{}) + } + } + } + } + } +} diff --git a/KubeArmor/enforcer/runtimeEnforcer.go b/KubeArmor/enforcer/runtimeEnforcer.go index f6da5d7a7b..1d00415dbd 100644 --- a/KubeArmor/enforcer/runtimeEnforcer.go +++ b/KubeArmor/enforcer/runtimeEnforcer.go @@ -149,7 +149,9 @@ func (re *RuntimeEnforcer) UpdateSecurityPolicies(endPoint tp.EndPoint) { return } - if re.EnforcerType == "AppArmor" { + if re.EnforcerType == "BPFLSM" { + re.bpfEnforcer.UpdateSecurityPolicies(endPoint) + } else if re.EnforcerType == "AppArmor" { re.appArmorEnforcer.UpdateSecurityPolicies(endPoint) } else if re.EnforcerType == "SELinux" { // do nothing