iovisor / iovisor/bcc

Checksum code does not work for LLVM-14, but it works for LLVM-13

Open
#4,612 7 comments 1 reaction 0 assignees View on GitHub
Dominant language
C
Stars
22.7k
Forks
4.1k
Avg merge
10d 4h
Merged PRs (30d)
3

Description

__attribute__((__always_inline__))
static inline __u16 caludpcsum(struct iphdr *iph, struct udphdr *udph, void *data_end)
{
__u32 csum_buffer = 0;
__u16 *buf = (void *)udph;

// Compute pseudo-header checksum
csum_buffer += (__u16)iph->saddr;
csum_buffer += (__u16)(iph->saddr >> 16);
csum_buffer += (__u16)iph->daddr;
csum_buffer += (__u16)(iph->daddr >> 16);
csum_buffer += (__u16)iph->protocol << 8;
csum_buffer += udph->len;

// Compute checksum on udp header + payload
for (int i = 0; i < MAX_UDP_SIZE; i += 2)
{
if ((void *)(buf + 1) > data_end)
{
break;
}

csum_buffer += *buf;
buf++;
}

if ((void *)buf + 1 <= data_end)
{
// In case payload is not 2 bytes aligned
csum_buffer += *(__u8 *)buf;
}

__u16 csum = (__u16)csum_buffer + (__u16)(csum_buffer >> 16);
csum = ~csum;

return csum;
}

The above code does not work for LLVM-14 in ubutun 22.04, but it works for LLVM-13/LLVM-12. I think there is a bug in LLVM-14 with bcc. The error code:

