diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/filter.h | 74 | ||||
| -rw-r--r-- | include/linux/seccomp.h | 1 |
2 files changed, 64 insertions, 11 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h index 9bde3ed19fe6..262dcbb75ffe 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h | |||
| @@ -9,13 +9,58 @@ | |||
| 9 | #include <linux/workqueue.h> | 9 | #include <linux/workqueue.h> |
| 10 | #include <uapi/linux/filter.h> | 10 | #include <uapi/linux/filter.h> |
| 11 | 11 | ||
| 12 | #ifdef CONFIG_COMPAT | 12 | /* Internally used and optimized filter representation with extended |
| 13 | /* | 13 | * instruction set based on top of classic BPF. |
| 14 | * A struct sock_filter is architecture independent. | ||
| 15 | */ | 14 | */ |
| 15 | |||
| 16 | /* instruction classes */ | ||
| 17 | #define BPF_ALU64 0x07 /* alu mode in double word width */ | ||
| 18 | |||
| 19 | /* ld/ldx fields */ | ||
| 20 | #define BPF_DW 0x18 /* double word */ | ||
| 21 | #define BPF_XADD 0xc0 /* exclusive add */ | ||
| 22 | |||
| 23 | /* alu/jmp fields */ | ||
| 24 | #define BPF_MOV 0xb0 /* mov reg to reg */ | ||
| 25 | #define BPF_ARSH 0xc0 /* sign extending arithmetic shift right */ | ||
| 26 | |||
| 27 | /* change endianness of a register */ | ||
| 28 | #define BPF_END 0xd0 /* flags for endianness conversion: */ | ||
| 29 | #define BPF_TO_LE 0x00 /* convert to little-endian */ | ||
| 30 | #define BPF_TO_BE 0x08 /* convert to big-endian */ | ||
| 31 | #define BPF_FROM_LE BPF_TO_LE | ||
| 32 | #define BPF_FROM_BE BPF_TO_BE | ||
| 33 | |||
| 34 | #define BPF_JNE 0x50 /* jump != */ | ||
| 35 | #define BPF_JSGT 0x60 /* SGT is signed '>', GT in x86 */ | ||
| 36 | #define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */ | ||
| 37 | #define BPF_CALL 0x80 /* function call */ | ||
| 38 | #define BPF_EXIT 0x90 /* function return */ | ||
| 39 | |||
| 40 | /* BPF has 10 general purpose 64-bit registers and stack frame. */ | ||
| 41 | #define MAX_BPF_REG 11 | ||
| 42 | |||
| 43 | /* BPF program can access up to 512 bytes of stack space. */ | ||
| 44 | #define MAX_BPF_STACK 512 | ||
| 45 | |||
| 46 | /* Arg1, context and stack frame pointer register positions. */ | ||
| 47 | #define ARG1_REG 1 | ||
| 48 | #define CTX_REG 6 | ||
| 49 | #define FP_REG 10 | ||
| 50 | |||
| 51 | struct sock_filter_int { | ||
| 52 | __u8 code; /* opcode */ | ||
| 53 | __u8 a_reg:4; /* dest register */ | ||
| 54 | __u8 x_reg:4; /* source register */ | ||
| 55 | __s16 off; /* signed offset */ | ||
| 56 | __s32 imm; /* signed immediate constant */ | ||
| 57 | }; | ||
| 58 | |||
| 59 | #ifdef CONFIG_COMPAT | ||
| 60 | /* A struct sock_filter is architecture independent. */ | ||
| 16 | struct compat_sock_fprog { | 61 | struct compat_sock_fprog { |
| 17 | u16 len; | 62 | u16 len; |
| 18 | compat_uptr_t filter; /* struct sock_filter * */ | 63 | compat_uptr_t filter; /* struct sock_filter * */ |
| 19 | }; | 64 | }; |
| 20 | #endif | 65 | #endif |
| 21 | 66 | ||
| @@ -26,6 +71,7 @@ struct sock_fprog_kern { | |||
| 26 | 71 | ||
| 27 | struct sk_buff; | 72 | struct sk_buff; |
| 28 | struct sock; | 73 | struct sock; |
| 74 | struct seccomp_data; | ||
| 29 | 75 | ||
| 30 | struct sk_filter { | 76 | struct sk_filter { |
| 31 | atomic_t refcnt; | 77 | atomic_t refcnt; |
| @@ -34,9 +80,10 @@ struct sk_filter { | |||
| 34 | struct sock_fprog_kern *orig_prog; /* Original BPF program */ | 80 | struct sock_fprog_kern *orig_prog; /* Original BPF program */ |
| 35 | struct rcu_head rcu; | 81 | struct rcu_head rcu; |
| 36 | unsigned int (*bpf_func)(const struct sk_buff *skb, | 82 | unsigned int (*bpf_func)(const struct sk_buff *skb, |
| 37 | const struct sock_filter *filter); | 83 | const struct sock_filter_int *filter); |
| 38 | union { | 84 | union { |
| 39 | struct sock_filter insns[0]; | 85 | struct sock_filter insns[0]; |
| 86 | struct sock_filter_int insnsi[0]; | ||
| 40 | struct work_struct work; | 87 | struct work_struct work; |
| 41 | }; | 88 | }; |
| 42 | }; | 89 | }; |
| @@ -50,9 +97,18 @@ static inline unsigned int sk_filter_size(unsigned int proglen) | |||
| 50 | #define sk_filter_proglen(fprog) \ | 97 | #define sk_filter_proglen(fprog) \ |
| 51 | (fprog->len * sizeof(fprog->filter[0])) | 98 | (fprog->len * sizeof(fprog->filter[0])) |
| 52 | 99 | ||
| 100 | #define SK_RUN_FILTER(filter, ctx) \ | ||
| 101 | (*filter->bpf_func)(ctx, filter->insnsi) | ||
| 102 | |||
| 53 | int sk_filter(struct sock *sk, struct sk_buff *skb); | 103 | int sk_filter(struct sock *sk, struct sk_buff *skb); |
| 54 | unsigned int sk_run_filter(const struct sk_buff *skb, | 104 | |
| 55 | const struct sock_filter *filter); | 105 | u32 sk_run_filter_int_seccomp(const struct seccomp_data *ctx, |
| 106 | const struct sock_filter_int *insni); | ||
| 107 | u32 sk_run_filter_int_skb(const struct sk_buff *ctx, | ||
| 108 | const struct sock_filter_int *insni); | ||
| 109 | |||
| 110 | int sk_convert_filter(struct sock_filter *prog, int len, | ||
| 111 | struct sock_filter_int *new_prog, int *new_len); | ||
| 56 | 112 | ||
| 57 | int sk_unattached_filter_create(struct sk_filter **pfp, | 113 | int sk_unattached_filter_create(struct sk_filter **pfp, |
| 58 | struct sock_fprog *fprog); | 114 | struct sock_fprog *fprog); |
| @@ -86,7 +142,6 @@ static inline void bpf_jit_dump(unsigned int flen, unsigned int proglen, | |||
| 86 | print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_OFFSET, | 142 | print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_OFFSET, |
| 87 | 16, 1, image, proglen, false); | 143 | 16, 1, image, proglen, false); |
| 88 | } | 144 | } |
| 89 | #define SK_RUN_FILTER(FILTER, SKB) (*FILTER->bpf_func)(SKB, FILTER->insns) | ||
| 90 | #else | 145 | #else |
| 91 | #include <linux/slab.h> | 146 | #include <linux/slab.h> |
| 92 | static inline void bpf_jit_compile(struct sk_filter *fp) | 147 | static inline void bpf_jit_compile(struct sk_filter *fp) |
| @@ -96,7 +151,6 @@ static inline void bpf_jit_free(struct sk_filter *fp) | |||
| 96 | { | 151 | { |
| 97 | kfree(fp); | 152 | kfree(fp); |
| 98 | } | 153 | } |
| 99 | #define SK_RUN_FILTER(FILTER, SKB) sk_run_filter(SKB, FILTER->insns) | ||
| 100 | #endif | 154 | #endif |
| 101 | 155 | ||
| 102 | static inline int bpf_tell_extensions(void) | 156 | static inline int bpf_tell_extensions(void) |
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index 6f19cfd1840e..4054b0994071 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h | |||
| @@ -76,7 +76,6 @@ static inline int seccomp_mode(struct seccomp *s) | |||
| 76 | #ifdef CONFIG_SECCOMP_FILTER | 76 | #ifdef CONFIG_SECCOMP_FILTER |
| 77 | extern void put_seccomp_filter(struct task_struct *tsk); | 77 | extern void put_seccomp_filter(struct task_struct *tsk); |
| 78 | extern void get_seccomp_filter(struct task_struct *tsk); | 78 | extern void get_seccomp_filter(struct task_struct *tsk); |
| 79 | extern u32 seccomp_bpf_load(int off); | ||
| 80 | #else /* CONFIG_SECCOMP_FILTER */ | 79 | #else /* CONFIG_SECCOMP_FILTER */ |
| 81 | static inline void put_seccomp_filter(struct task_struct *tsk) | 80 | static inline void put_seccomp_filter(struct task_struct *tsk) |
| 82 | { | 81 | { |
