bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Srivats P <pstavirs@gmail.com>
To: bpf@vger.kernel.org
Subject: Re: How to read from pkt_end?
Date: Fri, 27 Nov 2020 23:08:34 +0530	[thread overview]
Message-ID: <CANzUK5-g9wLiwUF88em4uVzMja_aR4xj9yzMS_ZObNKjvX6C6g@mail.gmail.com> (raw)
In-Reply-To: <CANzUK58dwpX9HjfCZTyZa4oJX2iAczYEfQe5ojW1N_0NrYW7mw@mail.gmail.com>

Hi,

> How do I read from the end of the packet in a XDP program? I tried the
> below ebpf program to read the last 4 bytes of the packet, but the
> verifier rejects it.

Got it working with some trial and error - the trick was to AND the
calculated offset with 0x3fff - largest value for a packet size that
allows 9K jumbo.

Here's the working code -

__section("prog")
int xdp_prog(struct xdp_md *ctx)
{
    void *data = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;

    __u16 len = data_end - data;
    if ((data + len) > data_end)
        return XDP_ABORTED;

    __u16 ofs = (len - 4) & 0x3fff;
    __u32 *mgc = (__u32*)(data+ofs);
    if ((mgc + 1) > (__u32*)data_end)
        return XDP_ABORTED;

    if (*mgc == 0x1d10c0da)
        return XDP_DROP;

    return XDP_PASS;
}

What clued me onto the AND thing was the following lines in
Documentation/networking/filter.txt about overflow -

    Operation 'r3 += rX' may overflow and become less than original skb->data,
    therefore the verifier has to prevent that.  So when it sees 'r3 += rX'
    instruction and rX is more than 16-bit value, any subsequent
bounds-check of r3
    against skb->data_end will not give us 'range' information, so
attempts to read
    through the pointer will give "invalid access to packet" error.

Without the (superfluous) data + len > data_end check, LLVM was
optimizing the code in a way that led to scalar arithmetic which the
verifier wouldn't allow.

Of course, the ideal way to work backwards from the end of  the packet
is to allow arithmetic on pkt_end (so you could do `ofs = data_end -
4`), but there may be valid reasons not to allow that, that I'm not
aware of.

Srivats

      reply	other threads:[~2020-11-27 17:38 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-25 16:09 How to read from pkt_end? Srivats P
2020-11-27 17:38 ` Srivats P [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CANzUK5-g9wLiwUF88em4uVzMja_aR4xj9yzMS_ZObNKjvX6C6g@mail.gmail.com \
    --to=pstavirs@gmail.com \
    --cc=bpf@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).