11#ifdef CORE
22 #include "../vmlinux.h"
33 #include <bpf/bpf_core_read.h>
4+
5+ #ifndef ETH_P_IP
6+ #define ETH_P_IP 0x0800
7+ #endif
8+
9+ #ifndef IPPROTO_UDP
10+ #define IPPROTO_UDP 17
11+ #endif
412#else
5- #include <linux/bpf.h>
613 #include <asm/ptrace.h>
14+ #include <linux/bpf.h>
15+ #include <linux/if_ether.h>
16+ #include <linux/in.h>
17+ #include <linux/ip.h>
18+ #include <linux/udp.h>
719#endif
820
921#include <bpf/bpf_helpers.h>
1022#include <bpf/bpf_tracing.h>
23+ #include <bpf/bpf_endian.h>
1124
1225#include "../lemon.h"
1326
@@ -113,32 +126,79 @@ int read_kernel_memory_uprobe(struct pt_regs *ctx)
113126 return read_memory (address , dump_size );
114127}
115128
129+ #define TRIGGER_PACKET_PORT 9999
130+ #define TRIGGER_PACKET_ADDR 0x7f000001 /* 127.0.0.1 */
131+
116132/*
117133 * read_kernel_memory_xdp() - XDP program to trigger a kernel memory read
118134 * @ctx: Pointer to the XDP context containing packet metadata
119135 *
120- * Parses a synthetic packet containing address and size parameters used to
121- * perform a kernel memory read.
136+ * Parses a UDP packet containing address and size parameters used to
137+ * perform a kernel memory read. Expects UDP packets to 127.0.0.1:9999.
122138 */
123139SEC ("xdp" )
124- int read_kernel_memory_xdp (struct xdp_md * ctx ) {
125- int ret ;
126-
127- /* Validate data in fake network packet (needed to bypass eBPF validator )*/
140+ int read_kernel_memory_xdp (struct xdp_md * ctx ) {
128141 void * data = (void * )(long )ctx -> data ;
129142 void * data_end = (void * )(long )ctx -> data_end ;
130- if ((data + sizeof (struct read_mem_args )> data_end )) return XDP_DROP ;
131143
132- /* Extract arguments from fake packet */
133- struct read_mem_args * args = data ;
144+ /* Validate Ethernet header */
145+ struct ethhdr * eth = data ;
146+ if ((void * )(eth + 1 ) > data_end ) {
147+ return XDP_DROP ;
148+ }
149+
150+ /* Check if this is an IP packet */
151+ if (eth -> h_proto != bpf_htons (ETH_P_IP )) {
152+ return XDP_PASS ;
153+ }
154+
155+ /* Validate and parse IP header */
156+ struct iphdr * ip = (struct iphdr * )(eth + 1 );
157+ if ((void * )(ip + 1 ) > data_end ) {
158+ return XDP_DROP ;
159+ }
160+
161+ /* Check if this is a UDP packet */
162+ if (ip -> protocol != IPPROTO_UDP ) {
163+ return XDP_PASS ;
164+ }
165+
166+ /* Check if source/dest is loopback */
167+ if (ip -> saddr != bpf_htonl (TRIGGER_PACKET_ADDR ) || ip -> daddr != bpf_htonl (TRIGGER_PACKET_ADDR )) {
168+ return XDP_PASS ;
169+ }
170+
171+ /* Validate IP header length */
172+ if (ip -> ihl < 5 ) {
173+ return XDP_DROP ;
174+ }
175+
176+ /* Validate UDP header */
177+ struct udphdr * udp = (struct udphdr * )((char * )ip + (ip -> ihl * 4 ));
178+ if ((void * )(udp + 1 ) > data_end ) {
179+ return XDP_DROP ;
180+ }
181+
182+ /* Check destination port */
183+ if (udp -> dest != bpf_htons (TRIGGER_PACKET_PORT )) {
184+ return XDP_PASS ;
185+ }
186+
187+ /* Validate payload */
188+ struct read_mem_args * args = (struct read_mem_args * )(udp + 1 );
189+ if ((void * )(args + 1 ) > data_end ) {
190+ return XDP_DROP ;
191+ }
192+
134193 __u64 address = args -> addr ;
135- __u64 dump_size = args -> size ;
194+ __u64 dump_size = args -> size ;
136195
137196 /* Read memory! */
138- ret = read_memory (address , dump_size );
139- if (ret ) return XDP_DROP ;
197+ if (read_memory (address , dump_size )) {
198+ return XDP_DROP ;
199+ }
140200
141201 return XDP_PASS ;
142202}
143203
144- char _license [] SEC ("license" ) = "GPL" ;
204+ char _license [] SEC ("license" ) = "GPL" ;
0 commit comments