diff options
author | Daniel Salzman <daniel.salzman@nic.cz> | 2024-12-31 20:03:04 +0100 |
---|---|---|
committer | Daniel Salzman <daniel.salzman@nic.cz> | 2025-01-03 19:44:20 +0100 |
commit | 57e40a4809ebc2a029d8d289c919224b58d854c7 (patch) | |
tree | 1e6462424bd253690c377752470c5b10ff560e81 | |
parent | xdp: refactor access checks to be uniform with the other checks (diff) | |
download | knot-57e40a4809ebc2a029d8d289c919224b58d854c7.tar.xz knot-57e40a4809ebc2a029d8d289c919224b58d854c7.zip |
xdp: add check for IP payload length and udp->len equality
-rw-r--r-- | src/libknot/xdp/bpf-kernel.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/src/libknot/xdp/bpf-kernel.c b/src/libknot/xdp/bpf-kernel.c index 95e7f0c9c..97a187f13 100644 --- a/src/libknot/xdp/bpf-kernel.c +++ b/src/libknot/xdp/bpf-kernel.c @@ -89,6 +89,7 @@ int xdp_redirect_dns_func(struct xdp_md *ctx) const void *ip_hdr; const struct iphdr *ip4; const struct ipv6hdr *ip6; + __u16 ip_len; __u8 ipv4; __u8 ip_proto; __u8 fragmented = 0; @@ -128,7 +129,8 @@ int xdp_redirect_dns_func(struct xdp_md *ctx) /* Check the IP length. Cannot use strict equality due to * Ethernet padding applied to frames shorter than 64 octects. */ - if (data_end - data < __bpf_ntohs(ip4->tot_len)) { + ip_len = bpf_ntohs(ip4->tot_len); + if (data_end - data < ip_len) { return XDP_DROP; } @@ -151,7 +153,8 @@ int xdp_redirect_dns_func(struct xdp_md *ctx) /* Check the IP length. Cannot use strict equality due to * Ethernet padding applied to frames shorter than 64 octects. */ - if (data_end - data < __bpf_ntohs(ip6->payload_len) + sizeof(*ip6)) { + ip_len = sizeof(*ip6) + bpf_ntohs(ip6->payload_len); + if (data_end - data < ip_len) { return XDP_DROP; } @@ -203,8 +206,8 @@ int xdp_redirect_dns_func(struct xdp_md *ctx) return XDP_DROP; } - /* Check the UDP length. */ - if (data_end - (void *)udp < __bpf_ntohs(udp->len)) { + /* Check if the UDP length matches the IP payload length. */ + if ((void *)udp - ip_hdr != ip_len - bpf_ntohs(udp->len)) { return XDP_DROP; } |