From: Demi Marie Obenour <demiobenour@gmail.com>
To: Spectrum OS Development <devel@spectrum-os.org>
Cc: Demi Marie Obenour <demiobenour@gmail.com>, Alyssa Ross <hi@alyssa.is>
Subject: [PATCH v4 1/2] tools/xdp-forwarder: Do not include libc headers in eBPF programs
Date: Tue, 21 Oct 2025 15:27:04 -0400 [thread overview]
Message-ID: <20251021-fix-forwarder-build-v4-1-b978718c004d@gmail.com> (raw)
In-Reply-To: <20251021-fix-forwarder-build-v4-0-b978718c004d@gmail.com>
The build happened to work on arm64 because the glibc arm64 headers
don't support multilib. On x86_64, glibc headers assume that BPF is a
32-bit platform (because __x86_64__ isn't defined) and fail to find the
32-bit headers. This is not a glibc bug. Rather, BPF programs should
not be including glibc headers.
Most Linux headers are not trivial to include in BPF programs. The
version of the headers meant for userspace use do include glibc headers,
and that isn't supported in BPF. The version meant for building
kernel modules does not, but using it requires much more complicated
build system.
Solve this problem by only including headers intended for use in BPF
programs. These headers include declarations explicitly intended for
use in BPF programs, so if they do pull in libc headers that is a bug.
Nix's wrapped clang would pull in libc headers automatically and is not
suitable when a target is specified explicitly. Therefore, use an
unwrapped clang.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
To check that the program does not include libc headers, one can add
#include <stdio.h> (or any other libc header) and check that one gets
an appropriate error.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
tools/default.nix | 11 +++----
tools/meson.options | 4 +++
tools/xdp-forwarder/meson.build | 11 +++++--
tools/xdp-forwarder/parsing_helpers.h | 57 -----------------------------------
4 files changed, 18 insertions(+), 65 deletions(-)
diff --git a/tools/default.nix b/tools/default.nix
index 2c6846c80073e7b64fb7a19488103f6cf97a4420..f4febc9aba394fad85f20a51bb33e6b3b9224bab 100644
--- a/tools/default.nix
+++ b/tools/default.nix
@@ -6,7 +6,7 @@ import ../lib/call-package.nix (
{ src, lib, stdenv, fetchCrate, fetchurl, runCommand, buildPackages
, meson, ninja, pkg-config, rustc
, clang-tools, clippy, jq
-, dbus
+, dbus, linuxHeaders
# clang 19 (current nixpkgs default) is too old to support -fwrapv-pointer
, clang_21, libbpf
, buildSupport ? false
@@ -87,8 +87,8 @@ stdenv.mkDerivation (finalAttrs: {
nativeBuildInputs = [ meson ninja ]
++ lib.optionals (appSupport || driverSupport) [ pkg-config ]
++ lib.optionals hostSupport [ rustc ]
- ++ lib.optionals driverSupport [ clang_21 ];
- buildInputs = lib.optionals appSupport [ dbus ] ++ lib.optionals driverSupport [ libbpf ];
+ ++ lib.optionals driverSupport [ clang_21.cc ];
+ buildInputs = lib.optionals appSupport [ dbus ] ++ lib.optionals driverSupport [ libbpf linuxHeaders ];
postPatch = lib.optionals hostSupport (lib.concatMapStringsSep "\n" (crate: ''
mkdir -p subprojects/packagecache
@@ -104,11 +104,10 @@ stdenv.mkDerivation (finalAttrs: {
"-Dtests=false"
"-Dunwind=false"
"-Dwerror=true"
+ ] ++ lib.optionals driverSupport [
+ "-Dlinux-headers=${linuxHeaders}"
];
- # Not supported for target bpf
- hardeningDisable = lib.optionals driverSupport [ "zerocallusedregs" ];
-
passthru.tests = {
clang-tidy = finalAttrs.finalPackage.overrideAttrs (
{ name, src, nativeBuildInputs ? [], ... }:
diff --git a/tools/meson.options b/tools/meson.options
index 301efb9f677fdec57c8491fd6a6868f2d35cb076..2077cdeb33d6b962107b46733f855172ecfc499d 100644
--- a/tools/meson.options
+++ b/tools/meson.options
@@ -13,6 +13,10 @@ option('driver', type : 'boolean', value : false,
option('hostfsrootdir', type : 'string', value : '/run/host',
description : 'Path where the virtio-fs provided by the host will be mounted')
+option('linux-headers',
+ type : 'string',
+ description : 'Path to Linux kernel package')
+
option('tests',
type : 'boolean',
description : 'Build tests')
diff --git a/tools/xdp-forwarder/meson.build b/tools/xdp-forwarder/meson.build
index b73130eb27b8000a102b0a8847ecb06b93a955d2..501540af4d3e786774cedc1bb092c9887a2f37d8 100644
--- a/tools/xdp-forwarder/meson.build
+++ b/tools/xdp-forwarder/meson.build
@@ -11,8 +11,13 @@ executable('set-router-iface', 'set_router_iface.c',
clang = find_program('clang', native : true)
+linux_headers_path = get_option('linux-headers')
+if linux_headers_path == ''
+ error('Linux header path must be provided to build XDP forwarder')
+endif
+
bpf_o_cmd = [
- clang.full_path(),
+ clang,
'-fno-stack-protector',
'-fno-strict-aliasing',
'-fwrapv', '-fwrapv-pointer',
@@ -22,10 +27,12 @@ bpf_o_cmd = [
'-Wno-sign-compare',
'-O2',
'-target', 'bpf',
- '-I', meson.current_source_dir() + '/include',
'-g',
'-c',
+ '-std=gnu23',
'-o', '@OUTPUT@',
+ '-I', libbpf.get_variable('includedir'),
+ '-I', linux_headers_path + '/include',
'-MD',
'-MQ', '@OUTPUT',
'-MF', '@DEPFILE@',
diff --git a/tools/xdp-forwarder/parsing_helpers.h b/tools/xdp-forwarder/parsing_helpers.h
index da099346008bd58485af8308feb4d3391ceef8f5..1ea822100fdb9a75c2d28d34d93e6bb2b5d3ae26 100644
--- a/tools/xdp-forwarder/parsing_helpers.h
+++ b/tools/xdp-forwarder/parsing_helpers.h
@@ -26,8 +26,6 @@
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
-#include <linux/icmp.h>
-#include <linux/icmpv6.h>
#include <linux/udp.h>
#include <linux/tcp.h>
@@ -46,16 +44,6 @@ struct vlan_hdr {
__be16 h_vlan_encapsulated_proto;
};
-/*
- * Struct icmphdr_common represents the common part of the icmphdr and icmp6hdr
- * structures.
- */
-struct icmphdr_common {
- __u8 type;
- __u8 code;
- __sum16 cksum;
-};
-
/* Allow users of header file to redefine VLAN max depth */
#ifndef VLAN_MAX_DEPTH
#define VLAN_MAX_DEPTH 2
@@ -175,51 +163,6 @@ static __always_inline int parse_iphdr(struct hdr_cursor *nh,
return iph->protocol;
}
-static __always_inline int parse_icmp6hdr(struct hdr_cursor *nh,
- void *data_end,
- struct icmp6hdr **icmp6hdr)
-{
- struct icmp6hdr *icmp6h = nh->pos;
-
- if (icmp6h + 1 > data_end)
- return -1;
-
- nh->pos = icmp6h + 1;
- *icmp6hdr = icmp6h;
-
- return icmp6h->icmp6_type;
-}
-
-static __always_inline int parse_icmphdr(struct hdr_cursor *nh,
- void *data_end,
- struct icmphdr **icmphdr)
-{
- struct icmphdr *icmph = nh->pos;
-
- if (icmph + 1 > data_end)
- return -1;
-
- nh->pos = icmph + 1;
- *icmphdr = icmph;
-
- return icmph->type;
-}
-
-static __always_inline int parse_icmphdr_common(struct hdr_cursor *nh,
- void *data_end,
- struct icmphdr_common **icmphdr)
-{
- struct icmphdr_common *h = nh->pos;
-
- if (h + 1 > data_end)
- return -1;
-
- nh->pos = h + 1;
- *icmphdr = h;
-
- return h->type;
-}
-
/*
* parse_udphdr: parse the udp header and return the length of the udp payload
*/
--
2.51.1
next prev parent reply other threads:[~2025-10-21 19:47 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20251008-fix-forwarder-build-v3-1-705d1636d4f1@gmail.com>
2025-10-21 19:27 ` [PATCH v4 0/2] Fix build of forwarder, then improve it Demi Marie Obenour
2025-10-21 19:27 ` Demi Marie Obenour [this message]
2025-10-24 20:35 ` [PATCH v4 1/2] tools/xdp-forwarder: Do not include libc headers in eBPF programs Alyssa Ross
2025-10-21 19:27 ` [PATCH v4 2/2] tools/xdp-forwarder: Simplify forwarder programs Demi Marie Obenour
2025-10-25 11:17 ` Alyssa Ross
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=20251021-fix-forwarder-build-v4-1-b978718c004d@gmail.com \
--to=demiobenour@gmail.com \
--cc=devel@spectrum-os.org \
--cc=hi@alyssa.is \
/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.
Code repositories for project(s) associated with this public inbox
https://spectrum-os.org/git/crosvm
https://spectrum-os.org/git/doc
https://spectrum-os.org/git/mktuntap
https://spectrum-os.org/git/nixpkgs
https://spectrum-os.org/git/spectrum
https://spectrum-os.org/git/ucspi-vsock
https://spectrum-os.org/git/www
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).