summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Salzman <daniel.salzman@nic.cz>2024-12-31 20:03:04 +0100
committerDaniel Salzman <daniel.salzman@nic.cz>2025-01-03 19:44:20 +0100
commit57e40a4809ebc2a029d8d289c919224b58d854c7 (patch)
tree1e6462424bd253690c377752470c5b10ff560e81
parentxdp: refactor access checks to be uniform with the other checks (diff)
downloadknot-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.c11
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;
}