[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250827-dynptr-skb-meta-no-net-v1-1-42695c402b16@cloudflare.com>
Date: Wed, 27 Aug 2025 12:48:29 +0200
From: Jakub Sitnicki <jakub@...udflare.com>
To: bpf@...r.kernel.org, Martin KaFai Lau <martin.lau@...ux.dev>
Cc: Alexei Starovoitov <ast@...nel.org>,
Andrii Nakryiko <andrii@...nel.org>, Daniel Borkmann <daniel@...earbox.net>,
kernel-team@...udflare.com, netdev@...r.kernel.org,
kernel test robot <lkp@...el.com>
Subject: [PATCH bpf-next] bpf: stub out skb metadata dynptr read/write ops
when CONFIG_NET=n
Kernel Test Robot reported a compiler warning - a null pointer may be
passed to memmove in __bpf_dynptr_{read,write} when building without
networking support.
The warning is correct from a static analysis standpoint, but not actually
reachable. Without CONFIG_NET, creating dynptrs to skb metadata is
impossible since the constructor kfunc is missing.
Fix this the same way as for skb and xdp data dynptrs. Add wrappers for
loading and storing bytes to skb metadata, and stub them out to return an
error when CONFIG_NET=n.
Fixes: 6877cd392bae ("bpf: Enable read/write access to skb metadata through a dynptr")
Reported-by: kernel test robot <lkp@...el.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202508212031.ir9b3B6Q-lkp@intel.com/
Signed-off-by: Jakub Sitnicki <jakub@...udflare.com>
---
include/linux/filter.h | 26 ++++++++++++++++++++++++++
kernel/bpf/helpers.c | 6 ++----
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 9092d8ea95c8..5b0d7c5824ac 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1779,6 +1779,20 @@ void *bpf_xdp_pointer(struct xdp_buff *xdp, u32 offset, u32 len);
void bpf_xdp_copy_buf(struct xdp_buff *xdp, unsigned long off,
void *buf, unsigned long len, bool flush);
void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset);
+
+static inline int __bpf_skb_meta_load_bytes(struct sk_buff *skb,
+ u32 offset, void *to, u32 len)
+{
+ memmove(to, bpf_skb_meta_pointer(skb, offset), len);
+ return 0;
+}
+
+static inline int __bpf_skb_meta_store_bytes(struct sk_buff *skb, u32 offset,
+ const void *from, u32 len)
+{
+ memmove(bpf_skb_meta_pointer(skb, offset), from, len);
+ return 0;
+}
#else /* CONFIG_NET */
static inline int __bpf_skb_load_bytes(const struct sk_buff *skb, u32 offset,
void *to, u32 len)
@@ -1818,6 +1832,18 @@ static inline void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset)
{
return NULL;
}
+
+static inline int __bpf_skb_meta_load_bytes(struct sk_buff *skb, u32 offset,
+ void *to, u32 len)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int __bpf_skb_meta_store_bytes(struct sk_buff *skb, u32 offset,
+ const void *from, u32 len)
+{
+ return -EOPNOTSUPP;
+}
#endif /* CONFIG_NET */
#endif /* __LINUX_FILTER_H__ */
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 401b4932cc49..85761e347190 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -1778,8 +1778,7 @@ static int __bpf_dynptr_read(void *dst, u32 len, const struct bpf_dynptr_kern *s
case BPF_DYNPTR_TYPE_XDP:
return __bpf_xdp_load_bytes(src->data, src->offset + offset, dst, len);
case BPF_DYNPTR_TYPE_SKB_META:
- memmove(dst, bpf_skb_meta_pointer(src->data, src->offset + offset), len);
- return 0;
+ return __bpf_skb_meta_load_bytes(src->data, src->offset + offset, dst, len);
default:
WARN_ONCE(true, "bpf_dynptr_read: unknown dynptr type %d\n", type);
return -EFAULT;
@@ -1839,8 +1838,7 @@ int __bpf_dynptr_write(const struct bpf_dynptr_kern *dst, u32 offset, void *src,
case BPF_DYNPTR_TYPE_SKB_META:
if (flags)
return -EINVAL;
- memmove(bpf_skb_meta_pointer(dst->data, dst->offset + offset), src, len);
- return 0;
+ return __bpf_skb_meta_store_bytes(dst->data, dst->offset + offset, src, len);
default:
WARN_ONCE(true, "bpf_dynptr_write: unknown dynptr type %d\n", type);
return -EFAULT;
Powered by blists - more mailing lists