Skip to content

Commit

Permalink
edriver-rust: execve upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskaliX committed Feb 11, 2024
1 parent b2b8be4 commit 695ce30
Show file tree
Hide file tree
Showing 15 changed files with 9,433 additions and 8,679 deletions.
2 changes: 2 additions & 0 deletions plugins/edriver-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ static = ["libbpf-rs/static"]
anyhow = "1.0"
log = { version = "0.4", features = ["std"] }
libc = "0.2.0"
lru = "0.12.2"
governor = "0.6.0"
libbpf-rs = {version = "0.22.1", features=["static"]}
libbpf-sys = { version = "1.2.1" }
sdk = { path = "../../SDK/rust" }
Expand Down
2 changes: 1 addition & 1 deletion plugins/edriver-rust/src/bpf/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static __always_inline int get_task_pgid(const struct task_struct *cur_task)
}

/* tty */
static __always_inline void *get_task_tty_str(struct task_struct *task)
static __always_inline void *get_task_tty(struct task_struct *task)
{
buf_t *cache = get_percpu_buf(LOCAL_CACHE);
int size = 0;
Expand Down
2 changes: 2 additions & 0 deletions plugins/edriver-rust/src/bpf/common/consts.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#define ARR_ENVS_LEN (64)
#define SOCKET_TRACE_LIMIT (4)
#define SOCKET_FD_NUM_LIMIT (12)
#define PIDTREE_LEN (512)
#define PIDTREE_MASK (PIDTREE_LEN - 1)

/* consts: fds */
#define STDIN (0)
Expand Down
115 changes: 112 additions & 3 deletions plugins/edriver-rust/src/bpf/common/edriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ static struct proc_info *proc_info_init(struct task_struct *);
static unsigned int proc_info_args(struct proc_info *, struct task_struct *);
static unsigned int proc_info_envs(struct proc_info *, struct task_struct *);
static __noinline struct sock *proc_socket_info(struct task_struct *, pid_t *);
static __always_inline int proc_pid_tree(struct proc_info *, struct task_struct *);
static __always_inline int proc_info_creds(struct proc_info *, struct task_struct *);
static __noinline int prepend_pid_tree(struct proc_info *, struct task_struct *);
static __noinline int do_u32toa(uint32_t, char *, int);
static __noinline int match_key(char *, int, uint64_t, int);

SEC("raw_tracepoint/sched_process_exec")
Expand All @@ -34,6 +38,7 @@ int rtp__process_exec(struct bpf_raw_tracepoint_args *ctx)
return -1;
proc_info_args(proc_i, task);
proc_info_envs(proc_i, task);
proc_pid_tree(proc_i, task);

/* report */
struct hds_context c = {0};
Expand All @@ -47,14 +52,17 @@ int rtp__process_exec(struct bpf_raw_tracepoint_args *ctx)
SBT((&c), &proc_i->pgid, S_U32);
SBT((&c), &proc_i->ppid, S_U32);
SBT((&c), &proc_i->sid, S_U32);
SBT((&c), &proc_i->pns, S_U32);
SBT((&c), &proc_i->cred.uid, S_U32);
SBT((&c), &proc_i->cred.gid, S_U32);
SBT((&c), &proc_i->socket_pid, S_U32);
SBT_CHAR((&c), &proc_i->comm);
SBT_CHAR((&c), &proc_i->node);
SBT_CHAR((&c), &proc_i->args);
SBT_CHAR((&c), &proc_i->ssh_conn);
SBT_CHAR((&c), &proc_i->ld_pre);
SBT_CHAR((&c), &proc_i->ld_lib);
SBT_CHAR((&c), get_task_tty_str(task));
SBT_CHAR((&c), get_task_tty(task));
/* pwd */
struct path pwd = BPF_CORE_READ(task, fs, pwd);
save_path(GET_FIELD_ADDR(pwd) ,(&c));
Expand All @@ -66,6 +74,7 @@ int rtp__process_exec(struct bpf_raw_tracepoint_args *ctx)
struct path exe_path = BPF_CORE_READ(task, mm, exe_file, f_path);
save_path(GET_FIELD_ADDR(exe_path), (&c));
SBT((&c), &proc_i->sinfo, sizeof(struct hds_socket_info));
SBT_CHAR((&c), &proc_i->pidtree);

report_event(&c);
return 0;
Expand Down Expand Up @@ -94,12 +103,14 @@ static struct proc_info *proc_info_init(struct task_struct *task)
proc_i->tgid = tgid;
proc_i->ppid = BPF_CORE_READ(task, real_parent, tgid);
proc_i->pgid = get_task_pgid(task);
proc_i->pns = BPF_CORE_READ(task, nsproxy, pid_ns_for_children, ns.inum);
char *uts_name = BPF_CORE_READ(task, nsproxy, uts_ns, name.nodename);
if (uts_name)
bpf_probe_read_str(proc_i->node, MAX_NODENAME, uts_name);
ret = bpf_get_current_comm(&proc_i->comm, TASK_COMM_LEN);
if (ret < 0)
return NULL;
/* socket */
struct sock *sk = proc_socket_info(task, &proc_i->socket_pid);
if (!sk) {
proc_i->socket_pid = 0;
Expand All @@ -111,7 +122,8 @@ static struct proc_info *proc_info_init(struct task_struct *task)
}
proc_i->sinfo = sinfo;
}