; for (u16 i = 0; i < MAX_UDP_SIZE; i += 2) {
43: (2d) if r7 > r6 goto pc+158 ; R6=pkt_end(off=0,imm=0) R7=pkt(off=36,r=42,imm=0)
44: (bf) r9 = r6 ; R6=pkt_end(off=0,imm=0) R9_w=pkt_end(off=0,imm=0)
45: (1f) r9 -= r8 ; R8=pkt(off=0,r=42,imm=0) R9_w=scalar()
46: (07) r9 += -36 ; R9_w=scalar()
47: (77) r9 >>= 1 ; R9_w=scalar(umax=9223372036854775807,var_off=(0x0; 0x7fffffffffffffff))
48: (b7) r1 = 739 ; R1_w=739
49: (2d) if r1 > r9 goto pc+1 ; R1_w=739 R9_w=scalar(umin=739,umax=9223372036854775807,var_off=(0x0; 0x7fffffffffffffff))
50: (b7) r9 = 739 ; R9=739
51: (b7) r5 = 0 ; R5_w=0
52: (b7) r2 = 7 ; R2_w=7
53: (bf) r1 = r7 ; R1_w=pkt(off=36,r=42,imm=0) R7=pkt(off=36,r=42,imm=0)
54: (2d) if r2 > r9 goto pc+134 ; R2_w=P7 R9=P739
55: (7b) *(u64 *)(r10 -128) = r8 ; R8=pkt(off=0,r=42,imm=0) R10=fp0 fp-128_w=pkt
56: (7b) *(u64 *)(r10 -136) = r3 ; R3=pkt(off=34,r=42,imm=0) R10=fp0 fp-136_w=pkt
57: (7b) *(u64 *)(r10 -152) = r6 ; R6=pkt_end(off=0,imm=0) R10=fp0 fp-152_w=pkt_end
58: (79) r1 = *(u64 *)(r10 -96) ; R1_w=scalar(id=1,umax=4294967295,var_off=(0x0; 0xffffffff)) R10=fp0
59: (7b) *(u64 *)(r10 -112) = r7 ; R7=pkt(off=36,r=42,imm=0) R10=fp0 fp-112_w=pkt
60: (07) r9 += 1 ; R9_w=P740
61: (bf) r1 = r9 ; R1_w=P740 R9_w=P740
62: (bf) r8 = r4 ; R4=scalar(id=4,umin=4352,umax=332027,var_off=(0x0; 0x7ffff)) R8_w=scalar(id=4,umin=4352,umax=332027,var_off=(0x0; 0x7ffff))
63: (b7) r9 = 0 ; R9_w=0
64: (7b) *(u64 *)(r10 -160) = r1 ; R1_w=P740 R10=fp0 fp-160_w=P740
65: (57) r1 &= 2040 ; R1_w=P736
66: (7b) *(u64 *)(r10 -104) = r1 ; R1_w=P736 R10=fp0 fp-104_w=P736
67: (07) r1 += -8 ; R1_w=P728
68: (bf) r5 = r1 ; R1_w=P728 R5_w=P728
69: (77) r5 >>= 3 ; R5_w=P91
70: (07) r5 += 1 ; R5_w=P92
71: (bf) r2 = r5 ; R2_w=P92 R5_w=P92
72: (57) r2 &= 1 ; R2_w=P0
73: (7b) *(u64 *)(r10 -168) = r2 ; R2_w=P0 R10=fp0 fp-168_w=00000000
74: (b7) r2 = 0 ; R2_w=0
75: (7b) *(u64 *)(r10 -144) = r2 ; R2_w=P0 R10=fp0 fp-144_w=00000000
76: (b7) r7 = 0 ; R7_w=0
77: (b7) r6 = 0 ; R6_w=0
78: (b7) r4 = 0 ; R4_w=0
79: (b7) r2 = 0 ; R2_w=0
80: (b7) r3 = 0 ; R3_w=0
81: (b7) r0 = 0 ; R0_w=0
82: (15) if r1 == 0x0 goto pc+51 ; R1_w=P728
83: (18) r1 = 0x3ffffffffffffffe ; R1_w=4611686018427387902
85: (5f) r5 &= r1 ; R1_w=P4611686018427387902 R5_w=P92
86: (b7) r4 = 0 ; R4_w=0
87: (79) r1 = *(u64 *)(r10 -128) ; R1_w=pkt(off=0,r=42,imm=0) R10=fp0
88: (07) r1 += 58 ; R1_w=pkt(off=58,r=42,imm=0)
89: (bf) r2 = r5 ; R2_w=P92 R5_w=P92
90: (67) r2 <<= 3 ; R2_w=P736
91: (7b) *(u64 *)(r10 -144) = r2 ; R2_w=P736 R10=fp0 fp-144_w=P736
92: (b7) r7 = 0 ; R7_w=0
93: (b7) r6 = 0 ; R6_w=0
94: (b7) r2 = 0 ; R2_w=0
95: (b7) r3 = 0 ; R3_w=0
96: (b7) r0 = 0 ; R0=0
97: (7b) *(u64 *)(r10 -88) = r5 ; R5=P92 R10=fp0 fp-88_w=P92
; sum += *ip_payload++;
98: (69) r5 = *(u16 *)(r1 -24) ; R1=pkt(off=58,r=42,imm=0) R5_w=scalar(umax=65535,var_off=(0x0; 0xffff))
; sum += *ip_payload++;
99: (0f) r8 += r5 ; R5_w=scalar(umax=65535,var_off=(0x0; 0xffff)) R8_w=scalar(umin=4352,umax=397562,var_off=(0x0; 0x7ffff))
; sum += *ip_payload++;
100: (69) r5 = *(u16 *)(r1 -16)
invalid access to packet, off=42 size=2, R1(id=0,off=42,r=42)
R1 offset is outside of the packet
processed 100 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 2

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the caludpcsum function and the LLVM-14 verifier log in the issue, then compare its generated instructions with LLVM-12/13 behavior on Ubuntu 22.04. Reproduce the packet-access rejection and determine whether the result is a BCC, LLVM, or verifier interaction; done requires a confirmed cause and a tested fix or minimal reproducer.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux
Domain
networking, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.