From patchwork Wed Mar 4 20:41:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlos Antonio Neira Bustos X-Patchwork-Id: 1249234 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=pSk4ExAQ; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48Xm6M2sCDz9sPg for ; Thu, 5 Mar 2020 07:42:51 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388203AbgCDUmu (ORCPT ); Wed, 4 Mar 2020 15:42:50 -0500 Received: from mail-qk1-f194.google.com ([209.85.222.194]:37954 "EHLO mail-qk1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728482AbgCDUmt (ORCPT ); Wed, 4 Mar 2020 15:42:49 -0500 Received: by mail-qk1-f194.google.com with SMTP id j7so2815256qkd.5; Wed, 04 Mar 2020 12:42:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Y5Ky3RnrstKzYFwSJbD0y3YJuOUDmcCn0OUSxFr3kjs=; b=pSk4ExAQesGPiRkrJ4m00/3RVcmAmGlJgQUb5vmLH7+GRgdGDIRD3GfX6ewBFztnD2 ldGhLdH1lHCoiY0YM1qiK1CtLCmBHZ0403AOR7mNWGlDLI4Vm4GaLVHRin4nXAkC+GT5 EZTrHwwcoH3sjTOOW5BhX0YXVaY46Y2RWiKlF7B476jPo5XINnkD0nH59HwHyZhsQ6vD BGP854EDkNLZvzjFydVbBnzJ/b7smMgz/xxRYwE3Sil0o2xXQpDpTGTe8s3aA7sjGj1g MshwFhx9hCu76TirTz8KODlsgb+odSNf9VHkFm+4GWRi7C8Mz8gEbnExlKObm697leiX HbsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Y5Ky3RnrstKzYFwSJbD0y3YJuOUDmcCn0OUSxFr3kjs=; b=R9qcFvUt0dRCGBl1PNAGU5S0L3DIyN1QVogiJF/qqdKparj0oacRbCTq+Bod6exaBA qgGVJZnBMAV2Ub27U0ONfJGBheRzaMP6Nrc2BnhbBlaxYXfa0xNLdwi5hSUkNfPn7R6o H1sMbN9IyLglZiDfmbfVgXlzzxEFbmzcYlUybM784vTSl/T9HuPmp6OBdn/1tIdjKEg6 qexGW6hlBHe3sQNeKT94o4vTY1uRD8lv0ScIIh4fWBivgV18vuDaglSiOjX/KIWdXuiX An1kf1qlI6rUfoH/6MGMGC3BW3cWBeR9rWDgBPzdN94I4T73zQhVKl57Bne/V0N97zAk cT4A== X-Gm-Message-State: ANhLgQ0/oY71OVEqutzGAukcTinufKeryzYuTS7FhjaaASuW67VlKRia KJt4sPbOELWxsmjf8RszYum2C/dl034= X-Google-Smtp-Source: ADFU+vs/fU4OISIPlNO4ygCwyMz7YhRvm6N60yw7Yxep3TCJbDZWcHw4ZPVdt+cQbjpTsjTboIQB7Q== X-Received: by 2002:a37:8046:: with SMTP id b67mr4691395qkd.218.1583354568564; Wed, 04 Mar 2020 12:42:48 -0800 (PST) Received: from localhost.localdomain (pc-184-104-160-190.cm.vtr.net. [190.160.104.184]) by smtp.googlemail.com with ESMTPSA id 82sm1750232qko.91.2020.03.04.12.42.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Mar 2020 12:42:48 -0800 (PST) From: Carlos Neira To: netdev@vger.kernel.org Cc: yhs@fb.com, ebiederm@xmission.com, brouer@redhat.com, bpf@vger.kernel.org, cneirabustos@gmail.com Subject: [PATCH v17 1/3] fs/nsfs.c: added ns_match Date: Wed, 4 Mar 2020 17:41:55 -0300 Message-Id: <20200304204157.58695-2-cneirabustos@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200304204157.58695-1-cneirabustos@gmail.com> References: <20200304204157.58695-1-cneirabustos@gmail.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org ns_match returns true if the namespace inode and dev_t matches the ones provided by the caller. Signed-off-by: Carlos Neira --- fs/nsfs.c | 14 ++++++++++++++ include/linux/proc_ns.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/fs/nsfs.c b/fs/nsfs.c index b13bfd406820..4f1205725cfe 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -247,6 +247,20 @@ struct file *proc_ns_fget(int fd) 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); diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h index 4626b1ac3b6c..adff08bfecf9 100644 --- a/include/linux/proc_ns.h +++ b/include/linux/proc_ns.h @@ -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); From patchwork Wed Mar 4 20:41:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlos Antonio Neira Bustos X-Patchwork-Id: 1249236 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=FiZibzMf; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48Xm6P03dnz9sPK for ; Thu, 5 Mar 2020 07:42:53 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388255AbgCDUmw (ORCPT ); Wed, 4 Mar 2020 15:42:52 -0500 Received: from mail-qk1-f194.google.com ([209.85.222.194]:32781 "EHLO mail-qk1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388230AbgCDUmw (ORCPT ); Wed, 4 Mar 2020 15:42:52 -0500 Received: by mail-qk1-f194.google.com with SMTP id p62so3087974qkb.0; Wed, 04 Mar 2020 12:42:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=e/XdTuBcTBU3OvToQ1oQMV0HPKeoQN+MyXw643ySz0k=; b=FiZibzMfIRDuqgCQakpTGLqbBB/RQUgEqftKDmi+bcDocykrJM5nt6zSVD6Eqay0Fm DtKZBQRFkzbW+qPaFgKMvdYZJV5i+8ytUr+J4Itd689y6BFrR1pzNZarrujIGy1SxZp9 Su5yKP/7wnrszG3rWWgKHvQphaRCCggTLFsAr3NTxm+DgGjCi+xdeFOX+QIIOCNj8qDJ 4Tw+C5UaPnyoCxAakNdrL3D5CL58hi6nk/sE04nDfd8b58mUsMFM2hGxxfYFcySwC949 6jL3eBMN/LCFKGk4qCSF9PPUoggLCX+RTeSOL+eRqcyzNWDPQygdMoFXNAcQizwMJKow VZ6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=e/XdTuBcTBU3OvToQ1oQMV0HPKeoQN+MyXw643ySz0k=; b=lg9uBGGdfwxjYKSRNllrkZ4TyURhUfxDvB9zaP2QYwK6dZ0yEf1QBhRI+zX0LHlaKv QF0uh9XEN4NW3r5OY2DiAMyEqUnzB+e5A9qB5XX91yBOoLqgZDi586yS53W+rULHfbEe SAk3wLacJxAPWJvGtZFVKjbEb91pfn630Mky27hg69ZChmRrxr4QXmmC/WQZ0om02pvT 9JOYrRN6naNDwHykfvHQNS8j/xKH7kWwuUzUrpMFON2d71d2LBmpzFM8hm53qWtsAkJr LOf3cnyQRhbVJJxlSvuiXYat3bwkV2vfRp78Dscrg4lotwQfX1HgppaJwAxeRlfXOa+U mZzw== X-Gm-Message-State: ANhLgQ0FosHLvbDHWWWM01bGScTzawTbt3LrY24WFKsy7+DvcPla0Q9F ei9Mcb8oba5xpyPuMjWjyEHci2/8Knc= X-Google-Smtp-Source: ADFU+vuKJEhGVBIbrJpnm87uxdEcoKf2bAgUVqk9ljM6gNr7F44CUEKvn9YotQEyvV8vGC8fy6NBIA== X-Received: by 2002:ae9:efc8:: with SMTP id d191mr1632872qkg.1.1583354570629; Wed, 04 Mar 2020 12:42:50 -0800 (PST) Received: from localhost.localdomain (pc-184-104-160-190.cm.vtr.net. [190.160.104.184]) by smtp.googlemail.com with ESMTPSA id 82sm1750232qko.91.2020.03.04.12.42.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Mar 2020 12:42:50 -0800 (PST) From: Carlos Neira To: netdev@vger.kernel.org Cc: yhs@fb.com, ebiederm@xmission.com, brouer@redhat.com, bpf@vger.kernel.org, cneirabustos@gmail.com Subject: [PATCH v17 2/3] bpf: added new helper bpf_get_ns_current_pid_tgid Date: Wed, 4 Mar 2020 17:41:56 -0300 Message-Id: <20200304204157.58695-3-cneirabustos@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200304204157.58695-1-cneirabustos@gmail.com> References: <20200304204157.58695-1-cneirabustos@gmail.com> MIME-Version: 1.0 Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org New bpf helper bpf_get_ns_current_pid_tgid, This helper will return pid and tgid from current task which namespace matches dev_t and inode number provided, this will allows us to instrument a process inside a container. Signed-off-by: Carlos Neira Acked-by: Yonghong Song --- include/linux/bpf.h | 1 + include/uapi/linux/bpf.h | 20 ++++++++++++++- kernel/bpf/core.c | 1 + kernel/bpf/helpers.c | 45 ++++++++++++++++++++++++++++++++++ kernel/trace/bpf_trace.c | 2 ++ scripts/bpf_helpers_doc.py | 1 + tools/include/uapi/linux/bpf.h | 20 ++++++++++++++- 7 files changed, 88 insertions(+), 2 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index f13c78c6f29d..8d6380394388 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1472,6 +1472,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); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index d6b33ea27bcc..f3ad826fa3bd 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2913,6 +2913,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), \ @@ -3034,7 +3047,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 @@ -3828,4 +3842,8 @@ struct bpf_sockopt { __s32 retval; }; +struct bpf_pidns_info { + __u32 pid; + __u32 tgid; +}; #endif /* _UAPI__LINUX_BPF_H__ */ diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 973a20d49749..0f9ca46e1978 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -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) { diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index d8b7b110a1c5..01878db15eaf 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "../../lib/kstrtox.h" @@ -499,3 +501,46 @@ const struct bpf_func_proto bpf_strtoul_proto = { .arg4_type = ARG_PTR_TO_LONG, }; #endif + +BPF_CALL_4(bpf_get_ns_current_pid_tgid, u64, dev, u64, ino, + struct bpf_pidns_info *, nsdata, u32, size) +{ + struct task_struct *task = current; + struct pid_namespace *pidns; + int err = -EINVAL; + + if (unlikely(size != sizeof(struct bpf_pidns_info))) + goto clear; + + if (unlikely((u64)(dev_t)dev != dev)) + goto clear; + + if (unlikely(!task)) + goto clear; + + pidns = task_active_pid_ns(task); + if (unlikely(!pidns)) { + err = -ENOENT; + goto clear; + } + + if (!ns_match(&pidns->ns, (dev_t)dev, ino)) + goto clear; + + nsdata->pid = task_pid_nr_ns(task, pidns); + nsdata->tgid = task_tgid_nr_ns(task, pidns); + return 0; +clear: + memset((void *)nsdata, 0, (size_t) size); + return err; +} + +const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto = { + .func = bpf_get_ns_current_pid_tgid, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_ANYTHING, + .arg2_type = ARG_ANYTHING, + .arg3_type = ARG_PTR_TO_UNINIT_MEM, + .arg4_type = ARG_CONST_SIZE, +}; diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 07764c761073..d7985629a3b1 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -843,6 +843,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_send_signal_thread_proto; case BPF_FUNC_perf_event_read_value: return &bpf_perf_event_read_value_proto; + case BPF_FUNC_get_ns_current_pid_tgid: + return &bpf_get_ns_current_pid_tgid_proto; default: return NULL; } diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py index cebed6fb5bbb..c1e2b5410faa 100755 --- a/scripts/bpf_helpers_doc.py +++ b/scripts/bpf_helpers_doc.py @@ -435,6 +435,7 @@ class PrinterHelpers(Printer): 'struct bpf_fib_lookup', 'struct bpf_perf_event_data', 'struct bpf_perf_event_value', + 'struct bpf_pidns_info', 'struct bpf_sock', 'struct bpf_sock_addr', 'struct bpf_sock_ops', diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index d6b33ea27bcc..f3ad826fa3bd 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2913,6 +2913,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), \ @@ -3034,7 +3047,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 @@ -3828,4 +3842,8 @@ struct bpf_sockopt { __s32 retval; }; +struct bpf_pidns_info { + __u32 pid; + __u32 tgid; +}; #endif /* _UAPI__LINUX_BPF_H__ */ From patchwork Wed Mar 4 20:41:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlos Antonio Neira Bustos X-Patchwork-Id: 1249238 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=gvnIrR+F; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48Xm6R1fFgz9sPF for ; Thu, 5 Mar 2020 07:42:55 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388309AbgCDUmy (ORCPT ); Wed, 4 Mar 2020 15:42:54 -0500 Received: from mail-qk1-f178.google.com ([209.85.222.178]:33655 "EHLO mail-qk1-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388230AbgCDUmy (ORCPT ); Wed, 4 Mar 2020 15:42:54 -0500 Received: by mail-qk1-f178.google.com with SMTP id p62so3088086qkb.0; Wed, 04 Mar 2020 12:42:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HQgb+cG4NkJXbnS+nj0Rdtq6SmKME6zMCxCGCB6CvAY=; b=gvnIrR+Fo17aHtz6sgCzGEJbMkWl5bKEWAXpa1xKU1XXDrOGm/OiMIAlxolImZQftc E+Kw/OzRo9FRlKmldQwpVpfzkxuRnPemQRkGmjOVd9GNjWsD5rOl1GvDKysjqJm/aMC7 +tnfEGGvkRdYq32n/dpA5Uh6HWwa07X+kjW6Pdvl2psSX+tMjKHUA4o/xysLTv/9T3+w HEGsgUQJjvzZQmCkKyo7qrihNo4ewsTR78MxR4b8ONU5+BZND+pC1DbA0kUlXMVwMIBm cFbsFg+ev14fbtTheuryBCRx3fN2ZvSbypr2HpU85kxKCkrjGFtLJEggJa0KZvy/0P2Z CSzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HQgb+cG4NkJXbnS+nj0Rdtq6SmKME6zMCxCGCB6CvAY=; b=XwGWMqbV3Pz7YVaWf1ov1GvGwIRfxHFhTEc48u4mz+2SpbjW/oL/vQnJZZ6opheMWn iVlhWN/5v9AYKE/YgdICmMWTKT7jXi0Fj0FdgBrnEM2nv+HmyoUHew9vpHEjeAzKSWMX uC5Mc8tdNSdOAhucVbDK4NHBHCjIBAlVmrExLu99cKr1T0mRZuzkIpm4hhLuCys23r6C iFyvYM4F1/6UVUhDfbtLFQ0vIzgNvoK7w6rnuvO0GEonUMzTxHYaWvmzkIk8X3dA3FGf Sg1YectW4itoSqdruyibf5+vrKGZSBgN1IGGvHcOrrX1WJGwwhAmc+oKsWrPxV6/nZC6 DIMg== X-Gm-Message-State: ANhLgQ3ma/Rb+bn/3Tw5KEAo6hqxy2/muvPbc2ZtKvRiEZa6mWHLWWqM gRuFvDY1A81IYKPZW2pdKltGRzqqqnA= X-Google-Smtp-Source: ADFU+vvf4fC5BLknlP1Of1MfY9/b3dGqUj1faYZIH7gpgJjiE18Y7hA4ncnSsZrPTd7aPIOxUlDS6A== X-Received: by 2002:a05:620a:228f:: with SMTP id o15mr344854qkh.197.1583354572768; Wed, 04 Mar 2020 12:42:52 -0800 (PST) Received: from localhost.localdomain (pc-184-104-160-190.cm.vtr.net. [190.160.104.184]) by smtp.googlemail.com with ESMTPSA id 82sm1750232qko.91.2020.03.04.12.42.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Mar 2020 12:42:52 -0800 (PST) From: Carlos Neira To: netdev@vger.kernel.org Cc: yhs@fb.com, ebiederm@xmission.com, brouer@redhat.com, bpf@vger.kernel.org, cneirabustos@gmail.com Subject: [PATCH v17 3/3] tools/testing/selftests/bpf: Add self-tests for new helper bpf_get_ns_current_pid_tgid. Date: Wed, 4 Mar 2020 17:41:57 -0300 Message-Id: <20200304204157.58695-4-cneirabustos@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200304204157.58695-1-cneirabustos@gmail.com> References: <20200304204157.58695-1-cneirabustos@gmail.com> MIME-Version: 1.0 Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Self tests added for new helper bpf_get_ns_current_pid_tgid Signed-off-by: Carlos Neira --- tools/testing/selftests/bpf/Makefile | 3 +- .../bpf/prog_tests/ns_current_pid_tgid.c | 88 ++++++++++ .../bpf/progs/test_ns_current_pid_tgid.c | 37 ++++ .../bpf/test_current_pid_tgid_new_ns.c | 159 ++++++++++++++++++ 4 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c create mode 100644 tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c create mode 100644 tools/testing/selftests/bpf/test_current_pid_tgid_new_ns.c diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 2d7f5df33f04..ea77239095a1 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -32,7 +32,8 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \ test_cgroup_storage \ test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \ - test_progs-no_alu32 + test_progs-no_alu32 \ + test_current_pid_tgid_new_ns # Also test bpf-gcc, if present ifneq ($(BPF_GCC),) diff --git a/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c b/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c new file mode 100644 index 000000000000..542240e16564 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Carlos Neira cneirabustos@gmail.com */ +#include +#include +#include +#include +#include + +struct bss { + __u64 dev; + __u64 ino; + __u64 pid_tgid; + __u64 user_pid_tgid; +}; + +void test_ns_current_pid_tgid(void) +{ + const char *probe_name = "raw_tracepoint/sys_enter"; + const char *file = "test_ns_current_pid_tgid.o"; + int err, key = 0, duration = 0; + struct bpf_link *link = NULL; + struct bpf_program *prog; + struct bpf_map *bss_map; + struct bpf_object *obj; + struct bss bss; + struct stat st; + __u64 id; + + obj = bpf_object__open_file(file, NULL); + if (CHECK(IS_ERR(obj), "obj_open", "err %ld\n", PTR_ERR(obj))) + return; + + err = bpf_object__load(obj); + if (CHECK(err, "obj_load", "err %d errno %d\n", err, errno)) + goto cleanup; + + bss_map = bpf_object__find_map_by_name(obj, "test_ns_.bss"); + if (CHECK(!bss_map, "find_bss_map", "failed\n")) + goto cleanup; + + prog = bpf_object__find_program_by_title(obj, probe_name); + if (CHECK(!prog, "find_prog", "prog '%s' not found\n", + probe_name)) + goto cleanup; + + memset(&bss, 0, sizeof(bss)); + pid_t tid = syscall(SYS_gettid); + pid_t pid = getpid(); + + id = (__u64) tid << 32 | pid; + bss.user_pid_tgid = id; + + if (CHECK_FAIL(stat("/proc/self/ns/pid", &st))) { + perror("Failed to stat /proc/self/ns/pid"); + goto cleanup; + } + + bss.dev = st.st_dev; + bss.ino = st.st_ino; + + err = bpf_map_update_elem(bpf_map__fd(bss_map), &key, &bss, 0); + if (CHECK(err, "setting_bss", "failed to set bss : %d\n", err)) + goto cleanup; + + link = bpf_program__attach_raw_tracepoint(prog, "sys_enter"); + if (CHECK(IS_ERR(link), "attach_raw_tp", "err %ld\n", + PTR_ERR(link))) { + link = NULL; + goto cleanup; + } + + /* trigger some syscalls */ + usleep(1); + + err = bpf_map_lookup_elem(bpf_map__fd(bss_map), &key, &bss); + if (CHECK(err, "set_bss", "failed to get bss : %d\n", err)) + goto cleanup; + + if (CHECK(id != bss.pid_tgid, "Compare user pid/tgid vs. bpf pid/tgid", + "User pid/tgid %llu BPF pid/tgid %llu\n", id, bss.pid_tgid)) + goto cleanup; +cleanup: + if (!link) { + bpf_link__destroy(link); + link = NULL; + } + bpf_object__close(obj); +} diff --git a/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c b/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c new file mode 100644 index 000000000000..1dca70a6de2f --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2019 Carlos Neira cneirabustos@gmail.com */ + +#include +#include +#include + +static volatile struct { + __u64 dev; + __u64 ino; + __u64 pid_tgid; + __u64 user_pid_tgid; +} res; + +SEC("raw_tracepoint/sys_enter") +int trace(void *ctx) +{ + __u64 ns_pid_tgid, expected_pid; + struct bpf_pidns_info nsdata; + __u32 key = 0; + + if (bpf_get_ns_current_pid_tgid(res.dev, res.ino, &nsdata, + sizeof(struct bpf_pidns_info))) + return 0; + + ns_pid_tgid = (__u64)nsdata.tgid << 32 | nsdata.pid; + expected_pid = res.user_pid_tgid; + + if (expected_pid != ns_pid_tgid) + return 0; + + res.pid_tgid = ns_pid_tgid; + + return 0; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/test_current_pid_tgid_new_ns.c b/tools/testing/selftests/bpf/test_current_pid_tgid_new_ns.c new file mode 100644 index 000000000000..16e94effa5f5 --- /dev/null +++ b/tools/testing/selftests/bpf/test_current_pid_tgid_new_ns.c @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Carlos Neira cneirabustos@gmail.com */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include "test_progs.h" + +#define CHECK_NEWNS(condition, tag, format...) ({ \ + int __ret = !!(condition); \ + if (__ret) { \ + printf("%s:FAIL:%s ", __func__, tag); \ + printf(format); \ + } else { \ + printf("%s:PASS:%s\n", __func__, tag); \ + } \ + __ret; \ +}) + +struct bss { + __u64 dev; + __u64 ino; + __u64 pid_tgid; + __u64 user_pid_tgid; +}; + +int main(int argc, char **argv) +{ + pid_t pid; + int exit_code = 1; + struct stat st; + + printf("Testing bpf_get_ns_current_pid_tgid helper in new ns\n"); + + if (stat("/proc/self/ns/pid", &st)) { + perror("stat failed on /proc/self/ns/pid ns\n"); + printf("%s:FAILED\n", argv[0]); + return exit_code; + } + + if (CHECK_NEWNS(unshare(CLONE_NEWPID | CLONE_NEWNS), + "unshare CLONE_NEWPID | CLONE_NEWNS", "error errno=%d\n", errno)) + return exit_code; + + pid = fork(); + if (pid == -1) { + perror("Fork() failed\n"); + printf("%s:FAILED\n", argv[0]); + return exit_code; + } + + if (pid > 0) { + int status; + + usleep(5); + waitpid(pid, &status, 0); + return 0; + } else { + + pid = fork(); + if (pid == -1) { + perror("Fork() failed\n"); + printf("%s:FAILED\n", argv[0]); + return exit_code; + } + + if (pid > 0) { + int status; + waitpid(pid, &status, 0); + return 0; + } else { + if (CHECK_NEWNS(mount("none", "/proc", NULL, MS_PRIVATE|MS_REC, NULL), + "Unmounting proc", "Cannot umount proc! errno=%d\n", errno)) + return exit_code; + + if (CHECK_NEWNS(mount("proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL), + "Mounting proc", "Cannot mount proc! errno=%d\n", errno)) + return exit_code; + + const char *probe_name = "raw_tracepoint/sys_enter"; + const char *file = "test_ns_current_pid_tgid.o"; + struct bpf_link *link = NULL; + struct bpf_program *prog; + struct bpf_map *bss_map; + struct bpf_object *obj; + int exit_code = 1; + int err, key = 0; + struct bss bss; + struct stat st; + __u64 id; + + obj = bpf_object__open_file(file, NULL); + if (CHECK_NEWNS(IS_ERR(obj), "obj_open", "err %ld\n", PTR_ERR(obj))) + return exit_code; + + err = bpf_object__load(obj); + if (CHECK_NEWNS(err, "obj_load", "err %d errno %d\n", err, errno)) + goto cleanup; + + bss_map = bpf_object__find_map_by_name(obj, "test_ns_.bss"); + if (CHECK_NEWNS(!bss_map, "find_bss_map", "failed\n")) + goto cleanup; + + prog = bpf_object__find_program_by_title(obj, probe_name); + if (CHECK_NEWNS(!prog, "find_prog", "prog '%s' not found\n", + probe_name)) + goto cleanup; + + memset(&bss, 0, sizeof(bss)); + pid_t tid = syscall(SYS_gettid); + pid_t pid = getpid(); + + id = (__u64) tid << 32 | pid; + bss.user_pid_tgid = id; + + if (CHECK_NEWNS(stat("/proc/self/ns/pid", &st), + "stat new ns", "Failed to stat /proc/self/ns/pid errno=%d\n", errno)) + goto cleanup; + + bss.dev = st.st_dev; + bss.ino = st.st_ino; + + err = bpf_map_update_elem(bpf_map__fd(bss_map), &key, &bss, 0); + if (CHECK_NEWNS(err, "setting_bss", "failed to set bss : %d\n", err)) + goto cleanup; + + link = bpf_program__attach_raw_tracepoint(prog, "sys_enter"); + if (CHECK_NEWNS(IS_ERR(link), "attach_raw_tp", "err %ld\n", + PTR_ERR(link))) { + link = NULL; + goto cleanup; + } + + /* trigger some syscalls */ + usleep(1); + + err = bpf_map_lookup_elem(bpf_map__fd(bss_map), &key, &bss); + if (CHECK_NEWNS(err, "set_bss", "failed to get bss : %d\n", err)) + goto cleanup; + + if (CHECK_NEWNS(id != bss.pid_tgid, "Compare user pid/tgid vs. bpf pid/tgid", + "User pid/tgid %llu BPF pid/tgid %llu\n", id, bss.pid_tgid)) + goto cleanup; + + exit_code = 0; + printf("%s:PASS\n", argv[0]); +cleanup: + if (!link) { + bpf_link__destroy(link); + link = NULL; + } + bpf_object__close(obj); + } + } +}