Skip to content

Commit d8e294b

Browse files
Jakub Kicinskigregkh
authored andcommitted
bpf: fix method of PTR_TO_PACKET reg id generation
[ Upstream commit 1f415a7 ] Using per-register incrementing ID can lead to find_good_pkt_pointers() confusing registers which have completely different values. Consider example: 0: (bf) r6 = r1 1: (61) r8 = *(u32 *)(r6 +76) 2: (61) r0 = *(u32 *)(r6 +80) 3: (bf) r7 = r8 4: (07) r8 += 32 5: (2d) if r8 > r0 goto pc+9 R0=pkt_end R1=ctx R6=ctx R7=pkt(id=0,off=0,r=32) R8=pkt(id=0,off=32,r=32) R10=fp 6: (bf) r8 = r7 7: (bf) r9 = r7 8: (71) r1 = *(u8 *)(r7 +0) 9: (0f) r8 += r1 10: (71) r1 = *(u8 *)(r7 +1) 11: (0f) r9 += r1 12: (07) r8 += 32 13: (2d) if r8 > r0 goto pc+1 R0=pkt_end R1=inv56 R6=ctx R7=pkt(id=0,off=0,r=32) R8=pkt(id=1,off=32,r=32) R9=pkt(id=1,off=0,r=32) R10=fp 14: (71) r1 = *(u8 *)(r9 +16) 15: (b7) r7 = 0 16: (bf) r0 = r7 17: (95) exit We need to get a UNKNOWN_VALUE with imm to force id generation so lines 0-5 make r7 a valid packet pointer. We then read two different bytes from the packet and add them to copies of the constructed packet pointer. r8 (line 9) and r9 (line 11) will get the same id of 1, independently. When either of them is validated (line 13) - find_good_pkt_pointers() will also mark the other as safe. This leads to access on line 14 being mistakenly considered safe. Fixes: 969bf05 ("bpf: direct packet access") Signed-off-by: Jakub Kicinski <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Acked-by: Daniel Borkmann <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b8509ce commit d8e294b

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

kernel/bpf/verifier.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ struct verifier_env {
194194
struct verifier_state_list **explored_states; /* search pruning optimization */
195195
struct bpf_map *used_maps[MAX_USED_MAPS]; /* array of map's used by eBPF program */
196196
u32 used_map_cnt; /* number of used maps */
197+
u32 id_gen; /* used to generate unique reg IDs */
197198
bool allow_ptr_leaks;
198199
};
199200

@@ -1277,7 +1278,7 @@ static int check_packet_ptr_add(struct verifier_env *env, struct bpf_insn *insn)
12771278
/* dst_reg stays as pkt_ptr type and since some positive
12781279
* integer value was added to the pointer, increment its 'id'
12791280
*/
1280-
dst_reg->id++;
1281+
dst_reg->id = ++env->id_gen;
12811282

12821283
/* something was added to pkt_ptr, set range and off to zero */
12831284
dst_reg->off = 0;

0 commit comments

Comments
 (0)