@@ -7438,7 +7438,8 @@ static int check_stack_range_initialized(
74387438}
74397439
74407440static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
7441- int access_size, bool zero_size_allowed,
7441+ int access_size, enum bpf_access_type access_type,
7442+ bool zero_size_allowed,
74427443 struct bpf_call_arg_meta *meta)
74437444{
74447445 struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno];
@@ -7450,23 +7451,21 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
74507451 return check_packet_access(env, regno, reg->off, access_size,
74517452 zero_size_allowed);
74527453 case PTR_TO_MAP_KEY:
7453- if (meta && meta->raw_mode ) {
7454+ if (access_type == BPF_WRITE ) {
74547455 verbose(env, "R%d cannot write into %s\n", regno,
74557456 reg_type_str(env, reg->type));
74567457 return -EACCES;
74577458 }
74587459 return check_mem_region_access(env, regno, reg->off, access_size,
74597460 reg->map_ptr->key_size, false);
74607461 case PTR_TO_MAP_VALUE:
7461- if (check_map_access_type(env, regno, reg->off, access_size,
7462- meta && meta->raw_mode ? BPF_WRITE :
7463- BPF_READ))
7462+ if (check_map_access_type(env, regno, reg->off, access_size, access_type))
74647463 return -EACCES;
74657464 return check_map_access(env, regno, reg->off, access_size,
74667465 zero_size_allowed, ACCESS_HELPER);
74677466 case PTR_TO_MEM:
74687467 if (type_is_rdonly_mem(reg->type)) {
7469- if (meta && meta->raw_mode ) {
7468+ if (access_type == BPF_WRITE ) {
74707469 verbose(env, "R%d cannot write into %s\n", regno,
74717470 reg_type_str(env, reg->type));
74727471 return -EACCES;
@@ -7477,7 +7476,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
74777476 zero_size_allowed);
74787477 case PTR_TO_BUF:
74797478 if (type_is_rdonly_mem(reg->type)) {
7480- if (meta && meta->raw_mode ) {
7479+ if (access_type == BPF_WRITE ) {
74817480 verbose(env, "R%d cannot write into %s\n", regno,
74827481 reg_type_str(env, reg->type));
74837482 return -EACCES;
@@ -7505,15 +7504,14 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
75057504 * Dynamically check it now.
75067505 */
75077506 if (!env->ops->convert_ctx_access) {
7508- enum bpf_access_type atype = meta && meta->raw_mode ? BPF_WRITE : BPF_READ;
75097507 int offset = access_size - 1;
75107508
75117509 /* Allow zero-byte read from PTR_TO_CTX */
75127510 if (access_size == 0)
75137511 return zero_size_allowed ? 0 : -EACCES;
75147512
75157513 return check_mem_access(env, env->insn_idx, regno, offset, BPF_B,
7516- atype , -1, false, false);
7514+ access_type , -1, false, false);
75177515 }
75187516
75197517 fallthrough;
@@ -7538,6 +7536,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
75387536 */
75397537static int check_mem_size_reg(struct bpf_verifier_env *env,
75407538 struct bpf_reg_state *reg, u32 regno,
7539+ enum bpf_access_type access_type,
75417540 bool zero_size_allowed,
75427541 struct bpf_call_arg_meta *meta)
75437542{
@@ -7553,15 +7552,12 @@ static int check_mem_size_reg(struct bpf_verifier_env *env,
75537552 */
75547553 meta->msize_max_value = reg->umax_value;
75557554
7556- /* The register is SCALAR_VALUE; the access check
7557- * happens using its boundaries.
7555+ /* The register is SCALAR_VALUE; the access check happens using
7556+ * its boundaries. For unprivileged variable accesses, disable
7557+ * raw mode so that the program is required to initialize all
7558+ * the memory that the helper could just partially fill up.
75587559 */
75597560 if (!tnum_is_const(reg->var_off))
7560- /* For unprivileged variable accesses, disable raw
7561- * mode so that the program is required to
7562- * initialize all the memory that the helper could
7563- * just partially fill up.
7564- */
75657561 meta = NULL;
75667562
75677563 if (reg->smin_value < 0) {
@@ -7581,9 +7577,8 @@ static int check_mem_size_reg(struct bpf_verifier_env *env,
75817577 regno);
75827578 return -EACCES;
75837579 }
7584- err = check_helper_mem_access(env, regno - 1,
7585- reg->umax_value,
7586- zero_size_allowed, meta);
7580+ err = check_helper_mem_access(env, regno - 1, reg->umax_value,
7581+ access_type, zero_size_allowed, meta);
75877582 if (!err)
75887583 err = mark_chain_precision(env, regno);
75897584 return err;
@@ -7594,13 +7589,11 @@ static int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg
75947589{
75957590 bool may_be_null = type_may_be_null(reg->type);
75967591 struct bpf_reg_state saved_reg;
7597- struct bpf_call_arg_meta meta;
75987592 int err;
75997593
76007594 if (register_is_null(reg))
76017595 return 0;
76027596
7603- memset(&meta, 0, sizeof(meta));
76047597 /* Assuming that the register contains a value check if the memory
76057598 * access is safe. Temporarily save and restore the register's state as
76067599 * the conversion shouldn't be visible to a caller.
@@ -7610,10 +7603,8 @@ static int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg
76107603 mark_ptr_not_null_reg(reg);
76117604 }
76127605
7613- err = check_helper_mem_access(env, regno, mem_size, true, &meta);
7614- /* Check access for BPF_WRITE */
7615- meta.raw_mode = true;
7616- err = err ?: check_helper_mem_access(env, regno, mem_size, true, &meta);
7606+ err = check_helper_mem_access(env, regno, mem_size, BPF_READ, true, NULL);
7607+ err = err ?: check_helper_mem_access(env, regno, mem_size, BPF_WRITE, true, NULL);
76177608
76187609 if (may_be_null)
76197610 *reg = saved_reg;
@@ -7639,13 +7630,12 @@ static int check_kfunc_mem_size_reg(struct bpf_verifier_env *env, struct bpf_reg
76397630 mark_ptr_not_null_reg(mem_reg);
76407631 }
76417632
7642- err = check_mem_size_reg(env, reg, regno, true, &meta);
7643- /* Check access for BPF_WRITE */
7644- meta.raw_mode = true;
7645- err = err ?: check_mem_size_reg(env, reg, regno, true, &meta);
7633+ err = check_mem_size_reg(env, reg, regno, BPF_READ, true, &meta);
7634+ err = err ?: check_mem_size_reg(env, reg, regno, BPF_WRITE, true, &meta);
76467635
76477636 if (may_be_null)
76487637 *mem_reg = saved_reg;
7638+
76497639 return err;
76507640}
76517641
@@ -8948,9 +8938,8 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
89488938 verbose(env, "invalid map_ptr to access map->key\n");
89498939 return -EACCES;
89508940 }
8951- err = check_helper_mem_access(env, regno,
8952- meta->map_ptr->key_size, false,
8953- NULL);
8941+ err = check_helper_mem_access(env, regno, meta->map_ptr->key_size,
8942+ BPF_READ, false, NULL);
89548943 break;
89558944 case ARG_PTR_TO_MAP_VALUE:
89568945 if (type_may_be_null(arg_type) && register_is_null(reg))
@@ -8965,9 +8954,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
89658954 return -EACCES;
89668955 }
89678956 meta->raw_mode = arg_type & MEM_UNINIT;
8968- err = check_helper_mem_access(env, regno,
8969- meta->map_ptr->value_size, false ,
8970- meta);
8957+ err = check_helper_mem_access(env, regno, meta->map_ptr->value_size,
8958+ arg_type & MEM_WRITE ? BPF_WRITE : BPF_READ ,
8959+ false, meta);
89718960 break;
89728961 case ARG_PTR_TO_PERCPU_BTF_ID:
89738962 if (!reg->btf_id) {
@@ -9009,18 +8998,26 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
90098998 */
90108999 meta->raw_mode = arg_type & MEM_UNINIT;
90119000 if (arg_type & MEM_FIXED_SIZE) {
9012- err = check_helper_mem_access(env, regno, fn->arg_size[arg], false, meta);
9001+ err = check_helper_mem_access(env, regno, fn->arg_size[arg],
9002+ arg_type & MEM_WRITE ? BPF_WRITE : BPF_READ,
9003+ false, meta);
90139004 if (err)
90149005 return err;
90159006 if (arg_type & MEM_ALIGNED)
90169007 err = check_ptr_alignment(env, reg, 0, fn->arg_size[arg], true);
90179008 }
90189009 break;
90199010 case ARG_CONST_SIZE:
9020- err = check_mem_size_reg(env, reg, regno, false, meta);
9011+ err = check_mem_size_reg(env, reg, regno,
9012+ fn->arg_type[arg - 1] & MEM_WRITE ?
9013+ BPF_WRITE : BPF_READ,
9014+ false, meta);
90219015 break;
90229016 case ARG_CONST_SIZE_OR_ZERO:
9023- err = check_mem_size_reg(env, reg, regno, true, meta);
9017+ err = check_mem_size_reg(env, reg, regno,
9018+ fn->arg_type[arg - 1] & MEM_WRITE ?
9019+ BPF_WRITE : BPF_READ,
9020+ true, meta);
90249021 break;
90259022 case ARG_PTR_TO_DYNPTR:
90269023 err = process_dynptr_func(env, regno, insn_idx, arg_type, 0);
@@ -21213,7 +21210,7 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
2121321210 delta += cnt - 1;
2121421211 env->prog = prog = new_prog;
2121521212 insn = new_prog->insnsi + i + delta;
21216- continue ;
21213+ goto next_insn ;
2121721214 }
2121821215
2121921216 /* Implement bpf_kptr_xchg inline */
0 commit comments