From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755931AbdKBRSQ (ORCPT ); Thu, 2 Nov 2017 13:18:16 -0400 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:44722 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754906AbdKBRQj (ORCPT ); Thu, 2 Nov 2017 13:16:39 -0400 From: Roman Gushchin To: CC: Tejun Heo , Alexei Starovoitov , Daniel Borkmann , , , Roman Gushchin Subject: [PATCH v3 net-next 3/5] bpf, cgroup: implement eBPF-based device controller for cgroup v2 Date: Thu, 2 Nov 2017 13:15:28 -0400 Message-ID: <20171102171530.7627-4-guro@fb.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171102171530.7627-1-guro@fb.com> References: <20171102171530.7627-1-guro@fb.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [2620:10d:c091:200::2:53d6] X-ClientProxiedBy: CO2PR04CA0112.namprd04.prod.outlook.com (2603:10b6:104:7::14) To BL2PR15MB1073.namprd15.prod.outlook.com (2603:10b6:201:17::7) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9f650c12-3fd8-4b9c-2a3e-08d522156f32 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(2017052603199);SRVR:BL2PR15MB1073; X-Microsoft-Exchange-Diagnostics: 1;BL2PR15MB1073;3:zxxdGoMR6mVWk3qPNqxvHJ+X6Xpwbfvh9QVkJcXHNP8B5V12TeDGKHymc0GzHFp0QhCg44+DxKJnNcVXdLGagfjDOYe3WTNh4qfS6g8Gz6mhwgKrebmKqOrBjTRlexkn165bgD6X3gXjvfkPXrDOv2JhVDKJ5hFjboIL1SJPahDzrfkIuczKPtpORiO/qCAokTOiTQp+EFtuVb7otLSl280RwjOyhkSFavUkccOdXpHqMwpAp7d8xLNisyWjuRvx;25:S10mMBQutF3Ma1ykJSuyoqwkvuxxgqT7U1t2Cwahar72W9WpFhn5WDt1gzAoEodHAR3xNrzl0hmv1mIlloBGBElZ2DG45Uuld+2SxZllg7n6KrLiivRH8QMAViDo2BgBsB+YPxa8LcQSGvI2fEYe8jUlL7I2uQU6J5s7CzDTh55sqkbMnBDaiJCgO+Hf+9T/s7LdxcMFK5kfyZxrAC+lD8sE5LQwThWhqRPldZuPtuGuwWDw4h50lxAORocCuNZ9qg9SfURwQi3LjAwNphYoGGzrrm3Mm2Jso2GXAijPILhW+7n3ntKPLquOZ/Z+N7DUrBLAnHIXnIyOkxppDfNKfA==;31:Tws6umaZdVOLnag5svkU1yPIw5Ic7KGSRSssjkkU1wrCNVi+1FEqrDzNxVI5/BvLMLBg1ZdWUME+AA6mYT4kcYHU0oEYd1ZkPc91p3j4xP9bb+/QoBXKFp1DzCGFnHLN0lL00sReF4Zwa9YVp86Lcqx5IGICMiI2wduRJqQRN9ele0WRpriSqfw5WWV4aXoyBX6PVqMJAeJ0q106AWe7LbxM1jRVsbFi2Tkn5WUANg0= X-MS-TrafficTypeDiagnostic: BL2PR15MB1073: X-Microsoft-Exchange-Diagnostics: 1;BL2PR15MB1073;20:CKVSe7DX7jQ45SwFJibITVbKTHbzNIGk0atBDyxhNY5gYbVC7jGXrf3lnXL8nQymz2xhe94+So949N9GoGC3cV/SDwR0bWJaiIDcwP/VSI4+IepxD5SPVAz4tEa44fT3/l57P8k42mU/z9+xuzzAFTeF5kF5kYRpUS2DQ+ihN+9UGKnsOlYOMOfFr6O7pVvTbtpHbXFdROXiQrckyW2eo1k/fGhu6ZXtx2T7Emd5s4TzcvRWKtMKb2W/qRh3JyG2Hevsg1Mwpp2c8WAdCFCMglaK5xzLbnIMqTX3FEg8KHtu+yYL8OtMhoYnht/Iw+mXvzyZP3zQrodBfNXlsQcQ3IUnMjU2nJKS48nb+CpP3AsKogxCQI/WU/pTZCbx0X9o/eeLM2j4R0Cm8pi8yXG4gezcncwVlF0dT+NUWT1x2HHuLt4gGZYObeVGqKwE2NKwTpD+I8bwBr+BrHe9Xtv/6NzLYZwqJQWyrJVTKWef9OdjtGQlCTHv0V2I9SqX/Zo4;4:Ox2YpCocoq56FREGgvSNPTivpCQWJt48vgVp7CkmDewcPEqcZUaqJIJu5XjqBHCl2m/c93PaxSbya50hgIeowU0IhRYMa+gtCYuMuRzXzerpJzDtsiYr3yB4X8Kh3z5RonefijfuDLr1lVOI9vwJ7+WdpZjK2u+4XNBUeSZatW6twBY+7teIiDcJxCbc9wC0/bNxF1aoKeD7OmT4XVgPfdsi9laRh2Eaoj4fParI+uY6+wZEXUyrIvO6VegUeG1euD8t3OuiqNWcML8UxXug+HTPHQAzVq5+79tPJx6M0fRW2K0TaJmTPgTS+bJP2dzv X-Exchange-Antispam-Report-Test: UriScan:(67672495146484); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(11241501159)(6040450)(2401047)(8121501046)(5005006)(100000703101)(100105400095)(93006095)(93001095)(10201501046)(3231020)(3002001)(6041248)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123560025)(20161123555025)(20161123562025)(20161123564025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:BL2PR15MB1073;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:BL2PR15MB1073; X-Forefront-PRVS: 047999FF16 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(6009001)(376002)(346002)(199003)(189002)(50986999)(76176999)(478600001)(53416004)(33646002)(54906003)(5003940100001)(2351001)(105586002)(4326008)(2361001)(2906002)(16586007)(316002)(106356001)(305945005)(5890100001)(7736002)(25786009)(101416001)(50226002)(1076002)(8676002)(189998001)(36756003)(81166006)(81156014)(47776003)(69596002)(97736004)(6666003)(6116002)(6916009)(2950100002)(5660300001)(6512007)(6506006)(68736007)(53936002)(48376002)(50466002)(6486002)(8936002)(86362001)(42262002);DIR:OUT;SFP:1102;SCL:1;SRVR:BL2PR15MB1073;H:castle.thefacebook.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BL2PR15MB1073;23:8XRzVie47mTT7ARvTWXsWiU2f19kG6u1S1n5vDiHL?= =?us-ascii?Q?Ts6fMYeiRhGaQGtPlxQoCSMs45GVKm0MgQ8OUelOoDzQe+l/OOFA4KO0kK7I?= =?us-ascii?Q?AsFlOnXjku+JZL7oT71fkdinSvZ0pGgIN6vUz5cjC80NMjrwqW0yTE2TgW/g?= =?us-ascii?Q?VUuuE5QZRivz6rsZ5siGk/68yk1HeeU63GoAnUdfLL+98MeRmbgLbjj7c1x6?= =?us-ascii?Q?XGzfqVPhtpnqUxF0ZBlsZwJS73/hgQfMdfNNxtd9qAvGY+iVIwFpd2A5BYMr?= =?us-ascii?Q?F38FCOeCVn9trqrCYVZO6sJtLzcdeE9j8B0ISQZRX0irPNUFdGLjcMbC7CpE?= =?us-ascii?Q?RTJIqkblNB6UvwDvAcO6pT2QampAkx81RzWzYpxKTOrkjv9vb5W5ExIIg1/1?= =?us-ascii?Q?Wl29TVsTxzX+1eQPgd8VSMLj5H1kggZJ95u1F6bvmECHoTLKouigMWVWTmc/?= =?us-ascii?Q?Lnx3fPs28t/1cvlmm2STzmXtf5HDOdFNndwqjuYQ0Y5btbCwi+lKKNBOlYKA?= =?us-ascii?Q?6D9P0NlkjotaqFOy7RmZ66Pd8hfPO7RPJE+WkAj8UktJHzumHvAjGMZrW3GD?= =?us-ascii?Q?hzFwp0Ru7Pz9EO8rPNEI53lTMD7+SAkR9VjIJG1+NpGKRMiJk6UoxwDS245u?= =?us-ascii?Q?YL9NG3AjIDbaFj7Cdosv1oTp1jzz2yUYq6F0pzCRyjG94M7Sd25J4MfFR/FK?= =?us-ascii?Q?NDnIQp7u+295kGiHtx6zrKqU6hvXFdFqGEklSR45EOg7zeXQ9UvRLpxiTvr9?= =?us-ascii?Q?9mQIIM5F3S+AD9q3TsEdtykEoYw6Lf3S8RjJR++1MkcT0i1F33xAR0kNObZu?= =?us-ascii?Q?AzHYQiDsFyd7tbBa2xFYDXd0nL3wzMWqSGaSnG6bVDCdLKqJlj8XHT+NQ0uw?= =?us-ascii?Q?OfpYIFnmnt++xC6FyLClrrZA5yz0Sf17buk0QbwW9p2CMilRIU/TfTpnMdEM?= =?us-ascii?Q?KZpSFwC3cThxmutBZsC2nZTbve8VtphC4xDaoQa13J8hlfj28HeMnyr7SBvs?= =?us-ascii?Q?UONLEedV7WZ7r+YChdXR4kAtbX7N+yi4qpaa4tTlIkjMbUTP+syxsAs976O9?= =?us-ascii?Q?zWI0FQwRovlYCACYZJhzsJyYSvrBSsylMdKuZ9goY3weqULbw2qk0f4qvNFF?= =?us-ascii?Q?b2y3xvl97ZQf1IKxujEN3SY0PMnOvFNgKWnXgDlHU4llVPAAnOiDg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;BL2PR15MB1073;6:9mt1/cf7g3Femt811pkfotwB8foLiYfq31pkevL4fKho4hBR2ij8g8pZvWtW0VOLzVEM0hjdXMIs7ffLY3X3tJNx8YJUZirGv+KqtBlcbWaScyT/OOUwsz4jJm5NKelYIIhgIWE1AmkxI+9EPuNVnaNsw4oquksdzwXKeOZerb5+4cn59x4gX5SghnPirnVctjiGD2qVFjxV/QmfsXwhPUgNO06nr2zWapw0FgdieyuKQeByZT71iey1nB3sAXGRy+mts/4xyuW1WpL9e0jTPLvI+GCq3TkuIOffMWXUE4S8ZnwqCaDqTt5RNMjI7OkfNRaXCJOtA+ame6sqJA4oUKbif11zEaD45e6EROcUEFs=;5:BcSQ7EzxPY5eu12SGp2RTwImAEQRb4ZVjsUI0V7tCnsn1pBZBDh5cty7WRMtdhg4bGqssgBFqdqWUBvAokiYOepj4fRNZbWxZhkPnBMYHkvIxeGfmGYr6fj22VJpCmRy8XUOlQ4T3Tdize5K81UJVPvfkLAEhIdygR6CWUlyt0A=;24:C7yuHKLNknaJXU4vZ7TWelp7BJODoZJicfaVVEUdpHalPOS7Fn+2xSyRNyqtALfD/rPxbFjlGLEBlW57CXOvrIN9luknGarItnKBlePZ4HA=;7:7w0SJhnvatRTSExkmtA8oC9dur+4OSxVoyj3NcUgcfe2guuXQssO9COiCHRHvDClGmKwOzThEFHl6euQhgcRZbFLXUayidXc1z5pCg16o+XSNMUY1+qxfIA+ZDzF0BJDtcob7Q3wmJWwLDlNj0VqnjW+CEzI0G7V6X9h9UujFh2nwugc+HN7DC8cWlvtyYmJzogsm0jsmLadoX2n4toVda5zMizYevFOL7DXddQE1R4nGM/SZ40RK4BYXvfJdKmo SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;BL2PR15MB1073;20:XgfuxqK5tRQhLT5xT2RBF5jpYiVggD6gbqrDFxCI2nS/43wTsl0aXd1iy3ZpDOo9ojkx2bFM/GzqpfxR1h4/eTXWouHgGYJdkBBszGtAEPYSiO+Zsa0eNVib1uLbnAfU/AAx6zgtWt1WwN7pRAmYpczPpICtE4ewsy6oQatF+Tk= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Nov 2017 17:16:18.2227 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9f650c12-3fd8-4b9c-2a3e-08d522156f32 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL2PR15MB1073 X-OriginatorOrg: fb.com X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-11-02_06:,, signatures=0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Cgroup v2 lacks the device controller, provided by cgroup v1. This patch adds a new eBPF program type, which in combination of previously added ability to attach multiple eBPF programs to a cgroup, will provide a similar functionality, but with some additional flexibility. This patch introduces a BPF_PROG_TYPE_CGROUP_DEVICE program type. A program takes major and minor device numbers, device type (block/character) and access type (mknod/read/write) as parameters and returns an integer which defines if the operation should be allowed or terminated with -EPERM. Signed-off-by: Roman Gushchin Acked-by: Alexei Starovoitov Acked-by: Tejun Heo Cc: Daniel Borkmann --- include/linux/bpf-cgroup.h | 15 ++++++++++ include/linux/bpf_types.h | 3 ++ include/linux/device_cgroup.h | 8 ++++- include/uapi/linux/bpf.h | 15 ++++++++++ kernel/bpf/cgroup.c | 67 ++++++++++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 7 +++++ kernel/bpf/verifier.c | 1 + tools/include/uapi/linux/bpf.h | 15 ++++++++++ 8 files changed, 130 insertions(+), 1 deletion(-) diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h index 359b6f5d3d90..d77cefb3fe99 100644 --- a/include/linux/bpf-cgroup.h +++ b/include/linux/bpf-cgroup.h @@ -66,6 +66,9 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk, struct bpf_sock_ops_kern *sock_ops, enum bpf_attach_type type); +int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, + short access, enum bpf_attach_type type); + /* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */ #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb) \ ({ \ @@ -111,6 +114,17 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk, } \ __ret; \ }) + +#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access) \ +({ \ + int __ret = 0; \ + if (cgroup_bpf_enabled) \ + __ret = __cgroup_bpf_check_dev_permission(type, major, minor, \ + access, \ + BPF_CGROUP_DEVICE); \ + \ + __ret; \ +}) #else struct cgroup_bpf {}; @@ -121,6 +135,7 @@ static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; } #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk,skb) ({ 0; }) #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) ({ 0; }) #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; }) +#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; }) #endif /* CONFIG_CGROUP_BPF */ diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h index 36418ad43245..963a97ee4b7c 100644 --- a/include/linux/bpf_types.h +++ b/include/linux/bpf_types.h @@ -18,6 +18,9 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_KPROBE, kprobe) BPF_PROG_TYPE(BPF_PROG_TYPE_TRACEPOINT, tracepoint) BPF_PROG_TYPE(BPF_PROG_TYPE_PERF_EVENT, perf_event) #endif +#ifdef CONFIG_CGROUP_BPF +BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_DEVICE, cg_dev) +#endif BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops) diff --git a/include/linux/device_cgroup.h b/include/linux/device_cgroup.h index 1e42d33accbf..90245a70d940 100644 --- a/include/linux/device_cgroup.h +++ b/include/linux/device_cgroup.h @@ -1,4 +1,5 @@ #include +#include #define DEVCG_ACC_MKNOD 1 #define DEVCG_ACC_READ 2 @@ -18,10 +19,15 @@ static inline int __devcgroup_check_permission(short type, u32 major, u32 minor, { return 0; } #endif -#ifdef CONFIG_CGROUP_DEVICE +#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF) static inline int devcgroup_check_permission(short type, u32 major, u32 minor, short access) { + int rc = BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access); + + if (rc) + return -EPERM; + return __devcgroup_check_permission(type, major, minor, access); } diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 0b7b54d898bd..ea905863a033 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -131,6 +131,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_LWT_XMIT, BPF_PROG_TYPE_SOCK_OPS, BPF_PROG_TYPE_SK_SKB, + BPF_PROG_TYPE_CGROUP_DEVICE, }; enum bpf_attach_type { @@ -140,6 +141,7 @@ enum bpf_attach_type { BPF_CGROUP_SOCK_OPS, BPF_SK_SKB_STREAM_PARSER, BPF_SK_SKB_STREAM_VERDICT, + BPF_CGROUP_DEVICE, __MAX_BPF_ATTACH_TYPE }; @@ -984,4 +986,17 @@ struct bpf_perf_event_value { __u64 running; }; +#define BPF_DEVCG_ACC_MKNOD (1ULL << 0) +#define BPF_DEVCG_ACC_READ (1ULL << 1) +#define BPF_DEVCG_ACC_WRITE (1ULL << 2) + +#define BPF_DEVCG_DEV_BLOCK (1ULL << 0) +#define BPF_DEVCG_DEV_CHAR (1ULL << 1) + +struct bpf_cgroup_dev_ctx { + __u32 access_type; /* (access << 16) | type */ + __u32 major; + __u32 minor; +}; + #endif /* _UAPI__LINUX_BPF_H__ */ diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 3db5a17fcfe8..b789ab78d28f 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -522,3 +522,70 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk, return ret == 1 ? 0 : -EPERM; } EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_ops); + +int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, + short access, enum bpf_attach_type type) +{ + struct cgroup *cgrp; + struct bpf_cgroup_dev_ctx ctx = { + .access_type = (access << 16) | dev_type, + .major = major, + .minor = minor, + }; + int allow = 1; + + rcu_read_lock(); + cgrp = task_dfl_cgroup(current); + allow = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], &ctx, + BPF_PROG_RUN); + rcu_read_unlock(); + + return !allow; +} +EXPORT_SYMBOL(__cgroup_bpf_check_dev_permission); + +static const struct bpf_func_proto * +cgroup_dev_func_proto(enum bpf_func_id func_id) +{ + switch (func_id) { + case BPF_FUNC_map_lookup_elem: + return &bpf_map_lookup_elem_proto; + case BPF_FUNC_map_update_elem: + return &bpf_map_update_elem_proto; + case BPF_FUNC_map_delete_elem: + return &bpf_map_delete_elem_proto; + case BPF_FUNC_get_current_uid_gid: + return &bpf_get_current_uid_gid_proto; + case BPF_FUNC_trace_printk: + if (capable(CAP_SYS_ADMIN)) + return bpf_get_trace_printk_proto(); + default: + return NULL; + } +} + +static bool cgroup_dev_is_valid_access(int off, int size, + enum bpf_access_type type, + struct bpf_insn_access_aux *info) +{ + if (type == BPF_WRITE) + return false; + + if (off < 0 || off + size > sizeof(struct bpf_cgroup_dev_ctx)) + return false; + /* The verifier guarantees that size > 0. */ + if (off % size != 0) + return false; + if (size != sizeof(__u32)) + return false; + + return true; +} + +const struct bpf_prog_ops cg_dev_prog_ops = { +}; + +const struct bpf_verifier_ops cg_dev_verifier_ops = { + .get_func_proto = cgroup_dev_func_proto, + .is_valid_access = cgroup_dev_is_valid_access, +}; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 323be2473c4b..08f7b450828e 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1291,6 +1291,9 @@ static int bpf_prog_attach(const union bpf_attr *attr) case BPF_CGROUP_SOCK_OPS: ptype = BPF_PROG_TYPE_SOCK_OPS; break; + case BPF_CGROUP_DEVICE: + ptype = BPF_PROG_TYPE_CGROUP_DEVICE; + break; case BPF_SK_SKB_STREAM_PARSER: case BPF_SK_SKB_STREAM_VERDICT: return sockmap_get_from_fd(attr, true); @@ -1343,6 +1346,9 @@ static int bpf_prog_detach(const union bpf_attr *attr) case BPF_CGROUP_SOCK_OPS: ptype = BPF_PROG_TYPE_SOCK_OPS; break; + case BPF_CGROUP_DEVICE: + ptype = BPF_PROG_TYPE_CGROUP_DEVICE; + break; case BPF_SK_SKB_STREAM_PARSER: case BPF_SK_SKB_STREAM_VERDICT: return sockmap_get_from_fd(attr, false); @@ -1385,6 +1391,7 @@ static int bpf_prog_query(const union bpf_attr *attr, case BPF_CGROUP_INET_EGRESS: case BPF_CGROUP_INET_SOCK_CREATE: case BPF_CGROUP_SOCK_OPS: + case BPF_CGROUP_DEVICE: break; default: return -EINVAL; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 2bb6d6aa7085..811f0582a1cc 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -3100,6 +3100,7 @@ static int check_return_code(struct bpf_verifier_env *env) case BPF_PROG_TYPE_CGROUP_SKB: case BPF_PROG_TYPE_CGROUP_SOCK: case BPF_PROG_TYPE_SOCK_OPS: + case BPF_PROG_TYPE_CGROUP_DEVICE: break; default: return 0; diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4a4b6e78c977..83763a3eb339 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -131,6 +131,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_LWT_XMIT, BPF_PROG_TYPE_SOCK_OPS, BPF_PROG_TYPE_SK_SKB, + BPF_PROG_TYPE_CGROUP_DEVICE, }; enum bpf_attach_type { @@ -140,6 +141,7 @@ enum bpf_attach_type { BPF_CGROUP_SOCK_OPS, BPF_SK_SKB_STREAM_PARSER, BPF_SK_SKB_STREAM_VERDICT, + BPF_CGROUP_DEVICE, __MAX_BPF_ATTACH_TYPE }; @@ -984,4 +986,17 @@ struct bpf_perf_event_value { __u64 running; }; +#define BPF_DEVCG_ACC_MKNOD (1ULL << 0) +#define BPF_DEVCG_ACC_READ (1ULL << 1) +#define BPF_DEVCG_ACC_WRITE (1ULL << 2) + +#define BPF_DEVCG_DEV_BLOCK (1ULL << 0) +#define BPF_DEVCG_DEV_CHAR (1ULL << 1) + +struct bpf_cgroup_dev_ctx { + __u32 access_type; /* (access << 16) | type */ + __u32 major; + __u32 minor; +}; + #endif /* _UAPI__LINUX_BPF_H__ */ -- 2.13.6