Skip to content

Commit

Permalink
bpf:cgroups: set ->flags error when reading cgroup info fails
Browse files Browse the repository at this point in the history
Set appropriate EVENT_ERROR_CGROUP_* flags when reading cgroup info
from BPF side fails. It allows to easily identify from user space the
offending bpf code.

Signed-off-by: Djalal Harouni <tixxdz@gmail.com>
(cherry picked from commit 82b216c)
tixxdz authored and kkourt committed Jan 18, 2023

Unverified

This user has not yet uploaded their public signing key.
1 parent 26d5224 commit 4f69f1c
Showing 2 changed files with 24 additions and 23 deletions.
38 changes: 21 additions & 17 deletions bpf/lib/bpf_cgroup.h
Original file line number Diff line number Diff line change
@@ -238,9 +238,12 @@ get_cgroup_id(const struct cgroup *cgrp)
* @task: must be current task.
* @subsys_idx: index of the desired cgroup_subsys_state part of css_set.
* Passing a zero as a subsys_idx is fine assuming you want that.
* @error_flags: error flags that will be ORed to indicate errors on
* failures.
*
* Returns the cgroup of the css part of css_set of current task and is
* indexed at subsys_idx on success, NULL on failures.
* indexed at subsys_idx on success. NULL on failures, and the error_flags
* will be ORed to indicate the corresponding error.
*
* To get cgroup and kernfs node information we want to operate on the right
* cgroup hierarchy which is setup by user space. However due to the
@@ -254,15 +257,17 @@ get_cgroup_id(const struct cgroup *cgrp)
* counting first comment line.
*/
static inline __attribute__((always_inline)) struct cgroup *
get_task_cgroup(struct task_struct *task, __u32 subsys_idx)
get_task_cgroup(struct task_struct *task, __u32 subsys_idx, __u32 *error_flags)
{
struct cgroup_subsys_state *subsys;
struct css_set *cgroups;
struct cgroup *cgrp = NULL;

probe_read(&cgroups, sizeof(cgroups), _(&task->cgroups));
if (unlikely(!cgroups))
if (unlikely(!cgroups)) {
*error_flags |= EVENT_ERROR_CGROUPS;
return cgrp;
}

/* We are interested only in the cpuset, memory or pids controllers
* which are indexed at 0, 4 and 11 respectively assuming all controllers
@@ -280,8 +285,10 @@ get_task_cgroup(struct task_struct *task, __u32 subsys_idx)
* especially if they happen to be before the desired subsys_idx,
* we fail.
*/
if (unlikely(subsys_idx > pids_cgrp_id))
if (unlikely(subsys_idx > pids_cgrp_id)) {
*error_flags |= EVENT_ERROR_CGROUP_SUBSYS;
return cgrp;
}

/* Read css from the passed subsys index to ensure that we operate
* on the desired controller. This allows user space to be flexible
@@ -290,34 +297,34 @@ get_task_cgroup(struct task_struct *task, __u32 subsys_idx)
* in a significant way.
*/
probe_read(&subsys, sizeof(subsys), _(&cgroups->subsys[subsys_idx]));
if (unlikely(!subsys))
if (unlikely(!subsys)) {
*error_flags |= EVENT_ERROR_CGROUP_SUBSYS;
return cgrp;
}

probe_read(&cgrp, sizeof(cgrp), _(&subsys->cgroup));
if (!cgrp)
*error_flags |= EVENT_ERROR_CGROUP_SUBSYSCGRP;

return cgrp;
}

/**
* tg_get_current_cgroup_id() Returns the accurate cgroup id of current task.
* @task: current task.
* @cgrp: cgroup target of current task.
* @cgrpfs_ver: Cgroupfs Magic number either Cgroupv1 or Cgroupv2
* @subsys_idx: index of the desired cgroup_subsys_state part of css_set.
* Passing zero as a subsys_idx is fine assuming that is what you want.
*
* It handles both cgroupv2 and cgroupv1.
* If @cgrpfs_ver is default cgroupv2 hierarchy, then it uses the bpf
* helper bpf_get_current_cgroup_id() to retrieve the cgroup id. Otherwise
* it falls back on the cgroup id of the desired css that is indexed by
* @subsys_idx.
* it falls back on using the passed @cgrp
*
* Returns the cgroup id of current task on success, zero on failures.
*/
static inline __attribute__((always_inline)) __u64
tg_get_current_cgroup_id(struct task_struct *task, __u64 cgrpfs_ver,
__u32 subsys_idx)
tg_get_current_cgroup_id(struct cgroup *cgrp, __u64 cgrpfs_ver)
{
__u64 id = 0;
struct cgroup *cgrp;

/*
* Try the bpf helper on the default hierarchy if available
@@ -328,10 +335,7 @@ tg_get_current_cgroup_id(struct task_struct *task, __u64 cgrpfs_ver,
cgrpfs_ver == CGROUP2_SUPER_MAGIC) {
id = get_current_cgroup_id();
} else {
/* Fallback to read cgroup ID from cgroup of the desired css */
cgrp = get_task_cgroup(task, subsys_idx);
if (cgrp)
id = get_cgroup_id(cgrp);
id = get_cgroup_id(cgrp);
}

return id;
9 changes: 3 additions & 6 deletions bpf/process/bpf_process_event.h
Original file line number Diff line number Diff line change
@@ -532,15 +532,12 @@ __event_get_cgroup_info(struct msg_execve_event *msg,
cgrpfs_magic = conf->cgrp_fs_magic;
}

cgrp = get_task_cgroup(task, subsys_idx);
if (!cgrp) {
process->flags |= EVENT_ERROR_CGROUP_SUBSYSCGRP;
cgrp = get_task_cgroup(task, subsys_idx, &process->flags);
if (!cgrp)
return;
}

/* Collect event cgroup ID */
msg->kube.cgrpid =
tg_get_current_cgroup_id(task, cgrpfs_magic, subsys_idx);
msg->kube.cgrpid = tg_get_current_cgroup_id(cgrp, cgrpfs_magic);
if (!msg->kube.cgrpid) {
process->flags |= EVENT_ERROR_CGROUP_ID;
/* Continue and gather remaining info */

0 comments on commit 4f69f1c

Please sign in to comment.