/* user */
proc_info_creds(proc_i, task);
return proc_i;
}

Expand Down Expand Up @@ -177,7 +189,6 @@ static unsigned int proc_info_envs(struct proc_info *info, struct task_struct *t
if (sl <= 0)
goto out; /* notice: break do not work on unroll */
len = len + sl;
// cache->buf[(len - 1) & MAX_STR_MASK] = 0x20;
if (match_key(&cache->buf[0], sl, 0x4e4e4f435f485353UL, 14)) {
/* SSH_CONN */
bpf_probe_read_str(info->ssh_conn, MAX_STR_ENV, &cache->buf[15]);
Expand Down Expand Up @@ -229,6 +240,104 @@ static __noinline struct sock *proc_socket_info(struct task_struct *task, pid_t
return sk;
}

/* Elkeid v1.8-rc */
static __always_inline int proc_pid_tree(struct proc_info *info, struct task_struct *task)
{
struct task_struct *parent;
int i;

info->pidtree_len = 0;

#pragma unroll
for (i = 0; i < 12; i++) {
if (!prepend_pid_tree(info, task))
break;
parent = BPF_CORE_READ(task, real_parent);
if (!parent || parent == task)
break;
task = parent;
}

/* trailing \0 added */
if (info->pidtree_len)
info->pidtree_len++;
return (int)info->pidtree_len;
}

static __noinline int prepend_pid_tree(struct proc_info *info, struct task_struct *task)
{
char *comm;
pid_t pid;
int rc = 0, len, last;

pid = BPF_CORE_READ(task, tgid);
if (!pid)
return 0;

len = last = info->pidtree_len;
if (len) {
info->pidtree[len & PIDTREE_MASK] = '<';
len = len + 1;
}
rc = do_u32toa(pid, &info->pidtree[len & PIDTREE_MASK], PIDTREE_LEN - len);
if (!rc)
goto out;
len += rc;
info->pidtree[len & PIDTREE_MASK] = '.';
len = len + 1;
comm = BPF_CORE_READ(task, comm);
if (!comm)
goto out;
if (len >= PIDTREE_LEN - TASK_COMM_LEN)
goto out;
rc = bpf_probe_read_str(&info->pidtree[len & PIDTREE_MASK], TASK_COMM_LEN, comm);
if (rc <= 1)
goto out;
if (rc > TASK_COMM_LEN)
rc = TASK_COMM_LEN;
len += rc - 1;

info->pidtree[len & PIDTREE_MASK] = 0;
info->pidtree_len = len;
return len;

out:
info->pidtree[last & PIDTREE_MASK] = 0;
return 0;
}

static __noinline int do_u32toa(uint32_t v, char *s, int l)
{
char t[16] = {0};
int i;

#pragma unroll
for (i = 0; i < 12; i++) {
t[12 - i] = 0x30 + (v % 10);
v = v / 10;
if (!v)
break;
}
if (i + 1 > l)
return 0;
bpf_probe_read(s, (i + 1) & 15, &t[(12 - i) & 15]);
return (i + 1);
}

static __always_inline int proc_info_creds(struct proc_info *info, struct task_struct *task)
{
info->cred.uid = BPF_CORE_READ(task, real_cred, uid.val);
info->cred.gid = BPF_CORE_READ(task, real_cred, gid.val);
info->cred.suid = BPF_CORE_READ(task, real_cred, suid.val);
info->cred.sgid = BPF_CORE_READ(task, real_cred, sgid.val);
info->cred.euid = BPF_CORE_READ(task, real_cred, euid.val);
info->cred.egid = BPF_CORE_READ(task, real_cred, egid.val);
info->cred.fsuid = BPF_CORE_READ(task, real_cred, fsuid.val);
info->cred.fsgid = BPF_CORE_READ(task, real_cred, fsgid.val);
return 0;
}


#endif

/* from Elkeid 1.8-rc, easier way to match */
Expand Down
26 changes: 15 additions & 11 deletions plugins/edriver-rust/src/bpf/common/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ typedef struct simple_buf {
} buf_t;

/* privilege slim */
struct hds_cred_slim {
kuid_t uid;
kgid_t gid;
kuid_t suid;
kgid_t sgid;
kuid_t euid;
kgid_t egid;
kuid_t fsuid;
kgid_t fsgid;
struct hds_cred {
uid_t uid;
gid_t gid;
uid_t suid;
gid_t sgid;
uid_t euid;
gid_t egid;
uid_t fsuid;
gid_t fsgid;
};

/* socket information */
Expand All @@ -40,6 +40,7 @@ struct proc_info {
__u32 pgid;
__u32 ppid;
__u32 sid;
__u32 pns;
__u32 socket_pid;
char comm[TASK_COMM_LEN];
char node[MAX_NODENAME];
Expand All @@ -48,9 +49,12 @@ struct proc_info {
char ssh_conn[MAX_STR_ENV];
char ld_pre[MAX_STR_ENV];
char ld_lib[MAX_STR_ENV];
/* user info */
struct hds_cred_slim cred;
/* extra information */
struct hds_cred cred;
struct hds_socket_info sinfo;
char pidtree[PIDTREE_LEN];
/* others */
__u16 pidtree_len;
__u64 retval;
};

Expand Down
Loading

0 comments on commit 695ce30

Please sign in to comment.