aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/filter.c')
-rw-r--r--net/core/filter.c27
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: