Payload increased length now being correctly recognized, but still cannot write to it yet.

This commit is contained in:
h3xduck
2021-11-25 06:36:32 -05:00
parent 442f955cf5
commit 253c302695
6 changed files with 641 additions and 421 deletions

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -127,19 +127,19 @@ int xdp_receive(struct xdp_md *ctx)
//We must check bounds again, otherwise the verifier gets angry //We must check bounds again, otherwise the verifier gets angry
data = (void*)(long)ret.ret_md.data; data = (void*)(long)ret.ret_md.data;
data_end = (void*)(long)ret.ret_md.data_end; data_end = (void*)(long)ret.ret_md.data_end;
eth = data; eth = ret.eth;
if(ethernet_header_bound_check(eth, data_end)<0){ if(ethernet_header_bound_check(eth, data_end)<0){
bpf_printk("Bound check A failed while expanding\n"); bpf_printk("Bound check A failed while expanding\n");
return XDP_PASS; return XDP_PASS;
} }
ip = data + sizeof(*eth); ip = ret.ip;
if (ip_header_bound_check(ip, data_end)<0){ if (ip_header_bound_check(ip, data_end)<0){
bpf_printk("Bound check B failed while expanding\n"); bpf_printk("Bound check B failed while expanding\n");
return XDP_PASS; return XDP_PASS;
} }
tcp = (void *)ip + sizeof(*ip); tcp = ret.tcp;
/*if (get_protocol(data_end) != IPPROTO_TCP){ /*if (get_protocol(data_end) != IPPROTO_TCP){
bpf_printk("Bound check C failed while expanding\n"); bpf_printk("Bound check C failed while expanding\n");
return XDP_PASS; return XDP_PASS;
@@ -163,8 +163,11 @@ int xdp_receive(struct xdp_md *ctx)
} }
data_len_next = data_end-data; data_len_next = data_end-data;
bpf_printk("Previous length: %i, current length: %i\n", data_len_prev, data_len_next); bpf_printk("Previous length: %i, current length: %i\n", data_len_prev, data_len_next);
//payload[4] = 'A';
//payload[6] = '\0'; //char payload_to_write[] = "hello";
//__builtin_memcpy(payload, payload_to_write, strlen(payload_to_write));
//payload[5] = '\0';
//payload[1] = 'b'; //payload[1] = 'b';
/*if(!payload){ /*if(!payload){
bpf_probe_read_str(&rb_event->payload, sizeof(rb_event->payload), (void *)payload); bpf_probe_read_str(&rb_event->payload, sizeof(rb_event->payload), (void *)payload);

View File

@@ -12,9 +12,9 @@ static struct expand_return{
struct xdp_md ret_md; struct xdp_md ret_md;
void *data; void *data;
void *data_end; void *data_end;
struct ethhdr eth; struct ethhdr *eth;
struct iphdr ip; struct iphdr *ip;
struct tcphdr tcp; struct tcphdr *tcp;
}expand_return; }expand_return;
/** /**
@@ -32,7 +32,7 @@ static __always_inline struct expand_return expand_tcp_packet_payload(struct xdp
struct ethhdr eth_copy; struct ethhdr eth_copy;
struct iphdr ip_copy; struct iphdr ip_copy;
struct tcphdr tcp_copy; struct tcphdr tcp_copy;
struct expand_return ret; struct expand_return ret;
//Copy the header for later before expanding ctx //Copy the header for later before expanding ctx
@@ -48,14 +48,42 @@ static __always_inline struct expand_return expand_tcp_packet_payload(struct xdp
return ret; return ret;
} }
//We must check bounds again, otherwise the verifier gets angry
ret.eth = (void*)(long)ctx->data;
ret.ip = (void *)ret.eth + sizeof(struct ethhdr);
ret.tcp = (void *)ret.ip + sizeof(struct iphdr);
void* data = (void*)(long)ctx->data;
void* data_end = (void*)(long)ctx->data_end;
if(ethernet_header_bound_check(ret.eth, data_end)<0){
bpf_printk("Bound check A failed while expanding\n");
ret.code = -1;//The rest is undefined
return ret;
}
if (ip_header_bound_check(ret.ip, data_end)<0){
bpf_printk("Bound check B failed while expanding\n");
ret.code = -1;//The rest is undefined
return ret;
}
if (tcp_header_bound_check(ret.tcp, data_end)){
bpf_printk("Bound check C failed while expanding\n");
ret.code = -1;//The rest is undefined
return ret;
}
//We now have to readjust the packet headers, checksums have changed //We now have to readjust the packet headers, checksums have changed
//Note that we do not care about ctx->data_meta or any other extra field //Note that we do not care about ctx->data_meta or any other extra field
//since we will not be using any communication here //since we will not be using any communication here
__builtin_memcpy(&(ret.eth), &eth_copy, sizeof(struct ethhdr)); __builtin_memcpy((ret.eth), &eth_copy, sizeof(struct ethhdr));
__builtin_memcpy(&(ret.ip), &ip_copy, sizeof(struct iphdr)); __builtin_memcpy((ret.ip), &ip_copy, sizeof(struct iphdr));
__builtin_memcpy(&(ret.tcp), &tcp_copy, sizeof(struct tcphdr)); __builtin_memcpy((ret.tcp), &tcp_copy, sizeof(struct tcphdr));
//We modify the fields we care about of the headers
bpf_printk("before: %i\n", ret.ip->tot_len);
ret.ip->tot_len = htons(ntohs(ret.ip->tot_len) + more_bytes);
bpf_printk("after: %i\n", ret.ip->tot_len);
ret.ret_md = *ctx; ret.ret_md = *ctx;
ret.code = 0; ret.code = 0;
ret.data = (void *)(long)ctx->data; ret.data = (void *)(long)ctx->data;