У меня ошибка при попытке получить доступ к iphdr с помощью eBPF

Поэтому я пытался получить доступ к iphdr с помощью eBPF.

static inline int parse_ipv4(void *data, u64 nh_off, void *data_end) {
struct iphdr *iph = data + nh_off;

if ((void*)&iph[1] > data_end)
    return 0;
return iph->protocol;
}

Когда я использую приведенный выше код в функции eBPF, он отлично работает, например:

if (h_proto == htons(ETH_P_IP)){
index = parse_ipv4(data, nh_off, data_end);

Вот так работает вызов функции parse_ipv4.

Однако, если я попытаюсь получить доступ к ipheader напрямую, не используя эту функцию, это не сработает.

if (h_proto == htons(ETH_P_IP)){
    index = parse_ipv4(data, nh_off, data_end);

    struct iphdr *iph2 = sizeof(*eth) + nh_off;
}

Это дает мне ошибку: ПОДСКАЗКА: ошибка недопустимого доступа к памяти 'inv' может произойти, если вы попытаетесь разыменовать память без предварительного использования bpf_probe_read() для ее копирования в стек BPF. Иногда bpf_probe_read запускается автоматически переписателем скрытой копии, в других случаях вам нужно указать это явно.

и не получается активировать.

Огромное спасибо заранее!


person Rosè    schedule 10.07.2019    source источник


Ответы (1)


Если я неправильно понимаю вашу программу, следующее:

struct iphdr *iph2 = sizeof(*eth) + nh_off;

выглядит ошибочно. Вместо этого iph2 должно быть чем-то вроде data + nh_off, как в вашей функции, не так ли? Если вы установите его на сумму двух размеров без базового адреса, вы попытаетесь получить доступ к данным в произвольном месте памяти (что-то вроде 0x28, я думаю), что, конечно, не разрешено.

person Qeole    schedule 10.07.2019
comment
О, это так верно! В очередной раз благодарим за помощь. Ты много раз спасаешь мне жизнь :D - person Rosè; 11.07.2019