security: add iteration limit to netjack2 sync wait loops

Add MAX_RECV_PACKETS limit to both sync_wait functions to prevent
busy-spinning on the real-time thread under a packet flood, where
SO_RCVTIMEO never fires because data is always available.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Wim Taymans 2026-04-29 14:18:41 +02:00
parent c21616d1ee
commit 5f50055750

View file

@ -716,10 +716,13 @@ static int netjack2_send_data(struct netjack2_peer *peer, uint32_t nframes,
return 0;
}
#define MAX_RECV_PACKETS 1024
static inline int32_t netjack2_driver_sync_wait(struct netjack2_peer *peer)
{
struct nj2_packet_header sync;
ssize_t len;
uint32_t tries = 0;
while (true) {
if ((len = recv(peer->fd, &sync, sizeof(sync), 0)) < 0)
@ -734,6 +737,10 @@ static inline int32_t netjack2_driver_sync_wait(struct netjack2_peer *peer)
ntohl(sync.id) == peer->params.id)
break;
}
if (++tries > MAX_RECV_PACKETS) {
pw_log_warn("too many packets in sync wait, aborting");
return -ENOENT;
}
}
peer->sync.is_last = ntohl(sync.is_last);
peer->sync.frames = ntohl(sync.frames);
@ -753,6 +760,7 @@ static inline int32_t netjack2_manager_sync_wait(struct netjack2_peer *peer)
struct nj2_packet_header sync;
ssize_t len;
int32_t offset;
uint32_t tries = 0;
while (true) {
if ((len = recv(peer->fd, &sync, sizeof(sync), MSG_PEEK)) < 0)
@ -769,6 +777,10 @@ static inline int32_t netjack2_manager_sync_wait(struct netjack2_peer *peer)
}
if ((len = recv(peer->fd, &sync, sizeof(sync), 0)) < 0)
goto receive_error;
if (++tries > MAX_RECV_PACKETS) {
pw_log_warn("too many packets in sync wait, aborting");
return -ENOENT;
}
}
peer->sync.cycle = ntohl(sync.cycle);
peer->sync.is_last = ntohl(sync.is_last);
@ -1074,7 +1086,6 @@ static int netjack2_recv_data(struct netjack2_peer *peer,
ssize_t len;
uint32_t i, audio_count = 0, midi_count = 0, packet_count = 0;
struct nj2_packet_header header;
#define MAX_RECV_PACKETS 1024
while (!peer->sync.is_last) {
if (++packet_count > MAX_RECV_PACKETS) {