Commit 4823b721 authored by Alexei Starovoitov's avatar Alexei Starovoitov
Browse files

Merge branch 'bpf_get_ns_current_pid_tgid'



Carlos Neira says:

====================
Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
scripts but this helper returns the pid as seen by the root namespace which is
fine when a bcc script is not executed inside a container.
When the process of interest is inside a container, pid filtering will not work
if bpf_get_current_pid_tgid() is used.
This helper addresses this limitation returning the pid as it's seen by the current
namespace where the script is executing.

In the future different pid_ns files may belong to different devices, according to the
discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
used to do pid filtering even inside a container.
====================

Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents 132c1af0 1c1052e0
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -247,6 +247,20 @@ out_invalid:
	return ERR_PTR(-EINVAL);
}

/**
 * ns_match() - Returns true if current namespace matches dev/ino provided.
 * @ns_common: current ns
 * @dev: dev_t from nsfs that will be matched against current nsfs
 * @ino: ino_t from nsfs that will be matched against current nsfs
 *
 * Return: true if dev and ino matches the current nsfs.
 */
bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino)
{
	return (ns->inum == ino) && (nsfs_mnt->mnt_sb->s_dev == dev);
}


static int nsfs_show_path(struct seq_file *seq, struct dentry *dentry)
{
	struct inode *inode = d_inode(dentry);
+1 −0
Original line number Diff line number Diff line
@@ -1497,6 +1497,7 @@ extern const struct bpf_func_proto bpf_strtol_proto;
extern const struct bpf_func_proto bpf_strtoul_proto;
extern const struct bpf_func_proto bpf_tcp_sock_proto;
extern const struct bpf_func_proto bpf_jiffies64_proto;
extern const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto;

/* Shared helpers among cBPF and eBPF. */
void bpf_user_rnd_init_once(void);
+2 −0
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ typedef struct ns_common *ns_get_path_helper_t(void *);
extern int ns_get_path_cb(struct path *path, ns_get_path_helper_t ns_get_cb,
			    void *private_data);

extern bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino);

extern int ns_get_name(char *buf, size_t size, struct task_struct *task,
			const struct proc_ns_operations *ns_ops);
extern void nsfs_init(void);
+19 −1
Original line number Diff line number Diff line
@@ -2914,6 +2914,19 @@ union bpf_attr {
 *		of sizeof(struct perf_branch_entry).
 *
 *		**-ENOENT** if architecture does not support branch records.
 *
 * int bpf_get_ns_current_pid_tgid(u64 dev, u64 ino, struct bpf_pidns_info *nsdata, u32 size)
 *	Description
 *		Returns 0 on success, values for *pid* and *tgid* as seen from the current
 *		*namespace* will be returned in *nsdata*.
 *
 *		On failure, the returned value is one of the following:
 *
 *		**-EINVAL** if dev and inum supplied don't match dev_t and inode number
 *              with nsfs of current task, or if dev conversion to dev_t lost high bits.
 *
 *		**-ENOENT** if pidns does not exists for the current task.
 *
 */
#define __BPF_FUNC_MAPPER(FN)		\
	FN(unspec),			\
@@ -3035,7 +3048,8 @@ union bpf_attr {
	FN(tcp_send_ack),		\
	FN(send_signal_thread),		\
	FN(jiffies64),			\
	FN(read_branch_records),
	FN(read_branch_records),	\
	FN(get_ns_current_pid_tgid),

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
 * function eBPF program intends to call
@@ -3829,4 +3843,8 @@ struct bpf_sockopt {
	__s32	retval;
};

struct bpf_pidns_info {
	__u32 pid;
	__u32 tgid;
};
#endif /* _UAPI__LINUX_BPF_H__ */
+1 −0
Original line number Diff line number Diff line
@@ -2149,6 +2149,7 @@ const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
const struct bpf_func_proto bpf_get_current_comm_proto __weak;
const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
const struct bpf_func_proto bpf_get_local_storage_proto __weak;
const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto __weak;

const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
{
Loading