forked from kubearmor/KubeArmor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Detect BPF on the host system - Setup eBPF objects for BPF LSM program - Boilerplate BPFLSM Program Signed-off-by: daemon1024 <[email protected]>
- Loading branch information
1 parent
b7a0176
commit 590d420
Showing
10 changed files
with
452 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,3 +19,6 @@ contribution/vagrant/*.log | |
|
||
# protobuf | ||
protobuf/go.sum | ||
|
||
#header | ||
vmlinux.h |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// +build ignore | ||
|
||
#include "vmlinux.h" | ||
#include <bpf/bpf_core_read.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | ||
#define EPERM 1 | ||
|
||
struct outer_key { | ||
u32 pid_ns; | ||
u32 mnt_ns; | ||
}; | ||
|
||
struct outer_hash { | ||
__uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); | ||
__uint(max_entries, 1024); | ||
__uint(key_size, sizeof(struct outer_key)); | ||
__uint(value_size, sizeof(u32)); | ||
__uint(pinning, LIBBPF_PIN_BY_NAME); | ||
}; | ||
|
||
struct outer_hash kubearmor_containers SEC(".maps"); | ||
|
||
static __always_inline u32 get_task_pid_ns_id(struct task_struct *task) { | ||
return BPF_CORE_READ(task, nsproxy, pid_ns_for_children, ns).inum; | ||
} | ||
|
||
static __always_inline u32 get_task_mnt_ns_id(struct task_struct *task) { | ||
return BPF_CORE_READ(task, nsproxy, mnt_ns, ns).inum; | ||
} | ||
|
||
static struct file *get_task_file(struct task_struct *task) { | ||
return BPF_CORE_READ(task, mm, exe_file); | ||
} | ||
|
||
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(); | ||
|
||
struct outer_key okey = {.pid_ns = get_task_pid_ns_id(t), | ||
.mnt_ns = get_task_mnt_ns_id(t)}; | ||
|
||
if (okey.pid_ns == PROC_PID_INIT_INO) { | ||
return 0; | ||
} | ||
|
||
u32 *inner = bpf_map_lookup_elem(&kubearmor_containers, &okey); | ||
|
||
if (!inner) { | ||
return 0; | ||
} | ||
|
||
bpf_printk("monitoring %u,%u", okey.pid_ns, okey.mnt_ns); | ||
|
||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright 2022 Authors of KubeArmor | ||
|
||
package bpflsm | ||
|
||
import ( | ||
"sync" | ||
|
||
"github.com/cilium/ebpf" | ||
"github.com/cilium/ebpf/link" | ||
"github.com/cilium/ebpf/rlimit" | ||
fd "github.com/kubearmor/KubeArmor/KubeArmor/feeder" | ||
tp "github.com/kubearmor/KubeArmor/KubeArmor/types" | ||
) | ||
|
||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang enforcer ../../BPF/enforcer.bpf.c -- -I/usr/include/bpf -O2 -g | ||
|
||
type BPFEnforcer struct { | ||
Logger *fd.Feeder | ||
|
||
InnerMapSpec *ebpf.MapSpec | ||
BPFContainerMap *ebpf.Map | ||
|
||
// ContainerID -> NsKey + rules | ||
ContainerMap map[string]ContainerKV | ||
ContainerMapLock *sync.RWMutex | ||
|
||
obj enforcerObjects | ||
|
||
Probes map[string]link.Link | ||
} | ||
|
||
func NewBPFEnforcer(node tp.Node, logger *fd.Feeder) *BPFEnforcer { | ||
|
||
be := &BPFEnforcer{} | ||
|
||
be.Logger = logger | ||
|
||
var err error | ||
|
||
if err := rlimit.RemoveMemlock(); err != nil { | ||
be.Logger.Errf("Error removing rlimit %v", err) | ||
return nil | ||
} | ||
|
||
be.InnerMapSpec = &ebpf.MapSpec{ | ||
Type: ebpf.Hash, | ||
KeySize: 4, | ||
ValueSize: 8, | ||
MaxEntries: 1024, | ||
} | ||
|
||
be.BPFContainerMap, err = ebpf.NewMapWithOptions(&ebpf.MapSpec{ | ||
Type: ebpf.HashOfMaps, | ||
KeySize: 8, | ||
ValueSize: 4, | ||
MaxEntries: 1024, | ||
Pinning: ebpf.PinByName, | ||
InnerMap: be.InnerMapSpec, | ||
Name: "kubearmor_containers", | ||
}, ebpf.MapOptions{ | ||
PinPath: "/sys/fs/bpf", | ||
}) | ||
if err != nil { | ||
be.Logger.Errf("error creating kubearmor_containers map: %s", err) | ||
return nil | ||
} | ||
|
||
if err := loadEnforcerObjects(&be.obj, &ebpf.CollectionOptions{ | ||
Maps: ebpf.MapOptions{ | ||
PinPath: "/sys/fs/bpf", | ||
}, | ||
}); err != nil { | ||
be.Logger.Errf("error loading BPF LSM objects: %v", err) | ||
return nil | ||
} | ||
|
||
be.Probes = make(map[string]link.Link) | ||
be.ContainerMap = make(map[string]ContainerKV) | ||
be.ContainerMapLock = new(sync.RWMutex) | ||
|
||
be.Probes[be.obj.EnforceProc.String()], err = link.AttachLSM(link.LSMOptions{Program: be.obj.EnforceProc}) | ||
if err != nil { | ||
be.Logger.Errf("opening kprobe %s: %s", be.obj.EnforceProc.String(), err) | ||
return nil | ||
} | ||
|
||
return be | ||
} | ||
|
||
func (be *BPFEnforcer) DestroyBPFEnforcer() error { | ||
if be == nil { | ||
return nil | ||
} | ||
|
||
if err := be.obj.Close(); err != nil { | ||
return err | ||
} | ||
|
||
if be.BPFContainerMap != nil { | ||
if err := be.BPFContainerMap.Unpin(); err != nil { | ||
return err | ||
} | ||
if err := be.BPFContainerMap.Close(); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
for _, link := range be.Probes { | ||
if err := link.Close(); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Binary file not shown.
Oops, something went wrong.