blob: e733834c57124bfc8c1e2333567f0eb0955feda8 [file] [log] [blame] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SECAGENTD_BPF_BPF_UTILS_H_
#define SECAGENTD_BPF_BPF_UTILS_H_
#include "secagentd/bpf/bpf_types.h"
#define CROS_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
static inline __attribute__((always_inline)) bool is_kthread(
const struct task_struct* t) {
// From sched.h:
// #define PF_KTHREAD 0x00200000
return (BPF_CORE_READ(t, flags) & 0x00200000);
}
static inline __attribute__((always_inline)) const struct task_struct*
cros_normalize_to_last_exec(const struct task_struct* t) {
const struct task_struct* ret = t;
// Arbitrarily selected limit to convince the verifier that the BPF will
// always halt.
for (int i = 0; i < 64; ++i) {
struct task_struct* parent = BPF_CORE_READ(ret, real_parent, group_leader);
if ((!parent) || (BPF_CORE_READ(ret, self_exec_id) !=
BPF_CORE_READ(parent, self_exec_id))) {
break;
}
ret = parent;
}
return ret;
}
static inline __attribute__((always_inline)) void cros_fill_task_info(
struct cros_process_task_info* task_info, const struct task_struct* t) {
const struct task_struct* parent =
cros_normalize_to_last_exec(BPF_CORE_READ(t, real_parent, group_leader));
task_info->ppid = BPF_CORE_READ(parent, tgid);
task_info->parent_start_time = BPF_CORE_READ(parent, start_boottime);
task_info->start_time = BPF_CORE_READ(t, group_leader, start_boottime);
task_info->pid = BPF_CORE_READ(t, tgid);
task_info->uid = BPF_CORE_READ(t, real_cred, uid.val);
task_info->gid = BPF_CORE_READ(t, real_cred, gid.val);
// Read argv from user memory.
const uintptr_t arg_start = (uintptr_t)BPF_CORE_READ(t, mm, arg_start);
const uintptr_t arg_end = (uintptr_t)BPF_CORE_READ(t, mm, arg_end);
task_info->real_commandline_len = arg_end - arg_start;
if ((arg_end - arg_start) > sizeof(task_info->commandline)) {
task_info->commandline_len = sizeof(task_info->commandline);
} else {
task_info->commandline_len = (uint32_t)(arg_end - arg_start);
}
bpf_probe_read_user(task_info->commandline, task_info->commandline_len,
(const void*)arg_start);
if (task_info->commandline_len == sizeof(task_info->commandline)) {
task_info->commandline[task_info->commandline_len - 1] = '\0';
}
}
#endif // SECAGENTD_BPF_BPF_UTILS_H_