Two BPF MPTCP packet-scheduler kfuncs accept a generic "struct sock *"
but internally reinterpret it as a specific role (the MPTCP-level
socket, or a subflow's TCP socket). The verifier only enforces that the
argument is a trusted struct sock, so a scheduler struct_ops program can
pass the wrong kind of socket; the kfunc then upcasts and dereferences
it, causing wild pointer use. Both are reachable from a scheduler hook
with no privilege beyond loading the scheduler.
Patch 1 (squash-to "bpf: Export mptcp packet scheduler helpers"):
mptcp_set_timeout() expects the msk. A subflow socket passed
instead is cast via mptcp_sk() and walked as msk->conn_list, causing a
GPF. Found by an MPTCP protocol-flow harness extending BRF
(arXiv:2305.08782). Fixed by narrowing the kfunc arg to
struct mptcp_sock *, so the verifier rejects a non-msk socket at load.
Patch 2 (squash-to "bpf: Export mptcp packet scheduler helpers"):
mptcp_pm_subflow_chk_stale()'s ssk arg is a subflow TCP
socket; a non-subflow socket passed in is reinterpreted via
mptcp_subflow_ctx() and both read and written through. This kfunc
legitimately takes a generic socket, so it is fixed with a runtime
role check in a __bpf_kfunc wrapper, like bpf_mptcp_subflow_ctx().
The wrapper also confirms ssk belongs to the passed msk; this is
hardening for a currently-unreachable surface, kept correct if it
widens.
Patch 3 (squash-to "selftests/bpf: Add bpf_burst scheduler & test"):
update the in-tree burst scheduler selftest to the new wrapper kfunc
names so it keeps building and loading. Split from patches 1 and 2 so
each squash-to lands on the commit it fixes.
Patches 4 and 5 (DO-NOT-MERGE): negative selftests validating the
verifier rejects the type confusion. Not intended for propagation to
net-next; like the other DO-NOT-MERGE checks they can live in the
MPTCP tree so the CI keeps exercising the kfunc type contract (per the
v1 review).
Signed-off-by: Shardul Bankar <shardul.b@mpiricsoftware.com>
---
Changes in v2:
- Split the burst-scheduler selftest kfunc rename out of the two
net/mptcp/bpf.c squash-tos into its own squash-to targeting
"selftests/bpf: Add bpf_burst scheduler & test" (Geliang).
- Patch 2: the wrapper now also verifies the subflow belongs to the
msk (subflow->conn == msk) and NULL-checks the context (the
Sashiko/Geliang ownership point).
- Marked the two negative selftests DO-NOT-MERGE so they are not
propagated to net-next (Geliang: the dedicated bad scheduler is not
for integration).
- Link to v1: https://patch.msgid.link/20260629-mptcp_bpf_kfunc_fixes-v1-0-8cc875f36f53@mpiricsoftware.com
---
Shardul Bankar (5):
Squash to "bpf: Export mptcp packet scheduler helpers"
Squash to "bpf: Export mptcp packet scheduler helpers"
Squash to "selftests/bpf: Add bpf_burst scheduler & test"
DO-NOT-MERGE: selftests/bpf: mptcp: verify scheduler rejects non-msk socket to set_timeout
DO-NOT-MERGE: selftests/bpf: mptcp: extend bad scheduler test to the kfunc type contract
net/mptcp/bpf.c | 21 ++++-
tools/testing/selftests/bpf/prog_tests/mptcp.c | 58 ++++++++++++
.../selftests/bpf/progs/mptcp_bpf_bad_sched.c | 104 +++++++++++++++++++++
.../testing/selftests/bpf/progs/mptcp_bpf_burst.c | 8 +-
4 files changed, 185 insertions(+), 6 deletions(-)
---
base-commit: 0d7f76b2394b7a20a1ec100557cd7905ee0ab40e
change-id: 20260629-mptcp_bpf_kfunc_fixes-7ab60edc2902
Best regards,
--
Shardul Bankar <shardul.b@mpiricsoftware.com>