Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2286596imm; Thu, 14 Jun 2018 11:42:56 -0700 (PDT) X-Google-Smtp-Source: ADUXVKL9GQXdFJDdwtLO7WuCgl/yBTUATOYpXe5WUTp+bkP7csPyCOeLNgiMiwA6JWJBu2upwl7t X-Received: by 2002:a63:6ecd:: with SMTP id j196-v6mr3402584pgc.12.1529001776636; Thu, 14 Jun 2018 11:42:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529001776; cv=none; d=google.com; s=arc-20160816; b=PMkUeI0t1fKAcNkHake44UifbLmEkpfkGUcMVmKEXSO6ouYrbIgxo5bBjFA92tVuBU dsB2uAY3kv7kXe/ymFki/zrslWXDlqGO2v9Lwtj/ZTkhYVOhkQc3TUvUfsP4wxMl8hDQ Ca13YOXdaR2+DjxAjQn8M0epaO6bcJMWW3vYcAXI2K0P2iEh74G7/SLKfPKrl4wGhIxZ ok0VhgRc1GkJ3TlMI7MARRvdnRqQeAW2U2ktrwewB+a7XWbtH6X6AaFW91MlSOPodVH7 LUddFBqW8G7ZFpA0q60MEg4yWhovpEaa83tciOO8lzq/N+OSuG9IScWGFEggTXocr1fj ojOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:arc-authentication-results; bh=vzVvhBFqTUgI0TpGac/D/6WWW1/wIpF1GoLOUiGgufI=; b=UamwZ5PmzSuo4d9e7z7oaiUpOD2dR9AKblhKMzPjtqicigGodDymr+q2E7RYEJ1a+Q yL3t8Zlu2ZsxzGF/vaU8SnWWcTzMgSAuFBXeNFtkGVcclR39RpMCrA5wtE2foY/GYNRH tnCXZcXzjoqz7dB7VlBpgKf22QthqMbQW2+uP5F5xgtNFfwFBBmGiX8GsYDu5cHn4eHJ czInc0jFdPcvmnK1dO+s/tfiV/tTTv61ZBxdJEFj52R0vxIB7V2JJS3l/HIL1qH5YXGx ZWmPI+rtUTn4M6UM5QJaE8G2DLjINbjJbJyIqZ6X5ZOAHTUUpJBFKvs8CjKd/hH45p4n 9vFQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e67-v6si5739861pfa.217.2018.06.14.11.42.40; Thu, 14 Jun 2018 11:42:56 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755245AbeFNSmM (ORCPT + 99 others); Thu, 14 Jun 2018 14:42:12 -0400 Received: from gofer.mess.org ([88.97.38.141]:52989 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754567AbeFNSmK (ORCPT ); Thu, 14 Jun 2018 14:42:10 -0400 Received: by gofer.mess.org (Postfix, from userid 1000) id B6C80602D7; Thu, 14 Jun 2018 19:42:07 +0100 (BST) Date: Thu, 14 Jun 2018 19:42:07 +0100 From: Sean Young To: Daniel Borkmann Cc: Y Song , Matthias Reichl , linux-media@vger.kernel.org, LKML , Alexei Starovoitov , Mauro Carvalho Chehab , netdev , Devin Heitmueller , Quentin Monnet Subject: [PATCH] bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_CGROUP_BPF Message-ID: <20180614184207.khwcmwmj4duous4c@gofer.mess.org> References: <9f2c54d4956f962f44fcda739a824397ddea132c.1527419762.git.sean@mess.org> <20180604174730.sctfoklq7klswebp@camel2.lan> <20180605101629.yffyp64o7adg6hu5@gofer.mess.org> <04cc36e7-4597-dc57-4ad7-71afcc17244a@iogearbox.net> <20180606210939.q3vviyc4b2h6gu3c@gofer.mess.org> <34406f72-722d-9c23-327f-b7c5d7a3090c@iogearbox.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <34406f72-722d-9c23-327f-b7c5d7a3090c@iogearbox.net> User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If the kernel is compiled with CONFIG_CGROUP_BPF not enabled, it is not possible to attach, detach or query IR BPF programs to /dev/lircN devices, making them impossible to use. For embedded devices, it should be possible to use IR decoding without cgroups or CONFIG_CGROUP_BPF enabled. This change requires some refactoring, since bpf_prog_{attach,detach,query} functions are now always compiled, but their code paths for cgroups need moving out. Rather than a #ifdef CONFIG_CGROUP_BPF in kernel/bpf/syscall.c, moving them to kernel/bpf/cgroup.c does not require #ifdefs since that file is already conditionally compiled. Signed-off-by: Sean Young --- include/linux/bpf-cgroup.h | 31 +++++++++++ kernel/bpf/cgroup.c | 110 +++++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 105 ++--------------------------------- 3 files changed, 145 insertions(+), 101 deletions(-) diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h index 975fb4cf1bb7..ee67cd35f426 100644 --- a/include/linux/bpf-cgroup.h +++ b/include/linux/bpf-cgroup.h @@ -188,12 +188,43 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, \ __ret; \ }) +int sockmap_get_from_fd(const union bpf_attr *attr, int type, bool attach); +int cgroup_bpf_prog_attach(const union bpf_attr *attr, + enum bpf_prog_type ptype); +int cgroup_bpf_prog_detach(const union bpf_attr *attr, + enum bpf_prog_type ptype); +int cgroup_bpf_prog_query(const union bpf_attr *attr, + union bpf_attr __user *uattr); #else struct cgroup_bpf {}; static inline void cgroup_bpf_put(struct cgroup *cgrp) {} static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; } +static inline int sockmap_get_from_fd(const union bpf_attr *attr, + int type, bool attach) +{ + return -EINVAL; +} + +static inline int cgroup_bpf_prog_attach(const union bpf_attr *attr, + enum bpf_prog_type ptype) +{ + return -EINVAL; +} + +static inline int cgroup_bpf_prog_detach(const union bpf_attr *attr, + enum bpf_prog_type ptype) +{ + return -EINVAL; +} + +static inline int cgroup_bpf_prog_query(const union bpf_attr *attr, + union bpf_attr __user *uattr) +{ + return -EINVAL; +} + #define cgroup_bpf_enabled (0) #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0) #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; }) diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index f7c00bd6f8e4..d6e18f9dc0c4 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -428,6 +428,116 @@ int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, return ret; } +int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog, + enum bpf_attach_type attach_type) +{ + switch (prog->type) { + case BPF_PROG_TYPE_CGROUP_SOCK: + case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: + return attach_type == prog->expected_attach_type ? 0 : -EINVAL; + default: + return 0; + } +} + +int sockmap_get_from_fd(const union bpf_attr *attr, int type, bool attach) +{ + struct bpf_prog *prog = NULL; + int ufd = attr->target_fd; + struct bpf_map *map; + struct fd f; + int err; + + f = fdget(ufd); + map = __bpf_map_get(f); + if (IS_ERR(map)) + return PTR_ERR(map); + + if (attach) { + prog = bpf_prog_get_type(attr->attach_bpf_fd, type); + if (IS_ERR(prog)) { + fdput(f); + return PTR_ERR(prog); + } + } + + err = sock_map_prog(map, prog, attr->attach_type); + if (err) { + fdput(f); + if (prog) + bpf_prog_put(prog); + return err; + } + + fdput(f); + return 0; +} + +int cgroup_bpf_prog_attach(const union bpf_attr *attr, enum bpf_prog_type ptype) +{ + struct bpf_prog *prog; + struct cgroup *cgrp; + int ret; + + prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); + if (IS_ERR(prog)) + return PTR_ERR(prog); + + if (bpf_prog_attach_check_attach_type(prog, attr->attach_type)) { + bpf_prog_put(prog); + return -EINVAL; + } + + cgrp = cgroup_get_from_fd(attr->target_fd); + if (IS_ERR(cgrp)) { + bpf_prog_put(prog); + return PTR_ERR(cgrp); + } + + ret = cgroup_bpf_attach(cgrp, prog, attr->attach_type, + attr->attach_flags); + if (ret) + bpf_prog_put(prog); + cgroup_put(cgrp); + + return ret; +} + +int cgroup_bpf_prog_detach(const union bpf_attr *attr, enum bpf_prog_type ptype) +{ + struct bpf_prog *prog; + struct cgroup *cgrp; + int ret; + + cgrp = cgroup_get_from_fd(attr->target_fd); + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); + + prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); + if (IS_ERR(prog)) + prog = NULL; + + ret = cgroup_bpf_detach(cgrp, prog, attr->attach_type, 0); + if (prog) + bpf_prog_put(prog); + cgroup_put(cgrp); + return ret; +} + +int cgroup_bpf_prog_query(const union bpf_attr *attr, + union bpf_attr __user *uattr) +{ + struct cgroup *cgrp; + int ret; + + cgrp = cgroup_get_from_fd(attr->query.target_fd); + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); + ret = cgroup_bpf_query(cgrp, attr, uattr); + cgroup_put(cgrp); + return ret; +} + /** * __cgroup_bpf_run_filter_skb() - Run a program for packet filtering * @sk: The socket sending or receiving traffic diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 0fa20624707f..52fa44856623 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1489,65 +1489,14 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr) return err; } -#ifdef CONFIG_CGROUP_BPF - -static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog, - enum bpf_attach_type attach_type) -{ - switch (prog->type) { - case BPF_PROG_TYPE_CGROUP_SOCK: - case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: - return attach_type == prog->expected_attach_type ? 0 : -EINVAL; - default: - return 0; - } -} - #define BPF_PROG_ATTACH_LAST_FIELD attach_flags -static int sockmap_get_from_fd(const union bpf_attr *attr, - int type, bool attach) -{ - struct bpf_prog *prog = NULL; - int ufd = attr->target_fd; - struct bpf_map *map; - struct fd f; - int err; - - f = fdget(ufd); - map = __bpf_map_get(f); - if (IS_ERR(map)) - return PTR_ERR(map); - - if (attach) { - prog = bpf_prog_get_type(attr->attach_bpf_fd, type); - if (IS_ERR(prog)) { - fdput(f); - return PTR_ERR(prog); - } - } - - err = sock_map_prog(map, prog, attr->attach_type); - if (err) { - fdput(f); - if (prog) - bpf_prog_put(prog); - return err; - } - - fdput(f); - return 0; -} - #define BPF_F_ATTACH_MASK \ (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI) static int bpf_prog_attach(const union bpf_attr *attr) { enum bpf_prog_type ptype; - struct bpf_prog *prog; - struct cgroup *cgrp; - int ret; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -1593,28 +1542,7 @@ static int bpf_prog_attach(const union bpf_attr *attr) return -EINVAL; } - prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); - if (IS_ERR(prog)) - return PTR_ERR(prog); - - if (bpf_prog_attach_check_attach_type(prog, attr->attach_type)) { - bpf_prog_put(prog); - return -EINVAL; - } - - cgrp = cgroup_get_from_fd(attr->target_fd); - if (IS_ERR(cgrp)) { - bpf_prog_put(prog); - return PTR_ERR(cgrp); - } - - ret = cgroup_bpf_attach(cgrp, prog, attr->attach_type, - attr->attach_flags); - if (ret) - bpf_prog_put(prog); - cgroup_put(cgrp); - - return ret; + return cgroup_bpf_prog_attach(attr, ptype); } #define BPF_PROG_DETACH_LAST_FIELD attach_type @@ -1622,9 +1550,6 @@ static int bpf_prog_attach(const union bpf_attr *attr) static int bpf_prog_detach(const union bpf_attr *attr) { enum bpf_prog_type ptype; - struct bpf_prog *prog; - struct cgroup *cgrp; - int ret; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -1667,19 +1592,7 @@ static int bpf_prog_detach(const union bpf_attr *attr) return -EINVAL; } - cgrp = cgroup_get_from_fd(attr->target_fd); - if (IS_ERR(cgrp)) - return PTR_ERR(cgrp); - - prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); - if (IS_ERR(prog)) - prog = NULL; - - ret = cgroup_bpf_detach(cgrp, prog, attr->attach_type, 0); - if (prog) - bpf_prog_put(prog); - cgroup_put(cgrp); - return ret; + return cgroup_bpf_prog_detach(attr, ptype); } #define BPF_PROG_QUERY_LAST_FIELD query.prog_cnt @@ -1687,9 +1600,6 @@ static int bpf_prog_detach(const union bpf_attr *attr) static int bpf_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr) { - struct cgroup *cgrp; - int ret; - if (!capable(CAP_NET_ADMIN)) return -EPERM; if (CHECK_ATTR(BPF_PROG_QUERY)) @@ -1717,14 +1627,9 @@ static int bpf_prog_query(const union bpf_attr *attr, default: return -EINVAL; } - cgrp = cgroup_get_from_fd(attr->query.target_fd); - if (IS_ERR(cgrp)) - return PTR_ERR(cgrp); - ret = cgroup_bpf_query(cgrp, attr, uattr); - cgroup_put(cgrp); - return ret; + + return cgroup_bpf_prog_query(attr, uattr); } -#endif /* CONFIG_CGROUP_BPF */ #define BPF_PROG_TEST_RUN_LAST_FIELD test.duration @@ -2371,7 +2276,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz case BPF_OBJ_GET: err = bpf_obj_get(&attr); break; -#ifdef CONFIG_CGROUP_BPF case BPF_PROG_ATTACH: err = bpf_prog_attach(&attr); break; @@ -2381,7 +2285,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz case BPF_PROG_QUERY: err = bpf_prog_query(&attr, uattr); break; -#endif case BPF_PROG_TEST_RUN: err = bpf_prog_test_run(&attr, uattr); break; -- 2.17.1