aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/seccomp.c
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-05-29 04:22:50 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-02 01:16:58 -0400
commit3480593131e0b781287dae0139bf7ccee7cba7ff (patch)
tree6e259a45b3767bd80b789814e4d484ee0ac069bf /kernel/seccomp.c
parentd50bc1575096250aa37f17299c86ea548156efe8 (diff)
net: filter: get rid of BPF_S_* enum
This patch finally allows us to get rid of the BPF_S_* enum. Currently, the code performs unnecessary encode and decode workarounds in seccomp and filter migration itself when a filter is being attached in order to overcome BPF_S_* encoding which is not used anymore by the new interpreter resp. JIT compilers. Keeping it around would mean that also in future we would need to extend and maintain this enum and related encoders/decoders. We can get rid of all that and save us these operations during filter attaching. Naturally, also JIT compilers need to be updated by this. Before JIT conversion is being done, each compiler checks if A is being loaded at startup to obtain information if it needs to emit instructions to clear A first. Since BPF extensions are a subset of BPF_LD | BPF_{W,H,B} | BPF_ABS variants, case statements for extensions can be removed at that point. To ease and minimalize code changes in the classic JITs, we have introduced bpf_anc_helper(). Tested with test_bpf on x86_64 (JIT, int), s390x (JIT, int), arm (JIT, int), i368 (int), ppc64 (JIT, int); for sparc we unfortunately didn't have access, but changes are analogous to the rest. Joint work with Alexei Starovoitov. Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Mircea Gherzan <mgherzan@gmail.com> Cc: Kees Cook <keescook@chromium.org> Acked-by: Chema Gonzalez <chemag@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/seccomp.c')
-rw-r--r--kernel/seccomp.c83
1 files changed, 41 insertions, 42 deletions
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 1036b6f2fded..44e69483b383 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -103,60 +103,59 @@ static int seccomp_check_filter(struct sock_filter *filter, unsigned int flen)
103 u32 k = ftest->k; 103 u32 k = ftest->k;
104 104
105 switch (code) { 105 switch (code) {
106 case BPF_S_LD_W_ABS: 106 case BPF_LD | BPF_W | BPF_ABS:
107 ftest->code = BPF_LDX | BPF_W | BPF_ABS; 107 ftest->code = BPF_LDX | BPF_W | BPF_ABS;
108 /* 32-bit aligned and not out of bounds. */ 108 /* 32-bit aligned and not out of bounds. */
109 if (k >= sizeof(struct seccomp_data) || k & 3) 109 if (k >= sizeof(struct seccomp_data) || k & 3)
110 return -EINVAL; 110 return -EINVAL;
111 continue; 111 continue;
112 case BPF_S_LD_W_LEN: 112 case BPF_LD | BPF_W | BPF_LEN:
113 ftest->code = BPF_LD | BPF_IMM; 113 ftest->code = BPF_LD | BPF_IMM;
114 ftest->k = sizeof(struct seccomp_data); 114 ftest->k = sizeof(struct seccomp_data);
115 continue; 115 continue;
116 case BPF_S_LDX_W_LEN: 116 case BPF_LDX | BPF_W | BPF_LEN:
117 ftest->code = BPF_LDX | BPF_IMM; 117 ftest->code = BPF_LDX | BPF_IMM;
118 ftest->k = sizeof(struct seccomp_data); 118 ftest->k = sizeof(struct seccomp_data);
119 continue; 119 continue;
120 /* Explicitly include allowed calls. */ 120 /* Explicitly include allowed calls. */
121 case BPF_S_RET_K: 121 case BPF_RET | BPF_K:
122 case BPF_S_RET_A: 122 case BPF_RET | BPF_A:
123 case BPF_S_ALU_ADD_K: 123 case BPF_ALU | BPF_ADD | BPF_K:
124 case BPF_S_ALU_ADD_X: 124 case BPF_ALU | BPF_ADD | BPF_X:
125 case BPF_S_ALU_SUB_K: 125 case BPF_ALU | BPF_SUB | BPF_K:
126 case BPF_S_ALU_SUB_X: 126 case BPF_ALU | BPF_SUB | BPF_X:
127 case BPF_S_ALU_MUL_K: 127 case BPF_ALU | BPF_MUL | BPF_K:
128 case BPF_S_ALU_MUL_X: 128 case BPF_ALU | BPF_MUL | BPF_X:
129 case BPF_S_ALU_DIV_X: 129 case BPF_ALU | BPF_DIV | BPF_K:
130 case BPF_S_ALU_AND_K: 130 case BPF_ALU | BPF_DIV | BPF_X:
131 case BPF_S_ALU_AND_X: 131 case BPF_ALU | BPF_AND | BPF_K:
132 case BPF_S_ALU_OR_K: 132 case BPF_ALU | BPF_AND | BPF_X:
133 case BPF_S_ALU_OR_X: 133 case BPF_ALU | BPF_OR | BPF_K:
134 case BPF_S_ALU_XOR_K: 134 case BPF_ALU | BPF_OR | BPF_X:
135 case BPF_S_ALU_XOR_X: 135 case BPF_ALU | BPF_XOR | BPF_K:
136 case BPF_S_ALU_LSH_K: 136 case BPF_ALU | BPF_XOR | BPF_X:
137 case BPF_S_ALU_LSH_X: 137 case BPF_ALU | BPF_LSH | BPF_K:
138 case BPF_S_ALU_RSH_K: 138 case BPF_ALU | BPF_LSH | BPF_X:
139 case BPF_S_ALU_RSH_X: 139 case BPF_ALU | BPF_RSH | BPF_K:
140 case BPF_S_ALU_NEG: 140 case BPF_ALU | BPF_RSH | BPF_X:
141 case BPF_S_LD_IMM: 141 case BPF_ALU | BPF_NEG:
142 case BPF_S_LDX_IMM: 142 case BPF_LD | BPF_IMM:
143 case BPF_S_MISC_TAX: 143 case BPF_LDX | BPF_IMM:
144 case BPF_S_MISC_TXA: 144 case BPF_MISC | BPF_TAX:
145 case BPF_S_ALU_DIV_K: 145 case BPF_MISC | BPF_TXA:
146 case BPF_S_LD_MEM: 146 case BPF_LD | BPF_MEM:
147 case BPF_S_LDX_MEM: 147 case BPF_LDX | BPF_MEM:
148 case BPF_S_ST: 148 case BPF_ST:
149 case BPF_S_STX: 149 case BPF_STX:
150 case BPF_S_JMP_JA: 150 case BPF_JMP | BPF_JA:
151 case BPF_S_JMP_JEQ_K: 151 case BPF_JMP | BPF_JEQ | BPF_K:
152 case BPF_S_JMP_JEQ_X: 152 case BPF_JMP | BPF_JEQ | BPF_X:
153 case BPF_S_JMP_JGE_K: 153 case BPF_JMP | BPF_JGE | BPF_K:
154 case BPF_S_JMP_JGE_X: 154 case BPF_JMP | BPF_JGE | BPF_X:
155 case BPF_S_JMP_JGT_K: 155 case BPF_JMP | BPF_JGT | BPF_K:
156 case BPF_S_JMP_JGT_X: 156 case BPF_JMP | BPF_JGT | BPF_X:
157 case BPF_S_JMP_JSET_K: 157 case BPF_JMP | BPF_JSET | BPF_K:
158 case BPF_S_JMP_JSET_X: 158 case BPF_JMP | BPF_JSET | BPF_X:
159 sk_decode_filter(ftest, ftest);
160 continue; 159 continue;
161 default: 160 default:
162 return -EINVAL; 161 return -EINVAL;