Skip to content

Commit c22e5c1

Browse files
committed
Merge branch 'bpf-verifier-improvements'
Alexei Starovoitov says: ==================== bpf: verifier improvements A number of bpf verifier improvements from Gianluca. See individual patches for details. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f3a3e24 + 39f19eb commit c22e5c1

File tree

6 files changed

+1131
-104
lines changed

6 files changed

+1131
-104
lines changed

include/linux/bpf.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ enum bpf_arg_type {
6969
/* the following constraints used to prototype bpf_memcmp() and other
7070
* functions that access data on eBPF program stack
7171
*/
72-
ARG_PTR_TO_STACK, /* any pointer to eBPF program stack */
73-
ARG_PTR_TO_RAW_STACK, /* any pointer to eBPF program stack, area does not
74-
* need to be initialized, helper function must fill
75-
* all bytes or clear them in error case.
72+
ARG_PTR_TO_MEM, /* pointer to valid memory (stack, packet, map value) */
73+
ARG_PTR_TO_UNINIT_MEM, /* pointer to memory does not need to be initialized,
74+
* helper function must fill all bytes or clear
75+
* them in error case.
7676
*/
7777

78-
ARG_CONST_STACK_SIZE, /* number of bytes accessed from stack */
79-
ARG_CONST_STACK_SIZE_OR_ZERO, /* number of bytes accessed from stack or 0 */
78+
ARG_CONST_SIZE, /* number of bytes accessed from memory */
79+
ARG_CONST_SIZE_OR_ZERO, /* number of bytes accessed from memory or 0 */
8080

8181
ARG_PTR_TO_CTX, /* pointer to context */
8282
ARG_ANYTHING, /* any (initialized) argument is ok */

kernel/bpf/helpers.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,6 @@ const struct bpf_func_proto bpf_get_current_comm_proto = {
176176
.func = bpf_get_current_comm,
177177
.gpl_only = false,
178178
.ret_type = RET_INTEGER,
179-
.arg1_type = ARG_PTR_TO_RAW_STACK,
180-
.arg2_type = ARG_CONST_STACK_SIZE,
179+
.arg1_type = ARG_PTR_TO_UNINIT_MEM,
180+
.arg2_type = ARG_CONST_SIZE,
181181
};

kernel/bpf/verifier.c

Lines changed: 146 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,13 @@ static void reset_reg_range_values(struct bpf_reg_state *regs, u32 regno)
481481
regs[regno].max_value = BPF_REGISTER_MAX_RANGE;
482482
}
483483

