diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index ec6d85a81744..e8295101b865 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -4735,6 +4735,18 @@ union bpf_attr {
* be zero-terminated except when **str_size** is 0.
*
* Or **-EBUSY** if the per-CPU memory copy buffer is busy.
+ *
+ * int bpf_get_current_cpuset_cgroup_path(char *buf, u32 buf_len)
+ * Description
+ * Get the cpuset cgroup path of current task from kernel memory,
+ * this path can be used to identify in which container is the
+ * current task running.
+ * *buf* memory is pre-allocated, and *buf_len* indicates the size
+ * of this memory.
+ *
+ * Return
+ * The cpuset cgroup path is copied into *buf* on success,
+ * or a negative integer error in case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \@@ -4903,6 +4915,7 @@ union bpf_attr {
FN(check_mtu), \
FN(for_each_map_elem), \
FN(snprintf), \
+ FN(get_current_cpuset_cgroup_path), \
/* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helperdiff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c
index 5efb2b24012c..5e62e3875df1 100644
--- a/kernel/bpf/bpf_lsm.c
+++ b/kernel/bpf/bpf_lsm.c
@@ -99,6 +99,30 @@ static const struct bpf_func_proto bpf_ima_inode_hash_proto = {
.allowed = bpf_ima_inode_hash_allowed,
};
+#ifdef CONFIG_CGROUPS
+BPF_CALL_2(bpf_get_current_cpuset_cgroup_path, char *, buf, u32, buf_len)
+{
+ struct cgroup_subsys_state *css;
+ int retval;
+
+ css = task_get_css(current, cpuset_cgrp_id);
+ retval = cgroup_path_ns(css->cgroup, buf, buf_len, &init_cgroup_ns);
+ css_put(css);
+ if (retval >= buf_len)
+ retval = -ENAMETOOLONG;
+ return retval;
+}
+
+static const struct bpf_func_proto bpf_get_current_cpuset_cgroup_path_proto = {
+ .func = bpf_get_current_cpuset_cgroup_path,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_PTR_TO_UNINIT_MEM,
+ .arg2_type = ARG_CONST_SIZE,
+ .allowed = bpf_ima_inode_hash_allowed,
+};
+#endif
+
static const struct bpf_func_proto *
bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{@@ -119,6 +143,10 @@ bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_bprm_opts_set_proto;
case BPF_FUNC_ima_inode_hash:
return prog->aux->sleepable ? &bpf_ima_inode_hash_proto : NULL;
+#ifdef CONFIG_CGROUPS
+ case BPF_FUNC_get_current_cpuset_cgroup_path:
+ return prog->aux->sleepable ? &bpf_get_current_cpuset_cgroup_path_proto : NULL;
+#endif
default:
return tracing_prog_func_proto(func_id, prog);
}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index ec6d85a81744..fe31252d92e3 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -4735,6 +4735,18 @@ union bpf_attr {
* be zero-terminated except when **str_size** is 0.
*
* Or **-EBUSY** if the per-CPU memory copy buffer is busy.
+ *
+ * int bpf_get_current_cpuset_cgroup_path(char *buf, u32 buf_len)
+ * Description
+ * Get the cpuset cgroup path of current task from kernel memory,
+ * this path can be used to identify in which container is the
+ * current task running.
+ * *buf* memory is pre-allocated, and *buf_len* indicates the size
+ * of this memory.
+ *
+ * Return
+ * The cpuset cgroup path is copied into *buf* on success,
+ * or a negative integer error in case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \@@ -4903,6 +4915,7 @@ union bpf_attr {
FN(check_mtu), \
FN(for_each_map_elem), \
FN(snprintf), \
+ FN(get_current_cpuset_cgroup_path), \
/* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper--
2.20.1 (Apple Git-117)