Describe the bug
INVALID_INDEX might not be checked everywhere correctly. AI found out that there could be an out of bounds read possiblity in client.cpp if calling SetRemoteChanGain:
|
|
|
// allocate and map client-side channel 0 |
|
int iChanID = FindClientChannel ( iServerChanID, true ); // should always return channel 0 |
|
|
|
// for headless mode we support to mute our own signal in the personal mix |
|
// (note that the check for headless is done in the main.cpp and must not |
|
// be checked here) |
|
if ( bMuteMeInPersonalMix ) |
|
{ |
|
SetRemoteChanGain ( iChanID, 0, false ); |
|
} |
|
|
To Reproduce
Not tested. Would probably need some server side trigger with invalid Channel ID.
Probably worth checking on the protocol level for invalid IDs.
Ox Alpha (GLM 5.3-Flash) suggested:
Guard the call site (minimal change):
if ( iChanID != INVALID_INDEX && bMuteMeInPersonalMix ) { ... }
and/or reject invalid IDs in EvaluateClientIDMes; optionally add a defensive Q_ASSERT/range check in SetRemoteChanGain/SetRemoteChanPan mirroring OnControllerInFaderLevel (client.cpp:956). Related latent gap: OnControllerInPanValue (client.cpp:965-975) lacks the bounds check its fader sibling has.
Expected behavior
No crash
AI analysis
src/protocol.cpp:1046-1063 (EvaluateClientIDMes) — validates only body size (1 byte); the ID value itself (0–255) is passed through unchecked.
src/client.cpp:1010-1036 (CClient::OnClientIDReceived):
int iChanID = FindClientChannel ( iServerChanID, true ); // should always return channel 0
...
if ( bMuteMeInPersonalMix )
{
SetRemoteChanGain ( iChanID, 0, false ); // iChanID can be INVALID_INDEX (-1)
}
src/client.cpp:1833-1885 (FindClientChannel) returns INVALID_INDEX (-1) when iServerChannelID < 0 || >= MAX_NUM_CHANNELS or when all 150 client channel slots are occupied.
src/client.cpp:506-539 (SetRemoteChanGain): &clientChannels[iId] with no bounds check →
- timer inactive: OOB write at
client.cpp:535 (clientChan->oldGain = clientChan->newGain = fGain;) plus OOB read of iServerChannelID fed to Channel.SetRemoteChanGain() (that callee is range-checked, channel.cpp:302);
- timer active: OOB write at
client.cpp:522, and minGainOrPanId = -1 causes OnTimerRemoteChanGainOrPan (client.cpp:546-548) to iterate from index −1 afterwards.
clientChannels is a fixed CClientChannel[150] member array (src/client.h:392).
Contrast with the correct pattern used 700 lines earlier: OnMuteStateHasChangedReceived checks if ( iChanID != INVALID_INDEX ) (client.cpp:340-346).
Describe the bug
INVALID_INDEX might not be checked everywhere correctly. AI found out that there could be an out of bounds read possiblity in client.cpp if calling SetRemoteChanGain:
jamulus/src/client.cpp
Lines 1020 to 1031 in 508f1f3
To Reproduce
Not tested. Would probably need some server side trigger with invalid Channel ID.
Probably worth checking on the protocol level for invalid IDs.
Ox Alpha (GLM 5.3-Flash) suggested:
and/or reject invalid IDs in
EvaluateClientIDMes; optionally add a defensiveQ_ASSERT/range check inSetRemoteChanGain/SetRemoteChanPanmirroringOnControllerInFaderLevel(client.cpp:956). Related latent gap:OnControllerInPanValue(client.cpp:965-975) lacks the bounds check its fader sibling has.Expected behavior
No crash
AI analysis
src/protocol.cpp:1046-1063(EvaluateClientIDMes) — validates only body size (1 byte); the ID value itself (0–255) is passed through unchecked.src/client.cpp:1010-1036(CClient::OnClientIDReceived):src/client.cpp:1833-1885(FindClientChannel) returnsINVALID_INDEX(-1) wheniServerChannelID < 0 || >= MAX_NUM_CHANNELSor when all 150 client channel slots are occupied.src/client.cpp:506-539(SetRemoteChanGain):&clientChannels[iId]with no bounds check →client.cpp:535(clientChan->oldGain = clientChan->newGain = fGain;) plus OOB read ofiServerChannelIDfed toChannel.SetRemoteChanGain()(that callee is range-checked,channel.cpp:302);client.cpp:522, andminGainOrPanId = -1causesOnTimerRemoteChanGainOrPan(client.cpp:546-548) to iterate from index −1 afterwards.clientChannelsis a fixedCClientChannel[150]member array (src/client.h:392).Contrast with the correct pattern used 700 lines earlier:
OnMuteStateHasChangedReceivedchecksif ( iChanID != INVALID_INDEX )(client.cpp:340-346).