@@ -80,8 +80,8 @@ static const struct bpf_verifier_ops * const bpf_verifier_ops[] = {
80
80
* (like pointer plus pointer becomes SCALAR_VALUE type)
81
81
*
82
82
* When verifier sees load or store instructions the type of base register
83
- * can be: PTR_TO_MAP_VALUE, PTR_TO_CTX, PTR_TO_STACK. These are three pointer
84
- * types recognized by check_mem_access() function.
83
+ * can be: PTR_TO_MAP_VALUE, PTR_TO_CTX, PTR_TO_STACK, PTR_TO_SOCKET . These are
84
+ * four pointer types recognized by check_mem_access() function.
85
85
*
86
86
* PTR_TO_MAP_VALUE means that this register is pointing to 'map element value'
87
87
* and the range of [ptr, ptr + map's value_size) is accessible.
@@ -267,6 +267,8 @@ static const char * const reg_type_str[] = {
267
267
[PTR_TO_PACKET_META ] = "pkt_meta" ,
268
268
[PTR_TO_PACKET_END ] = "pkt_end" ,
269
269
[PTR_TO_FLOW_KEYS ] = "flow_keys" ,
270
+ [PTR_TO_SOCKET ] = "sock" ,
271
+ [PTR_TO_SOCKET_OR_NULL ] = "sock_or_null" ,
270
272
};
271
273
272
274
static char slot_type_char [] = {
@@ -973,6 +975,8 @@ static bool is_spillable_regtype(enum bpf_reg_type type)
973
975
case PTR_TO_PACKET_END :
974
976
case PTR_TO_FLOW_KEYS :
975
977
case CONST_PTR_TO_MAP :
978
+ case PTR_TO_SOCKET :
979
+ case PTR_TO_SOCKET_OR_NULL :
976
980
return true;
977
981
default :
978
982
return false;
@@ -1341,6 +1345,28 @@ static int check_flow_keys_access(struct bpf_verifier_env *env, int off,
1341
1345
return 0 ;
1342
1346
}
1343
1347
1348
+ static int check_sock_access (struct bpf_verifier_env * env , u32 regno , int off ,
1349
+ int size , enum bpf_access_type t )
1350
+ {
1351
+ struct bpf_reg_state * regs = cur_regs (env );
1352
+ struct bpf_reg_state * reg = & regs [regno ];
1353
+ struct bpf_insn_access_aux info ;
1354
+
1355
+ if (reg -> smin_value < 0 ) {
1356
+ verbose (env , "R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n" ,
1357
+ regno );
1358
+ return - EACCES ;
1359
+ }
1360
+
1361
+ if (!bpf_sock_is_valid_access (off , size , t , & info )) {
1362
+ verbose (env , "invalid bpf_sock access off=%d size=%d\n" ,
1363
+ off , size );
1364
+ return - EACCES ;
1365
+ }
1366
+
1367
+ return 0 ;
1368
+ }
1369
+
1344
1370
static bool __is_pointer_value (bool allow_ptr_leaks ,
1345
1371
const struct bpf_reg_state * reg )
1346
1372
{
@@ -1459,6 +1485,9 @@ static int check_ptr_alignment(struct bpf_verifier_env *env,
1459
1485
*/
1460
1486
strict = true;
1461
1487
break ;
1488
+ case PTR_TO_SOCKET :
1489
+ pointer_desc = "sock " ;
1490
+ break ;
1462
1491
default :
1463
1492
break ;
1464
1493
}
@@ -1726,6 +1755,14 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
1726
1755
err = check_flow_keys_access (env , off , size );
1727
1756
if (!err && t == BPF_READ && value_regno >= 0 )
1728
1757
mark_reg_unknown (env , regs , value_regno );
1758
+ } else if (reg -> type == PTR_TO_SOCKET ) {
1759
+ if (t == BPF_WRITE ) {
1760
+ verbose (env , "cannot write into socket\n" );
1761
+ return - EACCES ;
1762
+ }
1763
+ err = check_sock_access (env , regno , off , size , t );
1764
+ if (!err && value_regno >= 0 )
1765
+ mark_reg_unknown (env , regs , value_regno );
1729
1766
} else {
1730
1767
verbose (env , "R%d invalid mem access '%s'\n" , regno ,
1731
1768
reg_type_str [reg -> type ]);
@@ -1948,6 +1985,10 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
1948
1985
err = check_ctx_reg (env , reg , regno );
1949
1986
if (err < 0 )
1950
1987
return err ;
1988
+ } else if (arg_type == ARG_PTR_TO_SOCKET ) {
1989
+ expected_type = PTR_TO_SOCKET ;
1990
+ if (type != expected_type )
1991
+ goto err_type ;
1951
1992
} else if (arg_type_is_mem_ptr (arg_type )) {
1952
1993
expected_type = PTR_TO_STACK ;
1953
1994
/* One exception here. In case function allows for NULL to be
@@ -2543,6 +2584,10 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
2543
2584
}
2544
2585
regs [BPF_REG_0 ].map_ptr = meta .map_ptr ;
2545
2586
regs [BPF_REG_0 ].id = ++ env -> id_gen ;
2587
+ } else if (fn -> ret_type == RET_PTR_TO_SOCKET_OR_NULL ) {
2588
+ mark_reg_known_zero (env , regs , BPF_REG_0 );
2589
+ regs [BPF_REG_0 ].type = PTR_TO_SOCKET_OR_NULL ;
2590
+ regs [BPF_REG_0 ].id = ++ env -> id_gen ;
2546
2591
} else {
2547
2592
verbose (env , "unknown return type %d of func %s#%d\n" ,
2548
2593
fn -> ret_type , func_id_name (func_id ), func_id );
@@ -2680,6 +2725,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
2680
2725
return - EACCES ;
2681
2726
case CONST_PTR_TO_MAP :
2682
2727
case PTR_TO_PACKET_END :
2728
+ case PTR_TO_SOCKET :
2729
+ case PTR_TO_SOCKET_OR_NULL :
2683
2730
verbose (env , "R%d pointer arithmetic on %s prohibited\n" ,
2684
2731
dst , reg_type_str [ptr_reg -> type ]);
2685
2732
return - EACCES ;
@@ -3627,6 +3674,8 @@ static void mark_ptr_or_null_reg(struct bpf_reg_state *reg, u32 id,
3627
3674
} else {
3628
3675
reg -> type = PTR_TO_MAP_VALUE ;
3629
3676
}
3677
+ } else if (reg -> type == PTR_TO_SOCKET_OR_NULL ) {
3678
+ reg -> type = PTR_TO_SOCKET ;
3630
3679
}
3631
3680
/* We don't need id from this point onwards anymore, thus we
3632
3681
* should better reset it, so that state pruning has chances
@@ -4402,6 +4451,8 @@ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur,
4402
4451
case CONST_PTR_TO_MAP :
4403
4452
case PTR_TO_PACKET_END :
4404
4453
case PTR_TO_FLOW_KEYS :
4454
+ case PTR_TO_SOCKET :
4455
+ case PTR_TO_SOCKET_OR_NULL :
4405
4456
/* Only valid matches are exact, which memcmp() above
4406
4457
* would have accepted
4407
4458
*/
@@ -4679,6 +4730,37 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
4679
4730
return 0 ;
4680
4731
}
4681
4732
4733
+ /* Return true if it's OK to have the same insn return a different type. */
4734
+ static bool reg_type_mismatch_ok (enum bpf_reg_type type )
4735
+ {
4736
+ switch (type ) {
4737
+ case PTR_TO_CTX :
4738
+ case PTR_TO_SOCKET :
4739
+ case PTR_TO_SOCKET_OR_NULL :
4740
+ return false;
4741
+ default :
4742
+ return true;
4743
+ }
4744
+ }
4745
+
4746
+ /* If an instruction was previously used with particular pointer types, then we
4747
+ * need to be careful to avoid cases such as the below, where it may be ok
4748
+ * for one branch accessing the pointer, but not ok for the other branch:
4749
+ *
4750
+ * R1 = sock_ptr
4751
+ * goto X;
4752
+ * ...
4753
+ * R1 = some_other_valid_ptr;
4754
+ * goto X;
4755
+ * ...
4756
+ * R2 = *(u32 *)(R1 + 0);
4757
+ */
4758
+ static bool reg_type_mismatch (enum bpf_reg_type src , enum bpf_reg_type prev )
4759
+ {
4760
+ return src != prev && (!reg_type_mismatch_ok (src ) ||
4761
+ !reg_type_mismatch_ok (prev ));
4762
+ }
4763
+
4682
4764
static int do_check (struct bpf_verifier_env * env )
4683
4765
{
4684
4766
struct bpf_verifier_state * state ;
@@ -4811,9 +4893,7 @@ static int do_check(struct bpf_verifier_env *env)
4811
4893
*/
4812
4894
* prev_src_type = src_reg_type ;
4813
4895
4814
- } else if (src_reg_type != * prev_src_type &&
4815
- (src_reg_type == PTR_TO_CTX ||
4816
- * prev_src_type == PTR_TO_CTX )) {
4896
+ } else if (reg_type_mismatch (src_reg_type , * prev_src_type )) {
4817
4897
/* ABuser program is trying to use the same insn
4818
4898
* dst_reg = *(u32*) (src_reg + off)
4819
4899
* with different pointer types:
@@ -4858,9 +4938,7 @@ static int do_check(struct bpf_verifier_env *env)
4858
4938
4859
4939
if (* prev_dst_type == NOT_INIT ) {
4860
4940
* prev_dst_type = dst_reg_type ;
4861
- } else if (dst_reg_type != * prev_dst_type &&
4862
- (dst_reg_type == PTR_TO_CTX ||
4863
- * prev_dst_type == PTR_TO_CTX )) {
4941
+ } else if (reg_type_mismatch (dst_reg_type , * prev_dst_type )) {
4864
4942
verbose (env , "same insn cannot be used with different pointers\n" );
4865
4943
return - EINVAL ;
4866
4944
}
@@ -5286,8 +5364,10 @@ static void sanitize_dead_code(struct bpf_verifier_env *env)
5286
5364
}
5287
5365
}
5288
5366
5289
- /* convert load instructions that access fields of 'struct __sk_buff'
5290
- * into sequence of instructions that access fields of 'struct sk_buff'
5367
+ /* convert load instructions that access fields of a context type into a
5368
+ * sequence of instructions that access fields of the underlying structure:
5369
+ * struct __sk_buff -> struct sk_buff
5370
+ * struct bpf_sock_ops -> struct sock
5291
5371
*/
5292
5372
static int convert_ctx_accesses (struct bpf_verifier_env * env )
5293
5373
{
@@ -5316,12 +5396,14 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
5316
5396
}
5317
5397
}
5318
5398
5319
- if (! ops -> convert_ctx_access || bpf_prog_is_dev_bound (env -> prog -> aux ))
5399
+ if (bpf_prog_is_dev_bound (env -> prog -> aux ))
5320
5400
return 0 ;
5321
5401
5322
5402
insn = env -> prog -> insnsi + delta ;
5323
5403
5324
5404
for (i = 0 ; i < insn_cnt ; i ++ , insn ++ ) {
5405
+ bpf_convert_ctx_access_t convert_ctx_access ;
5406
+
5325
5407
if (insn -> code == (BPF_LDX | BPF_MEM | BPF_B ) ||
5326
5408
insn -> code == (BPF_LDX | BPF_MEM | BPF_H ) ||
5327
5409
insn -> code == (BPF_LDX | BPF_MEM | BPF_W ) ||
@@ -5363,8 +5445,18 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
5363
5445
continue ;
5364
5446
}
5365
5447
5366
- if (env -> insn_aux_data [i + delta ].ptr_type != PTR_TO_CTX )
5448
+ switch (env -> insn_aux_data [i + delta ].ptr_type ) {
5449
+ case PTR_TO_CTX :
5450
+ if (!ops -> convert_ctx_access )
5451
+ continue ;
5452
+ convert_ctx_access = ops -> convert_ctx_access ;
5453
+ break ;
5454
+ case PTR_TO_SOCKET :
5455
+ convert_ctx_access = bpf_sock_convert_ctx_access ;
5456
+ break ;
5457
+ default :
5367
5458
continue ;
5459
+ }
5368
5460
5369
5461
ctx_field_size = env -> insn_aux_data [i + delta ].ctx_field_size ;
5370
5462
size = BPF_LDST_BYTES (insn );
@@ -5396,8 +5488,8 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
5396
5488
}
5397
5489
5398
5490
target_size = 0 ;
5399
- cnt = ops -> convert_ctx_access (type , insn , insn_buf , env -> prog ,
5400
- & target_size );
5491
+ cnt = convert_ctx_access (type , insn , insn_buf , env -> prog ,
5492
+ & target_size );
5401
5493
if (cnt == 0 || cnt >= ARRAY_SIZE (insn_buf ) ||
5402
5494
(ctx_field_size && !target_size )) {
5403
5495
verbose (env , "bpf verifier is misconfigured\n" );
0 commit comments