C713
C713

Reputation: 62

Permission Denied error message when running this ebpf code

I am getting this error when running xdp.py file

bpf: Failed to load program: Permission denied
; int dropper(struct xdp_md *ctx) {
0: (b7) r6 = 2
; void *data_end = (void *)(long)ctx->data_end;
1: (61) r2 = *(u32 *)(r1 +4)
; void *data = (void *)(long)ctx->data;
2: (61) r1 = *(u32 *)(r1 +0)
; if (data + ipsize > data_end) {
3: (bf) r3 = r1
4: (07) r3 += 34
; if (data + ipsize > data_end) {
5: (2d) if r3 > r2 goto pc+21
 R1_w=pkt(id=0,off=0,r=34,imm=0) R2_w=pkt_end(id=0,off=0,imm=0) R3_w=pkt(id=0,off=34,r=34,imm=0) R6_w=inv2 R10=fp0
; if (ip->protocol == IPPROTO_TCP) {
6: (71) r2 = *(u8 *)(r1 +23)
; if (ip->protocol == IPPROTO_TCP) {
7: (55) if r2 != 0x6 goto pc+19
 R1_w=pkt(id=0,off=0,r=34,imm=0) R2_w=inv6 R3_w=pkt(id=0,off=34,r=34,imm=0) R6_w=inv2 R10=fp0
8: (b7) r6 = 1
; if (ntohs(tcp->dest) == 4040){
9: (69) r1 = *(u16 *)(r1 +96)
invalid access to packet, off=96 size=2, R1(id=0,off=96,r=34)
R1 offset is outside of the packet
processed 10 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

Traceback (most recent call last):
  File "/home/kali/Documents/assignment/xdp.py", line 6, in <module>
    fn = b.load_func("dropper", BPF.XDP)
  File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 527, in load_func
    raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'dropper': Permission denied

This is my xdp.py code

from bcc import BPF #1
from bcc.utils import printb

device = "lo" 
b = BPF(src_file="dropper.c") 
fn = b.load_func("dropper", BPF.XDP)
b.attach_xdp(device, fn, 0) 

b.trace_print()

b.remove_xdp(device, 0)

This is my dropper.c code

#include <linux/bpf.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/pkt_cls.h>
#include <linux/tcp.h>

#define SEC(NAME) __attribute__((section(NAME), used))
#undef ntohs
#define ntohs(val) ((val)&0x00ff <<8 | (val)&0xff00 >>8)

SEC("dropper_main")
int dropper(struct xdp_md *ctx) {
  int ipsize = 0;

  void *data = (void *)(long)ctx->data;
  void *data_end = (void *)(long)ctx->data_end;

  struct ethhdr *eth = data;

  ipsize = sizeof(*eth);

  struct iphdr *ip = data + ipsize;
  ipsize += sizeof(struct iphdr);
  
  if (data + ipsize > data_end) {
    return XDP_PASS;
  }

  if (ip->protocol == IPPROTO_TCP) {
    struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ip + sizeof(*ip));
    //bpf_trace_printk("Packet dropped");
    if (ntohs(tcp->dest) == 4040){
        bpf_trace_printk("Packet dropped at 4040");
    }
    return XDP_DROP;
  }

  return XDP_PASS;
}

I am trying to print Packet Dropped message if a packet falls in Tcp port 4040. I am able to achieve Packet Dropped message whenever a packet is sent on a Tcp port but not able to achieve result only for port 4040.

Upvotes: 0

Views: 590

Answers (1)

pchaigno
pchaigno

Reputation: 13063

You need to check the packet is long enough to have the TCP header before accessing that header, in the same way you checked it was long enough to have the IP header before accessing the protocol field.

Upvotes: 2

Related Questions