484+
static void mark_reg_unknown_value_and_range(struct bpf_reg_state *regs,
485+
u32 regno)
486+
{
487+
mark_reg_unknown_value(regs, regno);
488+
reset_reg_range_values(regs, regno);
489+
}
490+
484491
enum reg_arg_type {
485492
SRC_OP, /* register is used as source operand */
486493
DST_OP, /* register is used as destination operand */
@@ -532,6 +539,7 @@ static bool is_spillable_regtype(enum bpf_reg_type type)
532539
switch (type) {
533540
case PTR_TO_MAP_VALUE:
534541
case PTR_TO_MAP_VALUE_OR_NULL:
542+
case PTR_TO_MAP_VALUE_ADJ:
535543
case PTR_TO_STACK:
536544
case PTR_TO_CTX:
537545
case PTR_TO_PACKET:
@@ -616,7 +624,8 @@ static int check_stack_read(struct bpf_verifier_state *state, int off, int size,
616624
}
617625
if (value_regno >= 0)
618626
/* have read misc data from the stack */
619-
mark_reg_unknown_value(state->regs, value_regno);
627+
mark_reg_unknown_value_and_range(state->regs,
628+
value_regno);
620629
return 0;
621630
}
622631
}
@@ -627,14 +636,59 @@ static int check_map_access(struct bpf_verifier_env *env, u32 regno, int off,
627636
{
628637
struct bpf_map *map = env->cur_state.regs[regno].map_ptr;
629638

630-
if (off < 0 || off + size > map->value_size) {
639+
if (off < 0 || size <= 0 || off + size > map->value_size) {
631640
verbose("invalid access to map value, value_size=%d off=%d size=%d\n",
632641
map->value_size, off, size);
633642
return -EACCES;
634643
}
635644
return 0;
636645
}
637646

647+
/* check read/write into an adjusted map element */
648+
static int check_map_access_adj(struct bpf_verifier_env *env, u32 regno,
649+
int off, int size)
650+
{
651+
struct bpf_verifier_state *state = &env->cur_state;
652+
struct bpf_reg_state *reg = &state->regs[regno];
653+
int err;
654+
655+
/* We adjusted the register to this map value, so we
656+
* need to change off and size to min_value and max_value
657+
* respectively to make sure our theoretical access will be
658+
* safe.
659+
*/
660+
if (log_level)
661+
print_verifier_state(state);
662+
env->varlen_map_value_access = true;
663+
/* The minimum value is only important with signed
664+
* comparisons where we can't assume the floor of a
665+
* value is 0. If we are using signed variables for our
666+
* index'es we need to make sure that whatever we use
667+
* will have a set floor within our range.
668+
*/
669+
if (reg->min_value < 0) {
670+
verbose("R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n",
671+
regno);
672+
return -EACCES;
673+
}
674+
err = check_map_access(env, regno, reg->min_value + off, size);
675+
if (err) {
676+
verbose("R%d min value is outside of the array range\n",
677+
regno);
678+
return err;
679+
}
680+
681+
/* If we haven't set a max value then we need to bail
682+
* since we can't be sure we won't do bad things.
683+
*/
684+
if (reg->max_value == BPF_REGISTER_MAX_RANGE) {
685+
verbose("R%d unbounded memory access, make sure to bounds check any array access into a map\n",
686+
regno);
687+
return -EACCES;
688+
}
689+
return check_map_access(env, regno, reg->max_value + off, size);
690+
}
691+
638692
#define MAX_PACKET_OFF 0xffff
639693

640694
static bool may_access_direct_pkt_data(struct bpf_verifier_env *env,
@@ -775,47 +829,13 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off,
775829
return -EACCES;
776830
}
777831

778-
/* If we adjusted the register to this map value at all then we
779-
* need to change off and size to min_value and max_value
780-
* respectively to make sure our theoretical access will be
781-
* safe.
782-
*/
783-
if (reg->type == PTR_TO_MAP_VALUE_ADJ) {
784-
if (log_level)
785-
print_verifier_state(state);
786-
env->varlen_map_value_access = true;
787-
/* The minimum value is only important with signed
788-
* comparisons where we can't assume the floor of a
789-
* value is 0. If we are using signed variables for our
790-
* index'es we need to make sure that whatever we use
791-
* will have a set floor within our range.
792-
*/
793-
if (reg->min_value < 0) {
794-
verbose("R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n",
795-
regno);
796-
return -EACCES;
797-
}
798-
err = check_map_access(env, regno, reg->min_value + off,
799-
size);
800-
if (err) {
801-
verbose("R%d min value is outside of the array range\n",
802-
regno);
803-
return err;
804-
}
805-
806-
/* If we haven't set a max value then we need to bail
807-
* since we can't be sure we won't do bad things.
808-
*/
809-
if (reg->max_value == BPF_REGISTER_MAX_RANGE) {
810-
verbose("R%d unbounded memory access, make sure to bounds check any array access into a map\n",
811-
regno);
812-
return -EACCES;
813-
}
814-
off += reg->max_value;
815-
}
816-
err = check_map_access(env, regno, off, size);
832+
if (reg->type == PTR_TO_MAP_VALUE_ADJ)
833+
err = check_map_access_adj(env, regno, off, size);
834+
else
835+
err = check_map_access(env, regno, off, size);
817836
if (!err && t == BPF_READ && value_regno >= 0)
818-
mark_reg_unknown_value(state->regs, value_regno);
837+
mark_reg_unknown_value_and_range(state->regs,
838+
value_regno);
819839

820840
} else if (reg->type == PTR_TO_CTX) {
821841
enum bpf_reg_type reg_type = UNKNOWN_VALUE;
@@ -827,7 +847,8 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off,
827847
}
828848
err = check_ctx_access(env, off, size, t, &reg_type);
829849
if (!err && t == BPF_READ && value_regno >= 0) {
830-
mark_reg_unknown_value(state->regs, value_regno);
850+
mark_reg_unknown_value_and_range(state->regs,
851+
value_regno);
831852
/* note that reg.[id|off|range] == 0 */
832853
state->regs[value_regno].type = reg_type;
833854
}
@@ -860,7 +881,8 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off,
860881
}
861882
err = check_packet_access(env, regno, off, size);
862883
if (!err && t == BPF_READ && value_regno >= 0)
863-
mark_reg_unknown_value(state->regs, value_regno);
884+
mark_reg_unknown_value_and_range(state->regs,
885+
value_regno);
864886
} else {
865887
verbose("R%d invalid mem access '%s'\n",
866888
regno, reg_type_str[reg->type]);
@@ -958,6 +980,25 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno,
958980
return 0;
959981
}
960982

