diff options
Diffstat (limited to 'net/core/filter.c')
-rw-r--r-- | net/core/filter.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index 907efd27ec7..3d92ebb7fbc 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -167,6 +167,14 @@ unsigned int sk_run_filter(const struct sk_buff *skb, | |||
167 | case BPF_S_ALU_DIV_K: | 167 | case BPF_S_ALU_DIV_K: |
168 | A = reciprocal_divide(A, K); | 168 | A = reciprocal_divide(A, K); |
169 | continue; | 169 | continue; |
170 | case BPF_S_ALU_MOD_X: | ||
171 | if (X == 0) | ||
172 | return 0; | ||
173 | A %= X; | ||
174 | continue; | ||
175 | case BPF_S_ALU_MOD_K: | ||
176 | A %= K; | ||
177 | continue; | ||
170 | case BPF_S_ALU_AND_X: | 178 | case BPF_S_ALU_AND_X: |
171 | A &= X; | 179 | A &= X; |
172 | continue; | 180 | continue; |
@@ -179,6 +187,13 @@ unsigned int sk_run_filter(const struct sk_buff *skb, | |||
179 | case BPF_S_ALU_OR_K: | 187 | case BPF_S_ALU_OR_K: |
180 | A |= K; | 188 | A |= K; |
181 | continue; | 189 | continue; |
190 | case BPF_S_ANC_ALU_XOR_X: | ||
191 | case BPF_S_ALU_XOR_X: | ||
192 | A ^= X; | ||
193 | continue; | ||
194 | case BPF_S_ALU_XOR_K: | ||
195 | A ^= K; | ||
196 | continue; | ||
182 | case BPF_S_ALU_LSH_X: | 197 | case BPF_S_ALU_LSH_X: |
183 | A <<= X; | 198 | A <<= X; |
184 | continue; | 199 | continue; |
@@ -326,9 +341,6 @@ load_b: | |||
326 | case BPF_S_ANC_CPU: | 341 | case BPF_S_ANC_CPU: |
327 | A = raw_smp_processor_id(); | 342 | A = raw_smp_processor_id(); |
328 | continue; | 343 | continue; |
329 | case BPF_S_ANC_ALU_XOR_X: | ||
330 | A ^= X; | ||
331 | continue; | ||
332 | case BPF_S_ANC_NLATTR: { | 344 | case BPF_S_ANC_NLATTR: { |
333 | struct nlattr *nla; | 345 | struct nlattr *nla; |
334 | 346 | ||
@@ -469,10 +481,14 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen) | |||
469 | [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K, | 481 | [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K, |
470 | [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X, | 482 | [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X, |
471 | [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X, | 483 | [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X, |
484 | [BPF_ALU|BPF_MOD|BPF_K] = BPF_S_ALU_MOD_K, | ||
485 | [BPF_ALU|BPF_MOD|BPF_X] = BPF_S_ALU_MOD_X, | ||
472 | [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K, | 486 | [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K, |
473 | [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X, | 487 | [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X, |
474 | [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K, | 488 | [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K, |
475 | [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X, | 489 | [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X, |
490 | [BPF_ALU|BPF_XOR|BPF_K] = BPF_S_ALU_XOR_K, | ||
491 | [BPF_ALU|BPF_XOR|BPF_X] = BPF_S_ALU_XOR_X, | ||
476 | [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K, | 492 | [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K, |
477 | [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X, | 493 | [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X, |
478 | [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K, | 494 | [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K, |
@@ -531,6 +547,11 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen) | |||
531 | return -EINVAL; | 547 | return -EINVAL; |
532 | ftest->k = reciprocal_value(ftest->k); | 548 | ftest->k = reciprocal_value(ftest->k); |
533 | break; | 549 | break; |
550 | case BPF_S_ALU_MOD_K: | ||
551 | /* check for division by zero */ | ||
552 | if (ftest->k == 0) | ||
553 | return -EINVAL; | ||
554 | break; | ||
534 | case BPF_S_LD_MEM: | 555 | case BPF_S_LD_MEM: |
535 | case BPF_S_LDX_MEM: | 556 | case BPF_S_LDX_MEM: |
536 | case BPF_S_ST: | 557 | case BPF_S_ST: |