[RFC v3 05/22] bpf,landlock: Add eBPF program subtype and is_valid_subtype() verifier

2016-09-14 Thread Mickaël Salaün
The program subtype goal is to be able to have different static
fine-grained verifications for a unique program type.

The struct bpf_verifier_ops gets a new optional function:
is_valid_subtype(). This new verifier is called at the begening of the
eBPF program verification to check if the (optional) program subtype is
valid.

For now, only Landlock eBPF programs are using a program subtype but
this could be used by other program types in the future.

Cf. the next commit to see how the subtype is used by Landlock LSM.

Signed-off-by: Mickaël Salaün 
Link: https://lkml.kernel.org/r/20160827205559.ga43...@ast-mbp.thefacebook.com
Cc: Alexei Starovoitov 
Cc: Daniel Borkmann 
Cc: David S. Miller 
---
 include/linux/bpf.h  |  8 ++--
 include/linux/filter.h   |  1 +
 include/uapi/linux/bpf.h |  9 +
 kernel/bpf/syscall.c |  5 +++--
 kernel/bpf/verifier.c|  9 +++--
 kernel/trace/bpf_trace.c | 12 
 net/core/filter.c| 21 +
 7 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index eae4ce4542c1..9aa01d9d3d80 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -149,17 +149,21 @@ struct bpf_prog;
 
 struct bpf_verifier_ops {
/* return eBPF function prototype for verification */
-   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id 
func_id);
+   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id,
+   union bpf_prog_subtype *prog_subtype);
 
/* return true if 'size' wide access at offset 'off' within bpf_context
 * with 'type' (read or write) is allowed
 */
bool (*is_valid_access)(int off, int size, enum bpf_access_type type,
-   enum bpf_reg_type *reg_type);
+   enum bpf_reg_type *reg_type,
+   union bpf_prog_subtype *prog_subtype);
 
u32 (*convert_ctx_access)(enum bpf_access_type type, int dst_reg,
  int src_reg, int ctx_off,
  struct bpf_insn *insn, struct bpf_prog *prog);
+
+   bool (*is_valid_subtype)(union bpf_prog_subtype *prog_subtype);
 };
 
 struct bpf_prog_type_list {
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 1f09c521adfe..88470cdd3ee1 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -406,6 +406,7 @@ struct bpf_prog {
kmemcheck_bitfield_end(meta);
u32 len;/* Number of filter blocks */
enum bpf_prog_type  type;   /* Type of BPF program */
+   union bpf_prog_subtype  subtype;/* For fine-grained 
verifications */
struct bpf_prog_aux *aux;   /* Auxiliary fields */
struct sock_fprog_kern  *orig_prog; /* Original BPF program */
unsigned int(*bpf_func)(const struct sk_buff *skb,
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index b68de57f7ab8..667b6ef3ff1e 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -127,6 +127,14 @@ enum bpf_attach_type {
 
 #define BPF_F_NO_PREALLOC  (1U << 0)
 
+union bpf_prog_subtype {
+   struct {
+   __u32   id; /* enum landlock_hook_id */
+   __u16   origin; /* LANDLOCK_FLAG_ORIGIN_* */
+   __aligned_u64   access; /* LANDLOCK_FLAG_ACCESS_* */
+   } landlock_hook;
+} __attribute__((aligned(8)));
+
 union bpf_attr {
struct { /* anonymous struct used by BPF_MAP_CREATE command */
__u32   map_type;   /* one of enum bpf_map_type */
@@ -155,6 +163,7 @@ union bpf_attr {
__u32   log_size;   /* size of user buffer */
__aligned_u64   log_buf;/* user supplied buffer */
__u32   kern_version;   /* checked when 
prog_type=kprobe */
+   union bpf_prog_subtype prog_subtype;/* checked when 
prog_type=landlock */
};
 
struct { /* anonymous struct used by BPF_OBJ_* commands */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 776c752604b0..8b3f4d2b4802 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -572,7 +572,7 @@ static void fixup_bpf_calls(struct bpf_prog *prog)
continue;
}
 
-   fn = prog->aux->ops->get_func_proto(insn->imm);
+   fn = prog->aux->ops->get_func_proto(insn->imm, 
&prog->subtype);
/* all functions that have prototype and verifier 
allowed
 * programs to call them, must be real in-kernel 
functions
 */
@@ -710,7 +710,7 @@ struct bpf_prog *bpf_prog_get_type(u32 ufd, enum 
bpf_prog_type type)
 EXPORT_SYMBOL_GPL(bpf_prog_get_type);
 
 /* last field in 'union bpf_attr' used by this command */
-#define

Re: [RFC v3 05/22] bpf,landlock: Add eBPF program subtype and is_valid_subtype() verifier

2016-10-19 Thread Thomas Graf
On 09/14/16 at 09:23am, Mickaël Salaün wrote:
> @@ -155,6 +163,7 @@ union bpf_attr {
>   __u32   log_size;   /* size of user buffer */
>   __aligned_u64   log_buf;/* user supplied buffer */
>   __u32   kern_version;   /* checked when 
> prog_type=kprobe */
> + union bpf_prog_subtype prog_subtype;/* checked when 
> prog_type=landlock */

The comment seems bogus, this is not landlock specific.