Skip to content

Commit a7bc583

Browse files
committed
ffmuc-ebpf-clat: fix unbounded memory access verifier error on older kernels
1 parent dbeb9a5 commit a7bc583

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

ffmuc-ebpf-clat/src/clat.bpf.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ char _license[] SEC("license") = "GPL";
4949
return TC_ACT_SHOT; \
5050
}
5151

52+
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
53+
5254
/* This is intended to run on WireGuard tunnels, which don't have Ethernet
5355
* headers. */
5456
#define HAS_ETH_HEADER 0
@@ -134,11 +136,17 @@ static int update_icmp_4to6(struct __sk_buff *skb, __u16 offset, struct ipv6hdr
134136
0, 1, 4, 4, 255, 255, 255, 255, 7, 6, 255, 255, 8, 8, 8, 8, 24, 24, 24, 24,
135137
};
136138
__u8 pointer = icmp.un.reserved[0];
137-
if (pointer > 19 || new_ptr[pointer] == 255) {
139+
__u32 new_ptr_len = ARRAY_SIZE(new_ptr);
140+
if (pointer >= new_ptr_len) {
141+
DEBUG_PRINT("Invalid pointer in ICMP parameter problem message");
142+
return TC_ACT_SHOT;
143+
}
144+
__u8 mapped_ptr = new_ptr[pointer];
145+
if (mapped_ptr == 255) {
138146
DEBUG_PRINT("Invalid pointer in ICMP parameter problem message");
139147
return TC_ACT_SHOT;
140148
}
141-
icmp6.icmp6_pointer = bpf_htonl(new_ptr[pointer]);
149+
icmp6.icmp6_pointer = bpf_htonl((__u32)mapped_ptr);
142150
break;
143151
case ICMP_DEST_UNREACH:
144152
icmp6.icmp6_type = ICMPV6_DEST_UNREACH;
@@ -418,11 +426,17 @@ static int update_icmp_6to4(struct __sk_buff *skb, __u16 offset, struct iphdr *i
418426
12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
419427
};
420428
__u32 pointer = bpf_ntohl(icmp6.icmp6_pointer);
421-
if (pointer > 39 || new_ptr[pointer] == 255) {
429+
__u32 new_ptr_len = ARRAY_SIZE(new_ptr);
430+
if (pointer >= new_ptr_len) {
431+
DEBUG_PRINT("Invalid pointer in ICMPv6 parameter problem message");
432+
return TC_ACT_SHOT;
433+
}
434+
__u8 mapped_ptr = new_ptr[pointer];
435+
if (mapped_ptr == 255) {
422436
DEBUG_PRINT("Invalid pointer in ICMPv6 parameter problem message");
423437
return TC_ACT_SHOT;
424438
}
425-
icmp.un.reserved[0] = new_ptr[pointer];
439+
icmp.un.reserved[0] = mapped_ptr;
426440
break;
427441
default:
428442
return TC_ACT_SHOT;

0 commit comments

Comments
 (0)