diff options
Diffstat (limited to 'kernel/bpf')
| -rw-r--r-- | kernel/bpf/core.c | 52 | ||||
| -rw-r--r-- | kernel/bpf/verifier.c | 5 |
2 files changed, 30 insertions, 27 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 628b3970a49b..a5b223ef7131 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
| @@ -933,32 +933,34 @@ EXPORT_SYMBOL_GPL(__bpf_call_base); | |||
| 933 | #define BPF_INSN_MAP(INSN_2, INSN_3) \ | 933 | #define BPF_INSN_MAP(INSN_2, INSN_3) \ |
| 934 | /* 32 bit ALU operations. */ \ | 934 | /* 32 bit ALU operations. */ \ |
| 935 | /* Register based. */ \ | 935 | /* Register based. */ \ |
| 936 | INSN_3(ALU, ADD, X), \ | 936 | INSN_3(ALU, ADD, X), \ |
| 937 | INSN_3(ALU, SUB, X), \ | 937 | INSN_3(ALU, SUB, X), \ |
| 938 | INSN_3(ALU, AND, X), \ | 938 | INSN_3(ALU, AND, X), \ |
| 939 | INSN_3(ALU, OR, X), \ | 939 | INSN_3(ALU, OR, X), \ |
| 940 | INSN_3(ALU, LSH, X), \ | 940 | INSN_3(ALU, LSH, X), \ |
| 941 | INSN_3(ALU, RSH, X), \ | 941 | INSN_3(ALU, RSH, X), \ |
| 942 | INSN_3(ALU, XOR, X), \ | 942 | INSN_3(ALU, XOR, X), \ |
| 943 | INSN_3(ALU, MUL, X), \ | 943 | INSN_3(ALU, MUL, X), \ |
| 944 | INSN_3(ALU, MOV, X), \ | 944 | INSN_3(ALU, MOV, X), \ |
| 945 | INSN_3(ALU, DIV, X), \ | 945 | INSN_3(ALU, ARSH, X), \ |
| 946 | INSN_3(ALU, MOD, X), \ | 946 | INSN_3(ALU, DIV, X), \ |
| 947 | INSN_3(ALU, MOD, X), \ | ||
| 947 | INSN_2(ALU, NEG), \ | 948 | INSN_2(ALU, NEG), \ |
| 948 | INSN_3(ALU, END, TO_BE), \ | 949 | INSN_3(ALU, END, TO_BE), \ |
| 949 | INSN_3(ALU, END, TO_LE), \ | 950 | INSN_3(ALU, END, TO_LE), \ |
| 950 | /* Immediate based. */ \ | 951 | /* Immediate based. */ \ |
| 951 | INSN_3(ALU, ADD, K), \ | 952 | INSN_3(ALU, ADD, K), \ |
| 952 | INSN_3(ALU, SUB, K), \ | 953 | INSN_3(ALU, SUB, K), \ |
| 953 | INSN_3(ALU, AND, K), \ | 954 | INSN_3(ALU, AND, K), \ |
| 954 | INSN_3(ALU, OR, K), \ | 955 | INSN_3(ALU, OR, K), \ |
| 955 | INSN_3(ALU, LSH, K), \ | 956 | INSN_3(ALU, LSH, K), \ |
| 956 | INSN_3(ALU, RSH, K), \ | 957 | INSN_3(ALU, RSH, K), \ |
| 957 | INSN_3(ALU, XOR, K), \ | 958 | INSN_3(ALU, XOR, K), \ |
| 958 | INSN_3(ALU, MUL, K), \ | 959 | INSN_3(ALU, MUL, K), \ |
| 959 | INSN_3(ALU, MOV, K), \ | 960 | INSN_3(ALU, MOV, K), \ |
| 960 | INSN_3(ALU, DIV, K), \ | 961 | INSN_3(ALU, ARSH, K), \ |
| 961 | INSN_3(ALU, MOD, K), \ | 962 | INSN_3(ALU, DIV, K), \ |
| 963 | INSN_3(ALU, MOD, K), \ | ||
| 962 | /* 64 bit ALU operations. */ \ | 964 | /* 64 bit ALU operations. */ \ |
| 963 | /* Register based. */ \ | 965 | /* Register based. */ \ |
| 964 | INSN_3(ALU64, ADD, X), \ | 966 | INSN_3(ALU64, ADD, X), \ |
| @@ -1137,6 +1139,12 @@ select_insn: | |||
| 1137 | DST = (u64) (u32) insn[0].imm | ((u64) (u32) insn[1].imm) << 32; | 1139 | DST = (u64) (u32) insn[0].imm | ((u64) (u32) insn[1].imm) << 32; |
| 1138 | insn++; | 1140 | insn++; |
| 1139 | CONT; | 1141 | CONT; |
| 1142 | ALU_ARSH_X: | ||
| 1143 | DST = (u64) (u32) ((*(s32 *) &DST) >> SRC); | ||
| 1144 | CONT; | ||
| 1145 | ALU_ARSH_K: | ||
| 1146 | DST = (u64) (u32) ((*(s32 *) &DST) >> IMM); | ||
| 1147 | CONT; | ||
| 1140 | ALU64_ARSH_X: | 1148 | ALU64_ARSH_X: |
| 1141 | (*(s64 *) &DST) >>= SRC; | 1149 | (*(s64 *) &DST) >>= SRC; |
| 1142 | CONT; | 1150 | CONT; |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 7658c61c1a88..2752d35ad073 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
| @@ -3649,11 +3649,6 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) | |||
| 3649 | return -EINVAL; | 3649 | return -EINVAL; |
| 3650 | } | 3650 | } |
| 3651 | 3651 | ||
| 3652 | if (opcode == BPF_ARSH && BPF_CLASS(insn->code) != BPF_ALU64) { | ||
| 3653 | verbose(env, "BPF_ARSH not supported for 32 bit ALU\n"); | ||
| 3654 | return -EINVAL; | ||
| 3655 | } | ||
| 3656 | |||
| 3657 | if ((opcode == BPF_LSH || opcode == BPF_RSH || | 3652 | if ((opcode == BPF_LSH || opcode == BPF_RSH || |
| 3658 | opcode == BPF_ARSH) && BPF_SRC(insn->code) == BPF_K) { | 3653 | opcode == BPF_ARSH) && BPF_SRC(insn->code) == BPF_K) { |
| 3659 | int size = BPF_CLASS(insn->code) == BPF_ALU64 ? 64 : 32; | 3654 | int size = BPF_CLASS(insn->code) == BPF_ALU64 ? 64 : 32; |
