From a7619fdfdb7860de366d7f2e1552e2275abca397 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 24 Apr 2026 16:56:46 +0200 Subject: [PATCH] security: validate MTU bounds in NetJack2 to prevent stack overflow Memory Safety: High The NetJack2 driver and manager modules use VLA (variable-length array) stack buffers sized by peer->params.mtu in every send and receive function. In the driver module, this MTU value comes directly from the remote peer via nj2_session_params_ntoh() without any upper bound validation. A malicious remote peer could advertise an extremely large MTU value (up to UINT32_MAX), causing multi-gigabyte VLA stack allocations that overflow the stack. Both modules also read net.mtu from user properties via pw_properties_get_uint32() without capping the value, even though MAX_MTU (9000) was already defined but never enforced. Add MTU validation against MAX_MTU in the driver's session setup handler, and cap the configured MTU value in both driver and manager initialization. Co-Authored-By: Claude Opus 4.6 --- src/modules/module-netjack2-driver.c | 5 ++++- src/modules/module-netjack2-manager.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/modules/module-netjack2-driver.c b/src/modules/module-netjack2-driver.c index 462857766..e9f846ace 100644 --- a/src/modules/module-netjack2-driver.c +++ b/src/modules/module-netjack2-driver.c @@ -846,6 +846,8 @@ static int handle_follower_setup(struct impl *impl, struct nj2_session_params *p peer->params.recv_midi_channels < 0 || peer->params.sample_rate == 0 || peer->params.period_size == 0 || + peer->params.mtu == 0 || + peer->params.mtu > MAX_MTU || !encoding_supported(peer->params.sample_encoder)) { pw_log_warn("invalid follower setup"); return -EINVAL; @@ -1049,7 +1051,8 @@ static int create_netjack2_socket(struct impl *impl) goto out; } - impl->mtu = pw_properties_get_uint32(impl->props, "net.mtu", DEFAULT_NET_MTU); + impl->mtu = SPA_MIN(pw_properties_get_uint32(impl->props, "net.mtu", DEFAULT_NET_MTU), + (uint32_t)MAX_MTU); impl->ttl = pw_properties_get_uint32(impl->props, "net.ttl", DEFAULT_NET_TTL); impl->loop = pw_properties_get_bool(impl->props, "net.loop", DEFAULT_NET_LOOP); impl->dscp = pw_properties_get_uint32(impl->props, "net.dscp", DEFAULT_NET_DSCP); diff --git a/src/modules/module-netjack2-manager.c b/src/modules/module-netjack2-manager.c index bb8d9d020..f046f71df 100644 --- a/src/modules/module-netjack2-manager.c +++ b/src/modules/module-netjack2-manager.c @@ -1201,7 +1201,8 @@ static int create_netjack2_socket(struct impl *impl) goto out; } - impl->mtu = pw_properties_get_uint32(impl->props, "net.mtu", DEFAULT_NET_MTU); + impl->mtu = SPA_MIN(pw_properties_get_uint32(impl->props, "net.mtu", DEFAULT_NET_MTU), + (uint32_t)MAX_MTU); impl->ttl = pw_properties_get_uint32(impl->props, "net.ttl", DEFAULT_NET_TTL); impl->loop = pw_properties_get_bool(impl->props, "net.loop", DEFAULT_NET_LOOP); impl->dscp = pw_properties_get_uint32(impl->props, "net.dscp", DEFAULT_NET_DSCP);