You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This means that perfEventHeader->Size has a small number due to integer overflow. And perfEventSample->Size has a >64kB number.
Unfortunately, cilium/ebpf does not notice the inconsistency and I get errors such as:
Error reading perf ring buffer: read sample: unexpected EOF
How to reproduce
Generate a large UDP packet:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>intmain() {
intmax_packet_size=65507;
intsockfd;
structsockaddr_inservaddr;
if (getenv("max_packet_size") !=NULL) {
max_packet_size=atoi(getenv("max_packet_size"));
}
// Create a UDP socketif ((sockfd=socket(AF_INET, SOCK_DGRAM, 0)) <0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Fill server informationservaddr.sin_family=AF_INET;
servaddr.sin_port=htons(5353); // Change the port number as neededservaddr.sin_addr.s_addr=inet_addr("127.0.0.1"); // Change the IP address as needed// Create a large buffer to hold the packet datachar*buffer= (char*)malloc(max_packet_size);
if (buffer==NULL) {
perror("malloc failed");
exit(EXIT_FAILURE);
}
memset(buffer, 'A', max_packet_size-1);
buffer[max_packet_size-1] ='\0';
// Send the UDP packetintn=sendto(sockfd, buffer, max_packet_size,
MSG_CONFIRM, (conststructsockaddr*)&servaddr,
sizeof(servaddr));
if (n<0) {
perror("sendto failed");
exit(EXIT_FAILURE);
}
free(buffer);
close(sockfd);
return0;
}
Attach a socket filter using cilium/ebpf and read from the perf ring buffer:
Describe the bug
Perf events of type PERF_RECORD_SAMPLE contains a header with the 16-bit size, read in readRecord:
It is followed by another 32-bit size field, read in readRawSample:
Unfortunately, it is possible for a bpf program to submit a record larger than 64kB by appending a small event with a 65507-byte UDP packet:
The kernel calculates the header size in perf_sample_data_size. This returns a u32. Then, it just casts it in the u16 field in perf_prepare_header. See also bpf_event_output and perf_sample_save_raw_data.
This means that
perfEventHeader->Size
has a small number due to integer overflow. AndperfEventSample->Size
has a >64kB number.Unfortunately, cilium/ebpf does not notice the inconsistency and I get errors such as:
How to reproduce
Generate a large UDP packet:
Attach a socket filter using cilium/ebpf and read from the perf ring buffer:
Version information
github.com/cilium/ebpf v0.16.0 => github.com/cilium/ebpf v0.16.1-0.20241023154409-d3c63ab2edcb
The text was updated successfully, but these errors were encountered: