@@ -1356,6 +1356,13 @@ static bool is_ctx_reg(struct bpf_verifier_env *env, int regno)
1356
1356
return reg -> type == PTR_TO_CTX ;
1357
1357
}
1358
1358
1359
+ static bool is_pkt_reg (struct bpf_verifier_env * env , int regno )
1360
+ {
1361
+ const struct bpf_reg_state * reg = cur_regs (env ) + regno ;
1362
+
1363
+ return type_is_pkt_pointer (reg -> type );
1364
+ }
1365
+
1359
1366
static int check_pkt_ptr_alignment (struct bpf_verifier_env * env ,
1360
1367
const struct bpf_reg_state * reg ,
1361
1368
int off , int size , bool strict )
@@ -1416,10 +1423,10 @@ static int check_generic_ptr_alignment(struct bpf_verifier_env *env,
1416
1423
}
1417
1424
1418
1425
static int check_ptr_alignment (struct bpf_verifier_env * env ,
1419
- const struct bpf_reg_state * reg ,
1420
- int off , int size )
1426
+ const struct bpf_reg_state * reg , int off ,
1427
+ int size , bool strict_alignment_once )
1421
1428
{
1422
- bool strict = env -> strict_alignment ;
1429
+ bool strict = env -> strict_alignment || strict_alignment_once ;
1423
1430
const char * pointer_desc = "" ;
1424
1431
1425
1432
switch (reg -> type ) {
@@ -1576,9 +1583,9 @@ static void coerce_reg_to_size(struct bpf_reg_state *reg, int size)
1576
1583
* if t==write && value_regno==-1, some unknown value is stored into memory
1577
1584
* if t==read && value_regno==-1, don't care what we read from memory
1578
1585
*/
1579
- static int check_mem_access (struct bpf_verifier_env * env , int insn_idx , u32 regno , int off ,
1580
- int bpf_size , enum bpf_access_type t ,
1581
- int value_regno )
1586
+ static int check_mem_access (struct bpf_verifier_env * env , int insn_idx , u32 regno ,
1587
+ int off , int bpf_size , enum bpf_access_type t ,
1588
+ int value_regno , bool strict_alignment_once )
1582
1589
{
1583
1590
struct bpf_reg_state * regs = cur_regs (env );
1584
1591
struct bpf_reg_state * reg = regs + regno ;
@@ -1590,7 +1597,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
1590
1597
return size ;
1591
1598
1592
1599
/* alignment checks will add in reg->off themselves */
1593
- err = check_ptr_alignment (env , reg , off , size );
1600
+ err = check_ptr_alignment (env , reg , off , size , strict_alignment_once );
1594
1601
if (err )
1595
1602
return err ;
1596
1603
@@ -1735,21 +1742,23 @@ static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_ins
1735
1742
return - EACCES ;
1736
1743
}
1737
1744
1738
- if (is_ctx_reg (env , insn -> dst_reg )) {
1739
- verbose (env , "BPF_XADD stores into R%d context is not allowed\n" ,
1740
- insn -> dst_reg );
1745
+ if (is_ctx_reg (env , insn -> dst_reg ) ||
1746
+ is_pkt_reg (env , insn -> dst_reg )) {
1747
+ verbose (env , "BPF_XADD stores into R%d %s is not allowed\n" ,
1748
+ insn -> dst_reg , is_ctx_reg (env , insn -> dst_reg ) ?
1749
+ "context" : "packet" );
1741
1750
return - EACCES ;
1742
1751
}
1743
1752
1744
1753
/* check whether atomic_add can read the memory */
1745
1754
err = check_mem_access (env , insn_idx , insn -> dst_reg , insn -> off ,
1746
- BPF_SIZE (insn -> code ), BPF_READ , -1 );
1755
+ BPF_SIZE (insn -> code ), BPF_READ , -1 , true );
1747
1756
if (err )
1748
1757
return err ;
1749
1758
1750
1759
/* check whether atomic_add can write into the same memory */
1751
1760
return check_mem_access (env , insn_idx , insn -> dst_reg , insn -> off ,
1752
- BPF_SIZE (insn -> code ), BPF_WRITE , -1 );
1761
+ BPF_SIZE (insn -> code ), BPF_WRITE , -1 , true );
1753
1762
}
1754
1763
1755
1764
/* when register 'regno' is passed into function that will read 'access_size'
@@ -2388,7 +2397,8 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
2388
2397
* is inferred from register state.
2389
2398
*/
2390
2399
for (i = 0 ; i < meta .access_size ; i ++ ) {
2391
- err = check_mem_access (env , insn_idx , meta .regno , i , BPF_B , BPF_WRITE , -1 );
2400
+ err = check_mem_access (env , insn_idx , meta .regno , i , BPF_B ,
2401
+ BPF_WRITE , -1 , false);
2392
2402
if (err )
2393
2403
return err ;
2394
2404
}
@@ -4632,7 +4642,7 @@ static int do_check(struct bpf_verifier_env *env)
4632
4642
*/
4633
4643
err = check_mem_access (env , insn_idx , insn -> src_reg , insn -> off ,
4634
4644
BPF_SIZE (insn -> code ), BPF_READ ,
4635
- insn -> dst_reg );
4645
+ insn -> dst_reg , false );
4636
4646
if (err )
4637
4647
return err ;
4638
4648
@@ -4684,7 +4694,7 @@ static int do_check(struct bpf_verifier_env *env)
4684
4694
/* check that memory (dst_reg + off) is writeable */
4685
4695
err = check_mem_access (env , insn_idx , insn -> dst_reg , insn -> off ,
4686
4696
BPF_SIZE (insn -> code ), BPF_WRITE ,
4687
- insn -> src_reg );
4697
+ insn -> src_reg , false );
4688
4698
if (err )
4689
4699
return err ;
4690
4700
@@ -4719,7 +4729,7 @@ static int do_check(struct bpf_verifier_env *env)
4719
4729
/* check that memory (dst_reg + off) is writeable */
4720
4730
err = check_mem_access (env , insn_idx , insn -> dst_reg , insn -> off ,
4721
4731
BPF_SIZE (insn -> code ), BPF_WRITE ,
4722
- -1 );
4732
+ -1 , false );
4723
4733
if (err )
4724
4734
return err ;
4725
4735
0 commit comments