-
Notifications
You must be signed in to change notification settings - Fork 247
JSON-RPC: bound the per-connection read buffer so unterminated input cannot exhaust memory #3861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,6 +110,13 @@ QJsonObject CRpcServer::CreateJsonRpcErrorReply ( int code, QString message ) | |
| return object; | ||
| } | ||
|
|
||
| // Maximum size of a single JSON-RPC request line. An unauthenticated client that | ||
| // sends data without a terminating newline is only ever consumed on a complete line | ||
| // (canReadLine()), so without a bound the received bytes accumulate in the socket read | ||
| // buffer without limit until the process is killed by the allocator. Requests larger | ||
| // than this, or unterminated data that fills the buffer, are rejected instead of held. | ||
| static constexpr int MAX_JSON_RPC_REQUEST_BYTES = 64 * 1024; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This number needs explaining - where does the 64K bound actually come from? Is there a bound in the Server GUI Welcome Message text box? This shouldn't exceed that, for example. I don't know if there's a bound on the command line welcome message file size. The command line bounds as plain text would be bounded by the shell -- I've probably cut-n-paste over 64K into bash before now. So those other sources should be checked, too. |
||
|
|
||
| void CRpcServer::OnNewConnection() | ||
| { | ||
| QTcpSocket* pSocket = pTransportServer->nextPendingConnection(); | ||
|
|
@@ -122,6 +129,9 @@ void CRpcServer::OnNewConnection() | |
| vecClients.append ( pSocket ); | ||
| isAuthenticated[pSocket] = false; | ||
|
|
||
| // Bound the per-connection read buffer so unterminated input cannot exhaust memory. | ||
| pSocket->setReadBufferSize ( MAX_JSON_RPC_REQUEST_BYTES ); | ||
|
|
||
| connect ( pSocket, &QTcpSocket::disconnected, [this, pSocket]() { | ||
| qDebug() << "- JSON-RPC: connection from:" << pSocket->peerAddress().toString() << "closed"; | ||
| vecClients.removeAll ( pSocket ); | ||
|
|
@@ -197,6 +207,14 @@ void CRpcServer::OnNewConnection() | |
| pSocket->disconnectFromHost(); | ||
| return; | ||
| } | ||
|
|
||
| // A full buffer with no complete line is an oversized or unterminated request: | ||
| // reject and close rather than hold the bytes indefinitely. | ||
| if ( !pSocket->canReadLine() && pSocket->bytesAvailable() >= MAX_JSON_RPC_REQUEST_BYTES ) | ||
| { | ||
| Send ( pSocket, QJsonDocument ( CreateJsonRpcErrorReply ( iErrParseError, "Parse error: Request exceeds maximum size" ) ) ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maximum size of which length -> return it. |
||
| pSocket->disconnectFromHost(); | ||
| } | ||
| } ); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shorter comment, please. This declaration only needs a comment saying what it is, not where it's used.
The reasoning is repeated later anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you'd like to save tokens, use the Add a suggestion button, which might shortcut to Ctrl+g. The AI will still learn your preference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The size should definitely allow about a welcome message/chat message + some slack. That's how I would define the maximum.