983+
static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
984+
int access_size, bool zero_size_allowed,
985+
struct bpf_call_arg_meta *meta)
986+
{
987+
struct bpf_reg_state *regs = env->cur_state.regs;
988+
989+
switch (regs[regno].type) {
990+
case PTR_TO_PACKET:
991+
return check_packet_access(env, regno, 0, access_size);
992+
case PTR_TO_MAP_VALUE:
993+
return check_map_access(env, regno, 0, access_size);
994+
case PTR_TO_MAP_VALUE_ADJ:
995+
return check_map_access_adj(env, regno, 0, access_size);
996+
default: /* const_imm|ptr_to_stack or invalid ptr */
997+
return check_stack_boundary(env, regno, access_size,
998+
zero_size_allowed, meta);
999+
}
1000+
}
1001+
9611002
static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
9621003
enum bpf_arg_type arg_type,
9631004
struct bpf_call_arg_meta *meta)
@@ -993,10 +1034,13 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
9931034
expected_type = PTR_TO_STACK;
9941035
if (type != PTR_TO_PACKET && type != expected_type)
9951036
goto err_type;
996-
} else if (arg_type == ARG_CONST_STACK_SIZE ||
997-
arg_type == ARG_CONST_STACK_SIZE_OR_ZERO) {
1037+
} else if (arg_type == ARG_CONST_SIZE ||
1038+
arg_type == ARG_CONST_SIZE_OR_ZERO) {
9981039
expected_type = CONST_IMM;
999-
if (type != expected_type)
1040+
/* One exception. Allow UNKNOWN_VALUE registers when the
1041+
* boundaries are known and don't cause unsafe memory accesses
1042+
*/
1043+
if (type != UNKNOWN_VALUE && type != expected_type)
10001044
goto err_type;
10011045
} else if (arg_type == ARG_CONST_MAP_PTR) {
10021046
expected_type = CONST_PTR_TO_MAP;
@@ -1006,18 +1050,19 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
10061050
expected_type = PTR_TO_CTX;
10071051
if (type != expected_type)
10081052
goto err_type;
1009-
} else if (arg_type == ARG_PTR_TO_STACK ||
1010-
arg_type == ARG_PTR_TO_RAW_STACK) {
1053+
} else if (arg_type == ARG_PTR_TO_MEM ||
1054+
arg_type == ARG_PTR_TO_UNINIT_MEM) {
10111055
expected_type = PTR_TO_STACK;
10121056
/* One exception here. In case function allows for NULL to be
10131057
* passed in as argument, it's a CONST_IMM type. Final test
10141058
* happens during stack boundary checking.
10151059
*/
10161060
if (type == CONST_IMM && reg->imm == 0)
10171061
/* final test in check_stack_boundary() */;
1018-
else if (type != PTR_TO_PACKET && type != expected_type)
1062+
else if (type != PTR_TO_PACKET && type != PTR_TO_MAP_VALUE &&
1063+
type != PTR_TO_MAP_VALUE_ADJ && type != expected_type)
10191064
goto err_type;
1020-
meta->raw_mode = arg_type == ARG_PTR_TO_RAW_STACK;
1065+
meta->raw_mode = arg_type == ARG_PTR_TO_UNINIT_MEM;
10211066
} else {
10221067
verbose("unsupported arg_type %d\n", arg_type);
10231068
return -EFAULT;
@@ -1063,24 +1108,60 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
10631108
err = check_stack_boundary(env, regno,
10641109
meta->map_ptr->value_size,
10651110
false, NULL);
1066-
} else if (arg_type == ARG_CONST_STACK_SIZE ||
1067-
arg_type == ARG_CONST_STACK_SIZE_OR_ZERO) {
1068-
bool zero_size_allowed = (arg_type == ARG_CONST_STACK_SIZE_OR_ZERO);
1111+
} else if (arg_type == ARG_CONST_SIZE ||
1112+
arg_type == ARG_CONST_SIZE_OR_ZERO) {
1113+
bool zero_size_allowed = (arg_type == ARG_CONST_SIZE_OR_ZERO);
10691114

10701115
/* bpf_xxx(..., buf, len) call will access 'len' bytes
10711116
* from stack pointer 'buf'. Check it
10721117
* note: regno == len, regno - 1 == buf
10731118
*/
10741119
if (regno == 0) {
10751120
/* kernel subsystem misconfigured verifier */
1076-
verbose("ARG_CONST_STACK_SIZE cannot be first argument\n");
1121+
verbose("ARG_CONST_SIZE cannot be first argument\n");
10771122
return -EACCES;
10781123
}
1079-
if (regs[regno - 1].type == PTR_TO_PACKET)
1080-
err = check_packet_access(env, regno - 1, 0, reg->imm);
1081-
else
1082-
err = check_stack_boundary(env, regno - 1, reg->imm,
1083-
zero_size_allowed, meta);
1124+
1125+
/* If the register is UNKNOWN_VALUE, the access check happens
1126+
* using its boundaries. Otherwise, just use its imm
1127+
*/
1128+
if (type == UNKNOWN_VALUE) {
1129+
/* For unprivileged variable accesses, disable raw
1130+
* mode so that the program is required to
1131+
* initialize all the memory that the helper could
1132+
* just partially fill up.
1133+
*/
1134+
meta = NULL;
1135+
1136+
if (reg->min_value < 0) {
1137+
verbose("R%d min value is negative, either use unsigned or 'var &= const'\n",
1138+
regno);
1139+
return -EACCES;
1140+
}
1141+
1142+
if (reg->min_value == 0) {
1143+
err = check_helper_mem_access(env, regno - 1, 0,
1144+
zero_size_allowed,
1145+
meta);
1146+
if (err)
1147+
return err;
1148+
}
1149+
1150+
if (reg->max_value == BPF_REGISTER_MAX_RANGE) {
1151+
verbose("R%d unbounded memory access, use 'var &= const' or 'if (var < const)'\n",
1152+
regno);
1153+
return -EACCES;
1154+
}
1155+
err = check_helper_mem_access(env, regno - 1,
1156+
reg->max_value,
1157+
zero_size_allowed, meta);
1158+
if (err)
1159+
return err;
1160+
} else {
1161+
/* register is CONST_IMM */
1162+
err = check_helper_mem_access(env, regno - 1, reg->imm,
1163+
zero_size_allowed, meta);
1164+
}
10841165
}
10851166

