|
@@ -167,6 +167,14 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
|
|
|
case BPF_S_ALU_DIV_K:
|
|
|
A = reciprocal_divide(A, K);
|
|
|
continue;
|
|
|
+ case BPF_S_ALU_MOD_X:
|
|
|
+ if (X == 0)
|
|
|
+ return 0;
|
|
|
+ A %= X;
|
|
|
+ continue;
|
|
|
+ case BPF_S_ALU_MOD_K:
|
|
|
+ A %= K;
|
|
|
+ continue;
|
|
|
case BPF_S_ALU_AND_X:
|
|
|
A &= X;
|
|
|
continue;
|
|
@@ -469,6 +477,8 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
|
|
|
[BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K,
|
|
|
[BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X,
|
|
|
[BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X,
|
|
|
+ [BPF_ALU|BPF_MOD|BPF_K] = BPF_S_ALU_MOD_K,
|
|
|
+ [BPF_ALU|BPF_MOD|BPF_X] = BPF_S_ALU_MOD_X,
|
|
|
[BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K,
|
|
|
[BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X,
|
|
|
[BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K,
|
|
@@ -531,6 +541,11 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
|
|
|
return -EINVAL;
|
|
|
ftest->k = reciprocal_value(ftest->k);
|
|
|
break;
|
|
|
+ case BPF_S_ALU_MOD_K:
|
|
|
+ /* check for division by zero */
|
|
|
+ if (ftest->k == 0)
|
|
|
+ return -EINVAL;
|
|
|
+ break;
|
|
|
case BPF_S_LD_MEM:
|
|
|
case BPF_S_LDX_MEM:
|
|
|
case BPF_S_ST:
|