Skip to content

Commit

Permalink
feat: added capability hook
Browse files Browse the repository at this point in the history
Signed-off-by: Aryan-sharma11 <aryan1126.sharma@gmail.com>
  • Loading branch information
Aryan-sharma11 committed Jan 9, 2024
1 parent e64ccb7 commit 40cb640
Show file tree
Hide file tree
Showing 20 changed files with 558 additions and 14 deletions.
130 changes: 130 additions & 0 deletions KubeArmor/BPF/enforcer.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,4 +437,134 @@ int BPF_PROG(enforce_file_perm, struct file *file, int mask) {

struct path f_path = BPF_CORE_READ(file, f_path);
return match_and_enforce_path_hooks(&f_path, dfilewrite, _FILE_PERMISSION);
}
SEC("lsm/capable")
int BPF_PROG(enforce_cap, const struct cred *cred, struct user_namespace *ns ,int cap, int ret){

event *task_info;

struct task_struct *t = (struct task_struct *)bpf_get_current_task();

bool match = false;

struct outer_key okey;
get_outer_key(&okey, t);

u32 *inner = bpf_map_lookup_elem(&kubearmor_containers, &okey);

if (!inner) {
return 0;
}

u32 zero = 0;
bufs_k *z = bpf_map_lookup_elem(&bufk, &zero);
if (z == NULL)
return 0;

u32 one = 1;
bufs_k *p = bpf_map_lookup_elem(&bufk, &one);
if (p == NULL)
return 0;

u32 two = 2;
bufs_k *store = bpf_map_lookup_elem(&bufk, &two);
if (store == NULL)
return 0;

bpf_map_update_elem(&bufk, &one, z, BPF_ANY);
int p0;
int p1;

struct data_t *val = bpf_map_lookup_elem(inner, p);
bool fromSourceCheck = true;

struct file *file_p = get_task_file(t);
if (file_p == NULL)
fromSourceCheck = false;
bufs_t *src_buf = get_buf(PATH_BUFFER);
if (src_buf == NULL)
fromSourceCheck = false;
struct path f_src = BPF_CORE_READ(file_p, f_path);
if (!prepend_path(&f_src, src_buf))
fromSourceCheck = false;

u32 *src_offset = get_buf_off(PATH_BUFFER);
if (src_offset == NULL)
fromSourceCheck = false;

void *ptr = &src_buf->buf[*src_offset];

if (fromSourceCheck) {
bpf_probe_read_str(p->source, MAX_STRING_SIZE, ptr);
p0 = CAPABLE_KEY;
p1 = cap;
p->path[0] = p0 ;
p->path[1] = p1 ;
val = bpf_map_lookup_elem(inner, p);

if (val) {
match = true;
goto decision;
}

val = bpf_map_lookup_elem(inner, p);
}

bpf_map_update_elem(&bufk, &one, z, BPF_ANY);

p->path[0] = p0;
p->path[1] = p1;

val = bpf_map_lookup_elem(inner, p);

if (val) {
match = true;
goto decision;
}
decision:

task_info = bpf_ringbuf_reserve(&kubearmor_events, sizeof(event), 0);
if (!task_info) {
return 0;
}
// Clearing arrays to avoid garbage values to be parsed
__builtin_memset(task_info->data.path, 0, sizeof(task_info->data.path));
__builtin_memset(task_info->data.source, 0, sizeof(task_info->data.source));

init_context(task_info);
bpf_probe_read_str(&task_info->data.path, MAX_STRING_SIZE, p->path);
bpf_probe_read_str(&task_info->data.source, MAX_STRING_SIZE, p->source);

task_info->event_id = _CAPABLE;

task_info->retval = -EPERM;

bpf_map_update_elem(&bufk, &one, z, BPF_ANY);
p->path[0] = dcap;
struct data_t *allow = bpf_map_lookup_elem(inner, p);

if (allow) {
if (!match) {
if(allow->processmask == BLOCK_POSTURE) {
bpf_ringbuf_submit(task_info, BPF_RB_FORCE_WAKEUP);
return -EPERM;
} else {
task_info->retval = 0;
bpf_ringbuf_submit(task_info, BPF_RB_FORCE_WAKEUP);
return 0;
}
}
} else {
if (match) {
if (val && (val->processmask & RULE_DENY)) {
bpf_ringbuf_submit(task_info, BPF_RB_FORCE_WAKEUP);
return -EPERM;
}
}
}
bpf_ringbuf_discard(task_info, BPF_RB_NO_WAKEUP);


return 0;

}
4 changes: 3 additions & 1 deletion KubeArmor/BPF/shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ char LICENSE[] SEC("license") = "Dual BSD/GPL";
#define TASK_COMM_LEN 80
#define AUDIT_POSTURE 140
#define BLOCK_POSTURE 141
#define CAPABLE_KEY 200

enum file_hook_type { dpath = 0, dfileread, dfilewrite };

enum deny_by_default {
dproc = 101,
dfile,
dnet
dnet,
dcap
}; // check if the list is whitelist/blacklist
enum network_check_type {
sock_type = 2,
Expand Down
3 changes: 3 additions & 0 deletions KubeArmor/BPF/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ enum
//process
_SECURITY_BPRM_CHECK = 352,

// capabilities
_CAPABLE = 464,


};
#endif /* __SYSCALLS_H */
10 changes: 10 additions & 0 deletions KubeArmor/enforcer/bpflsm/enforcer.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ func NewBPFEnforcer(node tp.Node, pinpath string, logger *fd.Feeder, monitor *mo
be.Logger.Errf("opening lsm %s: %s", be.obj.EnforceNetAccept.String(), err)
return be, err
}
be.Probes[be.obj.EnforceCap.String()], err = link.AttachLSM(link.LSMOptions{Program: be.obj.EnforceCap})
if err != nil {
be.Logger.Errf("opening lsm %s: %s", be.obj.EnforceCap.String(), err)
return be, err
}

/*
Path Hooks
Expand Down Expand Up @@ -338,6 +343,11 @@ func (be *BPFEnforcer) TraceEvents() {
log.Source = string(bytes.Trim(event.Data.Source[:], "\x00"))
log.Resource = string(bytes.Trim(event.Data.Path[:], "\x00"))
log.Data = "lsm=" + mon.GetSyscallName(int32(event.EventID))

case mon.Capable:
log.Operation = "Capabilities"
log.Resource = mon.Capabilities[int32(event.Data.Path[1])]
log.Data = "lsm=" + mon.GetSyscallName(int32(event.EventID)) + " " + log.Resource
}
if event.Retval >= 0 {
log.Result = "Passed"
Expand Down
3 changes: 3 additions & 0 deletions KubeArmor/enforcer/bpflsm/enforcer_bpfeb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified KubeArmor/enforcer/bpflsm/enforcer_bpfeb.o
Binary file not shown.
3 changes: 3 additions & 0 deletions KubeArmor/enforcer/bpflsm/enforcer_bpfel.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified KubeArmor/enforcer/bpflsm/enforcer_bpfel.o
Binary file not shown.
Binary file modified KubeArmor/enforcer/bpflsm/enforcer_path_bpfeb.o
Binary file not shown.
Binary file modified KubeArmor/enforcer/bpflsm/enforcer_path_bpfel.o
Binary file not shown.
Loading

0 comments on commit 40cb640

Please sign in to comment.