Message ID | 20231015232953.84836-3-hengqi.chen@gmail.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2908:b0:403:3b70:6f57 with SMTP id ib8csp3185127vqb; Sun, 15 Oct 2023 18:47:52 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHoQd7Ew7mn6k+K8L/+1oh/nWucECx9b6h6ZxUbQE9T1Kd/Nhn5FV3WKUURq3B4hjKP+Ow0 X-Received: by 2002:a05:6871:8788:b0:1e9:8a7e:5893 with SMTP id td8-20020a056871878800b001e98a7e5893mr14788757oab.5.1697420872324; Sun, 15 Oct 2023 18:47:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697420872; cv=none; d=google.com; s=arc-20160816; b=vQMZUfchIl9NbDEDBVGbfU4EqAY5fJ09ToilV+NXNB1iF+pXMgxQDq4AF31pgqFrYl 6IydKIefR1/qQLJZVnouzk0dgQQprHwmlIoZsPqA3Tfro6fss8ylhVHIopHcP+joRVJv Q4/25GbccXDyNmtSUG6/JdPWySntNjholcrGRi9hDXABdjAwHKItywryOd+tEiChhsiT 6ca8HTlq7EVWauQY4vd+jiwxAApYU8HED5Dyocg2ViwLgxaM3FN7p9Uh2/LNc9G6QGwa U5gZNS9FHqaNuLEY2KSYQ0N4XtDgvzsUNfhuPTfSCOUVD0pfgABBrSr82IKJKs0TW2kN e64w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=kSRIz1vcgrjsRKJR1DAFgT80TJOeno9JVnMf1bkF8yQ=; fh=UUVBB6hdZtgkdevQaSWXrPPcR6FiQNJo3IQxWCli3s0=; b=V89Yb+MC+U6PO1/U7X+6WtHlBuRo3wHYZUpH3FvF7SBMeMT98hRgZPkgkPP9KaFnfx yAlOiyBP/Su2QHyWfmvM2GN++cwMF3eDsz7PSkYRTfhFVtgW0PjvpgiNSlaezOjSe/Vw Qz44L3cwleubW4U56HOKneSshgNY0NmirTFZWHTWferAqoukzAPzt68wx+icAY0u1eCZ fWb313AdVsn1UctA95eQBWWqv5svARaDQ7Ei8Oglh5Tf0LrkS9jz7nrmn2RTa9uX8oqP smpTZ+AFCaDhsHyCJy3D587Ve0tW59AFZc+aV14urwtTe+xG0LBAG/3040Y3jOeT55FS 5kbw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=LHGgOUlq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id m10-20020a634c4a000000b0055c7eb53d7fsi9391386pgl.584.2023.10.15.18.47.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Oct 2023 18:47:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=LHGgOUlq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 658F180A73D0; Sun, 15 Oct 2023 18:47:51 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231240AbjJPBrp (ORCPT <rfc822;hjfbswb@gmail.com> + 19 others); Sun, 15 Oct 2023 21:47:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33740 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231214AbjJPBrm (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sun, 15 Oct 2023 21:47:42 -0400 Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 03D45F4; Sun, 15 Oct 2023 18:47:37 -0700 (PDT) Received: by mail-pf1-x433.google.com with SMTP id d2e1a72fcca58-6b2018a11efso2402457b3a.0; Sun, 15 Oct 2023 18:47:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1697420856; x=1698025656; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kSRIz1vcgrjsRKJR1DAFgT80TJOeno9JVnMf1bkF8yQ=; b=LHGgOUlqsGoQijaWFtVw0zgQtzoBgVsejg25gDfGoTDVaXt7zgixYS1WYbvJsuiJl0 5aGxxlqDrAhmXESGDotyIiMODzeg+3Oo6zDFOfSKTa9f5VtWpIODIXt9PevhR6SNnAch 3GUFwiffKuaakcBKlmZhqAjtNCZuYaWSYIdTjv/7EeHnhQgqQmdtYxMau1Uknmd3f71i Z6tEu1CUZJLJq3FMOowQWaJ0hvUXpfcXLAAyYype84ebdwTLvDWdpi1wFPuK8TeNGWPt jIx2n6/t+31Ihr6aRbJIZnUwKhPaTxe9hDOsE0nPG3g+GX2JiT67NNKaJqGKKRc8aSgd BVPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697420856; x=1698025656; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kSRIz1vcgrjsRKJR1DAFgT80TJOeno9JVnMf1bkF8yQ=; b=Xop1EOnnsWzLZpVq0Qk55ABG+Mm/PtS/euqZpfZjgx3WCnNLRKbXEB7k9F0KzPQGjl qSgIOrgtmzlndc9/dL8XN7AWoEEWq+0v4GOmOiMSWBe1iN3jymSVc8l9tQDPegrsHYFQ fV7XCCIu8I3crUhOFqMwPqgc4oxGtJs9Au2ceADledQ9JgPw5iBcs1I45VvorCREXw52 oMvq4r2m1uN9Tql34O/GvGWfdefcsYkXLck+hHDWfSTviPUX9HtMl1haj+pBB33adlG3 eZT02guJ29Unm2owkzrNm+Rkr/R1ThGa1CQnaLc5KayX4EuySTNRnQhpNODRIQL/ONam JsfQ== X-Gm-Message-State: AOJu0Yy/+hZgXXwo1yxv7MAueIq8LKVWWN1+B9oFhWKi5c0uK+tC/0SP E61ey51P8rP5zytg0aGVVMSAof8AqDp84A== X-Received: by 2002:a05:6a21:7785:b0:179:f79e:8615 with SMTP id bd5-20020a056a21778500b00179f79e8615mr5301459pzc.52.1697420856610; Sun, 15 Oct 2023 18:47:36 -0700 (PDT) Received: from ubuntu.. ([203.205.141.13]) by smtp.googlemail.com with ESMTPSA id pd17-20020a17090b1dd100b0027cfb5f010dsm3574377pjb.4.2023.10.15.18.47.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Oct 2023 18:47:35 -0700 (PDT) From: Hengqi Chen <hengqi.chen@gmail.com> To: linux-kernel@vger.kernel.org, bpf@vger.kernel.org Cc: keescook@chromium.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, luto@amacapital.net, wad@chromium.org, alexyonghe@tencent.com, hengqi.chen@gmail.com Subject: [PATCH v2 2/5] seccomp, bpf: Introduce SECCOMP_LOAD_FILTER operation Date: Sun, 15 Oct 2023 23:29:50 +0000 Message-Id: <20231015232953.84836-3-hengqi.chen@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231015232953.84836-1-hengqi.chen@gmail.com> References: <20231015232953.84836-1-hengqi.chen@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Sun, 15 Oct 2023 18:47:51 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1779874788721009466 X-GMAIL-MSGID: 1779874788721009466 |
Series |
seccomp: Make seccomp filter reusable
|
|
Commit Message
Hengqi Chen
Oct. 15, 2023, 11:29 p.m. UTC
This patch adds a new operation named SECCOMP_LOAD_FILTER.
It accepts a sock_fprog the same as SECCOMP_SET_MODE_FILTER
but only performs the loading process. If succeed, return a
new fd associated with the JITed BPF program (the filter).
The filter can then be pinned to bpffs using the returned
fd and reused for different processes. To distinguish the
filter from other BPF progs, BPF_PROG_TYPE_SECCOMP is added.
Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
---
include/uapi/linux/bpf.h | 1 +
include/uapi/linux/seccomp.h | 1 +
kernel/seccomp.c | 43 ++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 1 +
4 files changed, 46 insertions(+)
Comments
On 10/16/23 1:29 AM, Hengqi Chen wrote: > This patch adds a new operation named SECCOMP_LOAD_FILTER. > It accepts a sock_fprog the same as SECCOMP_SET_MODE_FILTER > but only performs the loading process. If succeed, return a > new fd associated with the JITed BPF program (the filter). > The filter can then be pinned to bpffs using the returned > fd and reused for different processes. To distinguish the > filter from other BPF progs, BPF_PROG_TYPE_SECCOMP is added. > > Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> > --- > include/uapi/linux/bpf.h | 1 + > include/uapi/linux/seccomp.h | 1 + > kernel/seccomp.c | 43 ++++++++++++++++++++++++++++++++++ > tools/include/uapi/linux/bpf.h | 1 + > 4 files changed, 46 insertions(+) > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index 7ba61b75bc0e..61c80ffb1724 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -995,6 +995,7 @@ enum bpf_prog_type { > BPF_PROG_TYPE_SK_LOOKUP, > BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ > BPF_PROG_TYPE_NETFILTER, > + BPF_PROG_TYPE_SECCOMP, Please don't extend UAPI surface if this is not reachable/usable from user space anyway. > enum bpf_attach_type { > diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h > index dbfc9b37fcae..ee2c83697810 100644 > --- a/include/uapi/linux/seccomp.h > +++ b/include/uapi/linux/seccomp.h > @@ -16,6 +16,7 @@ > #define SECCOMP_SET_MODE_FILTER 1 > #define SECCOMP_GET_ACTION_AVAIL 2 > #define SECCOMP_GET_NOTIF_SIZES 3 > +#define SECCOMP_LOAD_FILTER 4 > > /* Valid flags for SECCOMP_SET_MODE_FILTER */ > #define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) > diff --git a/kernel/seccomp.c b/kernel/seccomp.c > index faf84fc892eb..c9f6a19f7a4e 100644 > --- a/kernel/seccomp.c > +++ b/kernel/seccomp.c > @@ -17,6 +17,7 @@ > > #include <linux/refcount.h> > #include <linux/audit.h> > +#include <linux/bpf.h> > #include <linux/compat.h> > #include <linux/coredump.h> > #include <linux/kmemleak.h> > @@ -25,6 +26,7 @@ > #include <linux/sched.h> > #include <linux/sched/task_stack.h> > #include <linux/seccomp.h> > +#include <linux/security.h> > #include <linux/slab.h> > #include <linux/syscalls.h> > #include <linux/sysctl.h> > @@ -2032,12 +2034,48 @@ static long seccomp_set_mode_filter(unsigned int flags, > seccomp_filter_free(prepared); > return ret; > } > + > +static long seccomp_load_filter(const char __user *filter) > +{ > + struct sock_fprog fprog; > + struct bpf_prog *prog; > + int ret; > + > + ret = seccomp_copy_user_filter(filter, &fprog); > + if (ret) > + return ret; > + > + ret = seccomp_prepare_prog(&prog, &fprog); > + if (ret) > + return ret; > + > + ret = security_bpf_prog_alloc(prog->aux); > + if (ret) { > + bpf_prog_free(prog); > + return ret; > + } > + > + prog->aux->user = get_current_user(); > + atomic64_set(&prog->aux->refcnt, 1); > + prog->type = BPF_PROG_TYPE_SECCOMP; > + > + ret = bpf_prog_new_fd(prog); > + if (ret < 0) > + bpf_prog_put(prog); My bigger concern here is that bpf_prog_new_fd() is only used by eBPF (not cBPF). Then you get an 'eBPF'-like fd back to user space which you can pass to various other bpf(2) commands like BPF_OBJ_GET_INFO_BY_FD etc which all have the assumption that this is a proper looking eBPF prog fd. There may be breakage/undefined behavior in subtle ways. I would suggest two potential alternatives : 1) Build a seccomp-specific fd via anon_inode_getfd() so that BPF side does not confuse it with bpf_prog_fops and therefore does not recognize it in bpf(2) as a prog fd. 2) Extend seccomp where proper eBPF could be supported. If option 2) is not realistic (where you would get this out of the box), then I think 1) could be however. > + return ret; > +} > #else > static inline long seccomp_set_mode_filter(unsigned int flags, > const char __user *filter) > { > return -EINVAL; > } > + > +static inline long seccomp_load_filter(const char __user *filter) > +{ > + return -EINVAL; > +} > #endif > > static long seccomp_get_action_avail(const char __user *uaction) > @@ -2099,6 +2137,11 @@ static long do_seccomp(unsigned int op, unsigned int flags, > return -EINVAL; > > return seccomp_get_notif_sizes(uargs); > + case SECCOMP_LOAD_FILTER: > + if (flags != 0) > + return -EINVAL; > + > + return seccomp_load_filter(uargs); > default: > return -EINVAL; > } > diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h > index 7ba61b75bc0e..61c80ffb1724 100644 > --- a/tools/include/uapi/linux/bpf.h > +++ b/tools/include/uapi/linux/bpf.h > @@ -995,6 +995,7 @@ enum bpf_prog_type { > BPF_PROG_TYPE_SK_LOOKUP, > BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ > BPF_PROG_TYPE_NETFILTER, > + BPF_PROG_TYPE_SECCOMP, > }; > > enum bpf_attach_type { >
Hi Hengqi, kernel test robot noticed the following build errors: [auto build test ERROR on kees/for-next/seccomp] [also build test ERROR on bpf-next/master bpf/master linus/master v6.6-rc6 next-20231020] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Hengqi-Chen/seccomp-Refactor-filter-copy-create-for-reuse/20231017-134654 base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/seccomp patch link: https://lore.kernel.org/r/20231015232953.84836-3-hengqi.chen%40gmail.com patch subject: [PATCH v2 2/5] seccomp, bpf: Introduce SECCOMP_LOAD_FILTER operation config: sh-shx3_defconfig (https://download.01.org/0day-ci/archive/20231023/202310230704.Uif0R7cz-lkp@intel.com/config) compiler: sh4-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231023/202310230704.Uif0R7cz-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202310230704.Uif0R7cz-lkp@intel.com/ All errors (new ones prefixed by >>): kernel/seccomp.c: In function 'seccomp_load_filter': >> kernel/seccomp.c:2052:15: error: implicit declaration of function 'security_bpf_prog_alloc'; did you mean 'security_msg_msg_alloc'? [-Werror=implicit-function-declaration] 2052 | ret = security_bpf_prog_alloc(prog->aux); | ^~~~~~~~~~~~~~~~~~~~~~~ | security_msg_msg_alloc >> kernel/seccomp.c:2062:15: error: implicit declaration of function 'bpf_prog_new_fd'; did you mean 'bpf_prog_get_ok'? [-Werror=implicit-function-declaration] 2062 | ret = bpf_prog_new_fd(prog); | ^~~~~~~~~~~~~~~ | bpf_prog_get_ok cc1: some warnings being treated as errors vim +2052 kernel/seccomp.c 2037 2038 static long seccomp_load_filter(const char __user *filter) 2039 { 2040 struct sock_fprog fprog; 2041 struct bpf_prog *prog; 2042 int ret; 2043 2044 ret = seccomp_copy_user_filter(filter, &fprog); 2045 if (ret) 2046 return ret; 2047 2048 ret = seccomp_prepare_prog(&prog, &fprog); 2049 if (ret) 2050 return ret; 2051 > 2052 ret = security_bpf_prog_alloc(prog->aux); 2053 if (ret) { 2054 bpf_prog_free(prog); 2055 return ret; 2056 } 2057 2058 prog->aux->user = get_current_user(); 2059 atomic64_set(&prog->aux->refcnt, 1); 2060 prog->type = BPF_PROG_TYPE_SECCOMP; 2061 > 2062 ret = bpf_prog_new_fd(prog); 2063 if (ret < 0) 2064 bpf_prog_put(prog); 2065 2066 return ret; 2067 } 2068 #else 2069 static inline long seccomp_set_mode_filter(unsigned int flags, 2070 const char __user *filter) 2071 { 2072 return -EINVAL; 2073 } 2074
On Mon, Oct 16, 2023 at 8:44 PM Daniel Borkmann <daniel@iogearbox.net> wrote: > > On 10/16/23 1:29 AM, Hengqi Chen wrote: > > This patch adds a new operation named SECCOMP_LOAD_FILTER. > > It accepts a sock_fprog the same as SECCOMP_SET_MODE_FILTER > > but only performs the loading process. If succeed, return a > > new fd associated with the JITed BPF program (the filter). > > The filter can then be pinned to bpffs using the returned > > fd and reused for different processes. To distinguish the > > filter from other BPF progs, BPF_PROG_TYPE_SECCOMP is added. > > > > Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> > > --- > > include/uapi/linux/bpf.h | 1 + > > include/uapi/linux/seccomp.h | 1 + > > kernel/seccomp.c | 43 ++++++++++++++++++++++++++++++++++ > > tools/include/uapi/linux/bpf.h | 1 + > > 4 files changed, 46 insertions(+) > > > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > > index 7ba61b75bc0e..61c80ffb1724 100644 > > --- a/include/uapi/linux/bpf.h > > +++ b/include/uapi/linux/bpf.h > > @@ -995,6 +995,7 @@ enum bpf_prog_type { > > BPF_PROG_TYPE_SK_LOOKUP, > > BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ > > BPF_PROG_TYPE_NETFILTER, > > + BPF_PROG_TYPE_SECCOMP, > > Please don't extend UAPI surface if this is not reachable/usable from user > space anyway. > > > enum bpf_attach_type { > > diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h > > index dbfc9b37fcae..ee2c83697810 100644 > > --- a/include/uapi/linux/seccomp.h > > +++ b/include/uapi/linux/seccomp.h > > @@ -16,6 +16,7 @@ > > #define SECCOMP_SET_MODE_FILTER 1 > > #define SECCOMP_GET_ACTION_AVAIL 2 > > #define SECCOMP_GET_NOTIF_SIZES 3 > > +#define SECCOMP_LOAD_FILTER 4 > > > > /* Valid flags for SECCOMP_SET_MODE_FILTER */ > > #define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) > > diff --git a/kernel/seccomp.c b/kernel/seccomp.c > > index faf84fc892eb..c9f6a19f7a4e 100644 > > --- a/kernel/seccomp.c > > +++ b/kernel/seccomp.c > > @@ -17,6 +17,7 @@ > > > > #include <linux/refcount.h> > > #include <linux/audit.h> > > +#include <linux/bpf.h> > > #include <linux/compat.h> > > #include <linux/coredump.h> > > #include <linux/kmemleak.h> > > @@ -25,6 +26,7 @@ > > #include <linux/sched.h> > > #include <linux/sched/task_stack.h> > > #include <linux/seccomp.h> > > +#include <linux/security.h> > > #include <linux/slab.h> > > #include <linux/syscalls.h> > > #include <linux/sysctl.h> > > @@ -2032,12 +2034,48 @@ static long seccomp_set_mode_filter(unsigned int flags, > > seccomp_filter_free(prepared); > > return ret; > > } > > + > > +static long seccomp_load_filter(const char __user *filter) > > +{ > > + struct sock_fprog fprog; > > + struct bpf_prog *prog; > > + int ret; > > + > > + ret = seccomp_copy_user_filter(filter, &fprog); > > + if (ret) > > + return ret; > > + > > + ret = seccomp_prepare_prog(&prog, &fprog); > > + if (ret) > > + return ret; > > + > > + ret = security_bpf_prog_alloc(prog->aux); > > + if (ret) { > > + bpf_prog_free(prog); > > + return ret; > > + } > > + > > + prog->aux->user = get_current_user(); > > + atomic64_set(&prog->aux->refcnt, 1); > > + prog->type = BPF_PROG_TYPE_SECCOMP; > > + > > + ret = bpf_prog_new_fd(prog); > > + if (ret < 0) > > + bpf_prog_put(prog); > > My bigger concern here is that bpf_prog_new_fd() is only used by eBPF (not cBPF). > > Then you get an 'eBPF'-like fd back to user space which you can pass to various > other bpf(2) commands like BPF_OBJ_GET_INFO_BY_FD etc which all have the assumption > that this is a proper looking eBPF prog fd. > > There may be breakage/undefined behavior in subtle ways. > > I would suggest two potential alternatives : > > 1) Build a seccomp-specific fd via anon_inode_getfd() so that BPF side does not > confuse it with bpf_prog_fops and therefore does not recognize it in bpf(2) > as a prog fd. > > 2) Extend seccomp where proper eBPF could be supported. > > If option 2) is not realistic (where you would get this out of the box), then I > think 1) could be however. > The intention is to use bpffs, so we need a bpf prog fd. I prefer option 2, though it requires a bit of work. That way, we could also write seccomp filter in eBPF language. Kees, could you share your opinions ? If you have no objection, I will continue this work. > > + return ret; > > +} > > #else > > static inline long seccomp_set_mode_filter(unsigned int flags, > > const char __user *filter) > > { > > return -EINVAL; > > } > > + > > +static inline long seccomp_load_filter(const char __user *filter) > > +{ > > + return -EINVAL; > > +} > > #endif > > > > static long seccomp_get_action_avail(const char __user *uaction) > > @@ -2099,6 +2137,11 @@ static long do_seccomp(unsigned int op, unsigned int flags, > > return -EINVAL; > > > > return seccomp_get_notif_sizes(uargs); > > + case SECCOMP_LOAD_FILTER: > > + if (flags != 0) > > + return -EINVAL; > > + > > + return seccomp_load_filter(uargs); > > default: > > return -EINVAL; > > } > > diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h > > index 7ba61b75bc0e..61c80ffb1724 100644 > > --- a/tools/include/uapi/linux/bpf.h > > +++ b/tools/include/uapi/linux/bpf.h > > @@ -995,6 +995,7 @@ enum bpf_prog_type { > > BPF_PROG_TYPE_SK_LOOKUP, > > BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ > > BPF_PROG_TYPE_NETFILTER, > > + BPF_PROG_TYPE_SECCOMP, > > }; > > > > enum bpf_attach_type { > > >
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 7ba61b75bc0e..61c80ffb1724 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -995,6 +995,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_SK_LOOKUP, BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ BPF_PROG_TYPE_NETFILTER, + BPF_PROG_TYPE_SECCOMP, }; enum bpf_attach_type { diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h index dbfc9b37fcae..ee2c83697810 100644 --- a/include/uapi/linux/seccomp.h +++ b/include/uapi/linux/seccomp.h @@ -16,6 +16,7 @@ #define SECCOMP_SET_MODE_FILTER 1 #define SECCOMP_GET_ACTION_AVAIL 2 #define SECCOMP_GET_NOTIF_SIZES 3 +#define SECCOMP_LOAD_FILTER 4 /* Valid flags for SECCOMP_SET_MODE_FILTER */ #define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) diff --git a/kernel/seccomp.c b/kernel/seccomp.c index faf84fc892eb..c9f6a19f7a4e 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -17,6 +17,7 @@ #include <linux/refcount.h> #include <linux/audit.h> +#include <linux/bpf.h> #include <linux/compat.h> #include <linux/coredump.h> #include <linux/kmemleak.h> @@ -25,6 +26,7 @@ #include <linux/sched.h> #include <linux/sched/task_stack.h> #include <linux/seccomp.h> +#include <linux/security.h> #include <linux/slab.h> #include <linux/syscalls.h> #include <linux/sysctl.h> @@ -2032,12 +2034,48 @@ static long seccomp_set_mode_filter(unsigned int flags, seccomp_filter_free(prepared); return ret; } + +static long seccomp_load_filter(const char __user *filter) +{ + struct sock_fprog fprog; + struct bpf_prog *prog; + int ret; + + ret = seccomp_copy_user_filter(filter, &fprog); + if (ret) + return ret; + + ret = seccomp_prepare_prog(&prog, &fprog); + if (ret) + return ret; + + ret = security_bpf_prog_alloc(prog->aux); + if (ret) { + bpf_prog_free(prog); + return ret; + } + + prog->aux->user = get_current_user(); + atomic64_set(&prog->aux->refcnt, 1); + prog->type = BPF_PROG_TYPE_SECCOMP; + + ret = bpf_prog_new_fd(prog); + if (ret < 0) + bpf_prog_put(prog); + + return ret; +} #else static inline long seccomp_set_mode_filter(unsigned int flags, const char __user *filter) { return -EINVAL; } + +static inline long seccomp_load_filter(const char __user *filter) +{ + return -EINVAL; +} #endif static long seccomp_get_action_avail(const char __user *uaction) @@ -2099,6 +2137,11 @@ static long do_seccomp(unsigned int op, unsigned int flags, return -EINVAL; return seccomp_get_notif_sizes(uargs); + case SECCOMP_LOAD_FILTER: + if (flags != 0) + return -EINVAL; + + return seccomp_load_filter(uargs); default: return -EINVAL; } diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 7ba61b75bc0e..61c80ffb1724 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -995,6 +995,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_SK_LOOKUP, BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ BPF_PROG_TYPE_NETFILTER, + BPF_PROG_TYPE_SECCOMP, }; enum bpf_attach_type {