Skip to content

Commit

Permalink
Add new LSM_HOOK to restrict root user
Browse files Browse the repository at this point in the history
We have decided to implement new LSH hook which disable root user in container.

Fix #85

Signed-off-by: Michal Jura <mjura@suse.com>
  • Loading branch information
mjura committed Jan 26, 2022
1 parent db33094 commit ad974df
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 2 deletions.
65 changes: 63 additions & 2 deletions lockc/src/bpf/lockc.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,68 @@ int BPF_PROG(mount_audit, const char *dev_name, const struct path *path,
return ret;
}

/*
* setuid_audit - LSM program triggered when user UID is changed.
* The goal is to deny changing user ID from regular account to root user account.
* @cred *new: data structure with new user context
* @cred *old: data structure with old user context
* @flags: additional flags
* @ret_prev: return code of a previous BPF program using the sb_mount hook
*
* Return: 0 if changing UID is allowed. -EPERM if root account not allowed. -EFAULT if there was
* a problem with reading the kernel strings into buffers or any important
* buffer is NULL.
*/
SEC("lsm/task_fix_setuid")
int BPF_PROG(setuid_audit, struct cred *new, const struct cred *old, int flags, int ret_prev)
{
int ret = 0;
char comm[TASK_COMM_LEN];

pid_t pid = bpf_get_current_pid_tgid() >> 32;
enum container_policy_level policy_level = get_policy_level(pid);

if (bpf_get_current_comm(&comm, sizeof(comm)) < 0)
return -EFAULT;

bpf_printk("DEBUG: setuid process: %s\n", comm);

uid_t uid_old = BPF_CORE_READ(old, uid).val;
bpf_printk("DEBUG: setuid old: %d\n", uid_old);

uid_t uid_new = BPF_CORE_READ(new, uid).val;
bpf_printk("DEBUG: setuid new: %d\n", uid_new);

switch (policy_level) {
case POLICY_LEVEL_LOOKUP_ERR:
ret = -EPERM;
goto out;
case POLICY_LEVEL_NOT_FOUND:
bpf_printk("DEBUG: policy: not_found\n");
break;
case POLICY_LEVEL_RESTRICTED:
bpf_printk("DEBUG: policy: restricted\n");
break;
case POLICY_LEVEL_BASELINE:
bpf_printk("DEBUG: policy: baseline\n");
break;
case POLICY_LEVEL_PRIVILEGED:
bpf_printk("root user: allow\n");
goto out;
}

// TODO mjura: add configuration option for what UID this restrion should be applied
if ((uid_new == 0) && (uid_old >= 1000)) {
bpf_printk("root user: deny\n");
ret = -EPERM;
}

out:
if (ret_prev != 0)
return ret_prev;
return ret;
}

SEC("lsm/file_open")
int BPF_PROG(open_audit, struct file *file, int ret_prev)
{
Expand All @@ -415,8 +477,7 @@ int BPF_PROG(open_audit, struct file *file, int ret_prev)
}

if (unlikely(bpf_d_path(&file->f_path, d_path_buf, PATH_LEN) < 0)) {
bpf_printk("warn: could not read the path of opened "
"file\n");
bpf_printk("warn: could not read the path of opened file\n");
goto out;
}
/*
Expand Down
7 changes: 7 additions & 0 deletions lockc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,13 @@ impl<'a> BpfContext<'a> {
}
link_open.pin(path_link_open)?;

let mut link_setuid = skel.progs_mut().setuid_audit().attach_lsm()?;
let path_link_setuid = path_base.join("link_setuid_audit");
if path_link_setuid.exists() {
fs::remove_file(path_link_setuid.clone())?;
}
link_setuid.pin(path_link_setuid)?;

let link_add_container = skel.progs_mut().add_container().attach_uprobe_addr(
false,
-1,
Expand Down

0 comments on commit ad974df

Please sign in to comment.