Re: [PATCHv4 net-next 05/15] bpf: expose internal verfier structures

2016-09-15 Thread Alexei Starovoitov
On Thu, Sep 15, 2016 at 08:12:25PM +0100, Jakub Kicinski wrote:
> Move verifier's internal structures to a header file and
> prefix their names with bpf_ to avoid potential namespace
> conflicts.  Those structures will soon be used by external
> analyzers.
> 
> Signed-off-by: Jakub Kicinski 
> ---
> v4:
>  - separate from adding the analyzer;
>  - squash with the prefixing patch.
> ---
>  include/linux/bpf_verifier.h |  78 +
>  kernel/bpf/verifier.c| 263 
> +--
>  2 files changed, 180 insertions(+), 161 deletions(-)
>  create mode 100644 include/linux/bpf_verifier.h
> 
> diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
> new file mode 100644
> index ..1c0511ef7eaf
> --- /dev/null
> +++ b/include/linux/bpf_verifier.h
...
> +#ifndef _LINUX_BPF_ANALYZER_H
> +#define _LINUX_BPF_ANALYZER_H 1

the macro doesn't match the file name.
Other than that
Acked-by: Alexei Starovoitov 



[PATCHv4 net-next 05/15] bpf: expose internal verfier structures

2016-09-15 Thread Jakub Kicinski
Move verifier's internal structures to a header file and
prefix their names with bpf_ to avoid potential namespace
conflicts.  Those structures will soon be used by external
analyzers.

Signed-off-by: Jakub Kicinski 
---
v4:
 - separate from adding the analyzer;
 - squash with the prefixing patch.
---
 include/linux/bpf_verifier.h |  78 +
 kernel/bpf/verifier.c| 263 +--
 2 files changed, 180 insertions(+), 161 deletions(-)
 create mode 100644 include/linux/bpf_verifier.h

diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
new file mode 100644
index ..1c0511ef7eaf
--- /dev/null
+++ b/include/linux/bpf_verifier.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#ifndef _LINUX_BPF_ANALYZER_H
+#define _LINUX_BPF_ANALYZER_H 1
+
+#include  /* for enum bpf_reg_type */
+#include  /* for MAX_BPF_STACK */
+
+struct bpf_reg_state {
+   enum bpf_reg_type type;
+   union {
+   /* valid when type == CONST_IMM | PTR_TO_STACK | UNKNOWN_VALUE 
*/
+   s64 imm;
+
+   /* valid when type == PTR_TO_PACKET* */
+   struct {
+   u32 id;
+   u16 off;
+   u16 range;
+   };
+
+   /* valid when type == CONST_PTR_TO_MAP | PTR_TO_MAP_VALUE |
+*   PTR_TO_MAP_VALUE_OR_NULL
+*/
+   struct bpf_map *map_ptr;
+   };
+};
+
+enum bpf_stack_slot_type {
+   STACK_INVALID,/* nothing was stored in this stack slot */
+   STACK_SPILL,  /* register spilled into stack */
+   STACK_MISC/* BPF program wrote some data into this slot */
+};
+
+#define BPF_REG_SIZE 8 /* size of eBPF register in bytes */
+
+/* state of the program:
+ * type of all registers and stack info
+ */
+struct bpf_verifier_state {
+   struct bpf_reg_state regs[MAX_BPF_REG];
+   u8 stack_slot_type[MAX_BPF_STACK];
+   struct bpf_reg_state spilled_regs[MAX_BPF_STACK / BPF_REG_SIZE];
+};
+
+/* linked list of verifier states used to prune search */
+struct bpf_verifier_state_list {
+   struct bpf_verifier_state state;
+   struct bpf_verifier_state_list *next;
+};
+
+struct bpf_insn_aux_data {
+   enum bpf_reg_type ptr_type; /* pointer type for load/store insns */
+};
+
+#define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */
+
+/* single container for all structs
+ * one verifier_env per bpf_check() call
+ */
+struct bpf_verifier_env {
+   struct bpf_prog *prog;  /* eBPF program being verified */
+   struct bpf_verifier_stack_elem *head; /* stack of verifier states to be 
processed */
+   int stack_size; /* number of states to be processed */
+   struct bpf_verifier_state cur_state; /* current verifier state */
+   struct bpf_verifier_state_list **explored_states; /* search pruning 
optimization */
+   struct bpf_map *used_maps[MAX_USED_MAPS]; /* array of map's used by 
eBPF program */
+   u32 used_map_cnt;   /* number of used maps */
+   u32 id_gen; /* used to generate unique reg IDs */
+   bool allow_ptr_leaks;
+   struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */
+};
+
+#endif /* _LINUX_BPF_ANALYZER_H */
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index ce9c0d1721c6..6e126a417290 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -126,81 +127,16 @@
  * are set to NOT_INIT to indicate that they are no longer readable.
  */
 
-struct reg_state {
-   enum bpf_reg_type type;
-   union {
-   /* valid when type == CONST_IMM | PTR_TO_STACK | UNKNOWN_VALUE 
*/
-   s64 imm;
-
-   /* valid when type == PTR_TO_PACKET* */
-   struct {
-   u32 id;
-   u16 off;
-   u16 range;
-   };
-
-   /* valid when type == CONST_PTR_TO_MAP | PTR_TO_MAP_VALUE |
-*   PTR_TO_MAP_VALUE_OR_NULL
-*/
-   struct bpf_map *map_ptr;
-   };
-};
-
-enum bpf_stack_slot_type {
-   STACK_INVALID,/* nothing was stored in this stack slot */
-   STACK_SPILL,  /* register spilled into stack */
-   STACK_MISC/* BPF program wrote some data into this slot */
-};
-
-#define BPF_REG_SIZE 8 /* size of eBPF register in bytes */
-
-/* state of the program:
- * type of all registers and stack info
- */
-struct verifier_state {
-   struct reg_state regs[MAX_BPF_REG];
-   u8