Re: [PATCH v2 net-next 3/5] bpf, cgroup: implement eBPF-based device controller for cgroup v2

2017-11-02 Thread Roman Gushchin
On Thu, Nov 02, 2017 at 08:11:07AM -0700, Alexei Starovoitov wrote:
> On 11/2/17 7:54 AM, Roman Gushchin wrote:
> > +#define DEV_BPF_ACC_MKNOD  (1ULL << 0)
> > +#define DEV_BPF_ACC_READ   (1ULL << 1)
> > +#define DEV_BPF_ACC_WRITE  (1ULL << 2)
> > +
> > +#define DEV_BPF_DEV_BLOCK  (1ULL << 0)
> > +#define DEV_BPF_DEV_CHAR   (1ULL << 1)
> > +
> 
> all macros in bpf.h start with BPF_
> To be consistent with the rest can you rename above to BPF_DEVCG_.. ?

Sure. Will post v3.


Re: [PATCH v2 net-next 3/5] bpf, cgroup: implement eBPF-based device controller for cgroup v2

2017-11-02 Thread Alexei Starovoitov

On 11/2/17 7:54 AM, Roman Gushchin wrote:

+#define DEV_BPF_ACC_MKNOD  (1ULL << 0)
+#define DEV_BPF_ACC_READ   (1ULL << 1)
+#define DEV_BPF_ACC_WRITE  (1ULL << 2)
+
+#define DEV_BPF_DEV_BLOCK  (1ULL << 0)
+#define DEV_BPF_DEV_CHAR   (1ULL << 1)
+


all macros in bpf.h start with BPF_
To be consistent with the rest can you rename above to BPF_DEVCG_.. ?


[PATCH v2 net-next 3/5] bpf, cgroup: implement eBPF-based device controller for cgroup v2

2017-11-02 Thread Roman Gushchin
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..4deb3c9acbb2 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,