aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/core.c52
-rw-r--r--kernel/bpf/verifier.c5
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;