fix(connection): Fix unsafe Player ID usage in ConnectionManager, DisconnectManager#2305
fix(connection): Fix unsafe Player ID usage in ConnectionManager, DisconnectManager#2305xezon wants to merge 2 commits intoTheSuperHackers:mainfrom
Conversation
Greptile Overview
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Include/GameNetwork/NetworkDefs.h | Removes duplicate NUM_CONNECTIONS enum value (was equal to MAX_SLOTS). Correct and safe change. |
| Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp | Adds MAX_SLOTS bounds checks for player IDs from network packets, replaces NUM_CONNECTIONS with MAX_SLOTS, removes redundant >= 0 checks on unsigned types. One concern: isPlayerConnected has only a debug assert, not a runtime guard against out-of-bounds access. |
| Core/GameEngine/Source/GameNetwork/DisconnectManager.cpp | Adds MAX_SLOTS bounds check in processDisconnectFrame and removes redundant playerID < 0 check in processDisconnectScreenOff. Both changes are correct. |
Flowchart
flowchart TD
A[Network Packet Received] --> B[processNetCommand]
B --> C{ACK Command?}
C -->|Yes| D[processAck / processAckStage1 / processAckStage2]
D --> D1{playerID < MAX_SLOTS?}
D1 -->|Yes| D2[Process ACK on connection]
D1 -->|No| D3[DEBUG_CRASH]
C -->|No| E{playerID >= MAX_SLOTS?}
E -->|Yes| F[Discard - Return TRUE]
E -->|No| G{Connection exists?}
G -->|No & not local| F
G -->|Yes| H{Command Type}
H -->|FRAMEINFO| I[processFrameInfo]
H -->|RUNAHEADMETRICS| J[processRunAheadMetrics]
H -->|CHAT| K[processChat]
H -->|DISCONNECT*| L[DisconnectManager]
H -->|FILEPROGRESS| M[processFileProgress]
H -->|Other| N[sendRemoteCommand]
I --> I1{playerID < MAX_SLOTS?}
I1 -->|Yes| I2[Update frame data]
I1 -->|No| I3[Skip]
J --> J1{playerID < MAX_SLOTS?}
J1 -->|Yes| J2[Update metrics]
J1 -->|No| J3[Return]
L --> L1[processDisconnectFrame]
L1 --> L2{playerID >= MAX_SLOTS?}
L2 -->|Yes| L3[Return]
L2 -->|No| L4[Process disconnect]
N --> N1{playerID < MAX_SLOTS?}
N1 -->|Yes| N2[Use frameData manager]
N1 -->|No| N3[Set frameDataMgr = nullptr]
Last reviewed commit: 2a615a8
Additional Comments (1)
Prompt To Fix With AIThis is a comment left during a code review.
Path: Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp
Line: 303:306
Comment:
`isPlayerConnected()` lacks bounds check before using `playerID` as array index in `m_connections[playerID]`
```suggestion
Bool ConnectionManager::isPlayerConnected( Int playerID )
{
return ( playerID == m_localSlot || ((playerID >= 0 && playerID < MAX_SLOTS) && m_connections[playerID] && !m_connections[playerID]->isQuitting()) );
}
```
How can I resolve this? If you propose a fix, please make it concise. |
|
Does not look like |
| NUM_CONNECTIONS | ||
| }; | ||
|
|
||
| static const Int MAX_SLOTS = MAX_PLAYER+1; |
There was a problem hiding this comment.
Maybe MAX_SLOTS should be made unsigned and instances where it is used with an iterator should all be made unsigned int, i noticed there are a few places where a mix of int or unsigned int is used.
And in some instances MAX_SLOT is explicitly cast while in others it's not.
It would be better to clean this up with this change.
This change fixes unsafe Player ID usage in classes
ConnectionManager,DisconnectManager.This problem surfaced as an actual remote client crash event when an invalid Player ID was send in a packet to a remote client. It then tried to use that value as an index to arrays (in function
ConnectionManager::sendRemoteCommand).This change now guards all relevant Player ID usages with an appropriate
MAX_SLOTSbound check.Additionally,
NUM_CONNECTIONSwas removed because it is a duplicate ofMAX_SLOTS. And allplayerID >= 0tests were removed because Player ID is an unsigned integer.