10861167
return err;
@@ -1154,15 +1235,15 @@ static int check_raw_mode(const struct bpf_func_proto *fn)
11541235
{
11551236
int count = 0;
11561237

1157-
if (fn->arg1_type == ARG_PTR_TO_RAW_STACK)
1238+
if (fn->arg1_type == ARG_PTR_TO_UNINIT_MEM)
11581239
count++;
1159-
if (fn->arg2_type == ARG_PTR_TO_RAW_STACK)
1240+
if (fn->arg2_type == ARG_PTR_TO_UNINIT_MEM)
11601241
count++;
1161-
if (fn->arg3_type == ARG_PTR_TO_RAW_STACK)
1242+
if (fn->arg3_type == ARG_PTR_TO_UNINIT_MEM)
11621243
count++;
1163-
if (fn->arg4_type == ARG_PTR_TO_RAW_STACK)
1244+
if (fn->arg4_type == ARG_PTR_TO_UNINIT_MEM)
11641245
count++;
1165-
if (fn->arg5_type == ARG_PTR_TO_RAW_STACK)
1246+
if (fn->arg5_type == ARG_PTR_TO_UNINIT_MEM)
11661247
count++;
11671248

11681249
return count > 1 ? -EINVAL : 0;
@@ -2729,7 +2810,6 @@ static int do_check(struct bpf_verifier_env *env)
27292810
if (err)
27302811
return err;
27312812

2732-
reset_reg_range_values(regs, insn->dst_reg);
27332813
if (BPF_SIZE(insn->code) != BPF_W &&
27342814
BPF_SIZE(insn->code) != BPF_DW) {
27352815
insn_idx++;

0 commit comments

Comments
 (0)