summaryrefslogtreecommitdiffstats
path: root/kernel/bpf/verifier.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-02-08 08:20:32 -0500
committerTakashi Iwai <tiwai@suse.de>2019-02-08 08:20:32 -0500
commitd02cac152c97dffcb0cdd91e09b54fd6e2cca63d (patch)
tree68e4c6bd842703009f3edbf8f0e0e9326e4b2fad /kernel/bpf/verifier.c
parent36e4617c01153757cde9e5fcd375a75a8f8425c3 (diff)
parenta50e32694fbcdbf55875095258b9398e2eabd71f (diff)
Merge tag 'asoc-v5.1' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v5.1 Lots and lots of new drivers so far, a highlight being the MediaTek BTCVSD which is a driver for a Bluetooth radio chip - the first such driver we've had upstream. Hopefully we will soon also see a baseband with an upstream driver! - Support for only powering up channels that are actively being used. - Quite a few improvements to simplify the generic card drivers, especially the merge of the SCU cards into the main generic drivers. - Lots of fixes for probing on Intel systems, trying to rationalize things to look more standard from a framework point of view. - New drivers for Asahi Kasei Microdevices AK4497, Cirrus Logic CS4341, Google ChromeOS embedded controllers, Ingenic JZ4725B, MediaTek BTCVSD, MT8183 and MT6358, NXP MICFIL, Rockchip RK3328, Spreadtrum DMA controllers, Qualcomm WCD9335, Xilinx S/PDIF and PCM formatters.
Diffstat (limited to 'kernel/bpf/verifier.c')
-rw-r--r--kernel/bpf/verifier.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index f6bc62a9ee8e..56674a7c3778 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3103,6 +3103,40 @@ static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg,
3103 } 3103 }
3104} 3104}
3105 3105
3106static bool can_skip_alu_sanitation(const struct bpf_verifier_env *env,
3107 const struct bpf_insn *insn)
3108{
3109 return env->allow_ptr_leaks || BPF_SRC(insn->code) == BPF_K;
3110}
3111
3112static int update_alu_sanitation_state(struct bpf_insn_aux_data *aux,
3113 u32 alu_state, u32 alu_limit)
3114{
3115 /* If we arrived here from different branches with different
3116 * state or limits to sanitize, then this won't work.
3117 */
3118 if (aux->alu_state &&
3119 (aux->alu_state != alu_state ||
3120 aux->alu_limit != alu_limit))
3121 return -EACCES;
3122
3123 /* Corresponding fixup done in fixup_bpf_calls(). */
3124 aux->alu_state = alu_state;
3125 aux->alu_limit = alu_limit;
3126 return 0;
3127}
3128
3129static int sanitize_val_alu(struct bpf_verifier_env *env,
3130 struct bpf_insn *insn)
3131{
3132 struct bpf_insn_aux_data *aux = cur_aux(env);
3133
3134 if (can_skip_alu_sanitation(env, insn))
3135 return 0;
3136
3137 return update_alu_sanitation_state(aux, BPF_ALU_NON_POINTER, 0);
3138}
3139
3106static int sanitize_ptr_alu(struct bpf_verifier_env *env, 3140static int sanitize_ptr_alu(struct bpf_verifier_env *env,
3107 struct bpf_insn *insn, 3141 struct bpf_insn *insn,
3108 const struct bpf_reg_state *ptr_reg, 3142 const struct bpf_reg_state *ptr_reg,
@@ -3117,7 +3151,7 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env,
3117 struct bpf_reg_state tmp; 3151 struct bpf_reg_state tmp;
3118 bool ret; 3152 bool ret;
3119 3153
3120 if (env->allow_ptr_leaks || BPF_SRC(insn->code) == BPF_K) 3154 if (can_skip_alu_sanitation(env, insn))
3121 return 0; 3155 return 0;
3122 3156
3123 /* We already marked aux for masking from non-speculative 3157 /* We already marked aux for masking from non-speculative
@@ -3133,19 +3167,8 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env,
3133 3167
3134 if (retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg)) 3168 if (retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg))
3135 return 0; 3169 return 0;
3136 3170 if (update_alu_sanitation_state(aux, alu_state, alu_limit))
3137 /* If we arrived here from different branches with different
3138 * limits to sanitize, then this won't work.
3139 */
3140 if (aux->alu_state &&
3141 (aux->alu_state != alu_state ||
3142 aux->alu_limit != alu_limit))
3143 return -EACCES; 3171 return -EACCES;
3144
3145 /* Corresponding fixup done in fixup_bpf_calls(). */
3146 aux->alu_state = alu_state;
3147 aux->alu_limit = alu_limit;
3148
3149do_sim: 3172do_sim:
3150 /* Simulate and find potential out-of-bounds access under 3173 /* Simulate and find potential out-of-bounds access under
3151 * speculative execution from truncation as a result of 3174 * speculative execution from truncation as a result of
@@ -3418,6 +3441,8 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
3418 s64 smin_val, smax_val; 3441 s64 smin_val, smax_val;
3419 u64 umin_val, umax_val; 3442 u64 umin_val, umax_val;
3420 u64 insn_bitness = (BPF_CLASS(insn->code) == BPF_ALU64) ? 64 : 32; 3443 u64 insn_bitness = (BPF_CLASS(insn->code) == BPF_ALU64) ? 64 : 32;
3444 u32 dst = insn->dst_reg;
3445 int ret;
3421 3446
3422 if (insn_bitness == 32) { 3447 if (insn_bitness == 32) {
3423 /* Relevant for 32-bit RSH: Information can propagate towards 3448 /* Relevant for 32-bit RSH: Information can propagate towards
@@ -3452,6 +3477,11 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
3452 3477
3453 switch (opcode) { 3478 switch (opcode) {
3454 case BPF_ADD: 3479 case BPF_ADD:
3480 ret = sanitize_val_alu(env, insn);
3481 if (ret < 0) {
3482 verbose(env, "R%d tried to add from different pointers or scalars\n", dst);
3483 return ret;
3484 }
3455 if (signed_add_overflows(dst_reg->smin_value, smin_val) || 3485 if (signed_add_overflows(dst_reg->smin_value, smin_val) ||
3456 signed_add_overflows(dst_reg->smax_value, smax_val)) { 3486 signed_add_overflows(dst_reg->smax_value, smax_val)) {
3457 dst_reg->smin_value = S64_MIN; 3487 dst_reg->smin_value = S64_MIN;
@@ -3471,6 +3501,11 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
3471 dst_reg->var_off = tnum_add(dst_reg->var_off, src_reg.var_off); 3501 dst_reg->var_off = tnum_add(dst_reg->var_off, src_reg.var_off);
3472 break; 3502 break;
3473 case BPF_SUB: 3503 case BPF_SUB:
3504 ret = sanitize_val_alu(env, insn);
3505 if (ret < 0) {
3506 verbose(env, "R%d tried to sub from different pointers or scalars\n", dst);
3507 return ret;
3508 }
3474 if (signed_sub_overflows(dst_reg->smin_value, smax_val) || 3509 if (signed_sub_overflows(dst_reg->smin_value, smax_val) ||
3475 signed_sub_overflows(dst_reg->smax_value, smin_val)) { 3510 signed_sub_overflows(dst_reg->smax_value, smin_val)) {
3476 /* Overflow possible, we know nothing */ 3511 /* Overflow possible, we know nothing */