Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5e04447

Browse files
committed
Check for unbounded authentication exchanges in libpq.
A couple of code paths in CONNECTION_AWAITING_RESPONSE will eagerly readbytes off a connection that should be closed. Don't let a misbehavingserver chew up client resources here; a v2 error can't be infinitelylong, and a v3 error should be bounded by its original message length.For the existing error_return cases, I added some additional errormessages for symmetry with the new ones, and cleaned up some messagerot.Author: Jacob ChampionDiscussion:https://www.postgresql.org/message-id/8e729daf-7d71-6965-9687-8bc0630599b3%40timescale.com
1 parenta75ff55 commit5e04447

File tree

1 file changed

+39
-12
lines changed

1 file changed

+39
-12
lines changed

‎src/interfaces/libpq/fe-connect.c

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3214,28 +3214,46 @@ PQconnectPoll(PGconn *conn)
32143214

32153215
/*
32163216
* Try to validate message length before using it.
3217+
*
32173218
* Authentication requests can't be very large, although GSS
32183219
* auth requests may not be that small. Same for
3219-
* NegotiateProtocolVersion. Errors can be a
3220-
* little larger, but not huge. If we see a large apparent
3221-
* length in an error, it means we're really talking to a
3222-
* pre-3.0-protocol server; cope. (Before version 14, the
3223-
* server also used the old protocol for errors that happened
3224-
* before processing the startup packet.)
3220+
* NegotiateProtocolVersion.
3221+
*
3222+
* Errors can be a little larger, but not huge. If we see a
3223+
* large apparent length in an error, it means we're really
3224+
* talking to a pre-3.0-protocol server; cope. (Before
3225+
* version 14, the server also used the old protocol for
3226+
* errors that happened before processing the startup packet.)
32253227
*/
3226-
if ((beresp=='R'||beresp=='v')&& (msgLength<8||msgLength>2000))
3228+
if (beresp=='R'&& (msgLength<8||msgLength>2000))
32273229
{
3228-
libpq_append_conn_error(conn,"expected authentication request from server, but received %c",
3229-
beresp);
3230+
libpq_append_conn_error(conn,"received invalid authentication request");
3231+
gotoerror_return;
3232+
}
3233+
if (beresp=='v'&& (msgLength<8||msgLength>2000))
3234+
{
3235+
libpq_append_conn_error(conn,"received invalid protocol negotiation message");
32303236
gotoerror_return;
32313237
}
32323238

3233-
if (beresp=='E'&& (msgLength<8||msgLength>30000))
3239+
#defineMAX_ERRLEN 30000
3240+
if (beresp=='E'&& (msgLength<8||msgLength>MAX_ERRLEN))
32343241
{
32353242
/* Handle error from a pre-3.0 server */
32363243
conn->inCursor=conn->inStart+1;/* reread data */
32373244
if (pqGets_append(&conn->errorMessage,conn))
32383245
{
3246+
/*
3247+
* We may not have authenticated the server yet, so
3248+
* don't let the buffer grow forever.
3249+
*/
3250+
avail=conn->inEnd-conn->inCursor;
3251+
if (avail>MAX_ERRLEN)
3252+
{
3253+
libpq_append_conn_error(conn,"received invalid error message");
3254+
gotoerror_return;
3255+
}
3256+
32393257
/* We'll come back when there is more data */
32403258
returnPGRES_POLLING_READING;
32413259
}
@@ -3255,9 +3273,15 @@ PQconnectPoll(PGconn *conn)
32553273

32563274
gotoerror_return;
32573275
}
3276+
#undef MAX_ERRLEN
32583277

32593278
/*
32603279
* Can't process if message body isn't all here yet.
3280+
*
3281+
* After this check passes, any further EOF during parsing
3282+
* implies that the server sent a bad/truncated message.
3283+
* Reading more bytes won't help in that case, so don't return
3284+
* PGRES_POLLING_READING after this point.
32613285
*/
32623286
msgLength-=4;
32633287
avail=conn->inEnd-conn->inCursor;
@@ -3280,8 +3304,8 @@ PQconnectPoll(PGconn *conn)
32803304
{
32813305
if (pqGetErrorNotice3(conn, true))
32823306
{
3283-
/* We'll come back when there is more data */
3284-
returnPGRES_POLLING_READING;
3307+
libpq_append_conn_error(conn,"received invalid error message");
3308+
gotoerror_return;
32853309
}
32863310
/* OK, we read the message; mark data consumed */
32873311
conn->inStart=conn->inCursor;
@@ -3357,6 +3381,7 @@ PQconnectPoll(PGconn *conn)
33573381
{
33583382
if (pqGetNegotiateProtocolVersion3(conn))
33593383
{
3384+
libpq_append_conn_error(conn,"received invalid protocol negotiation message");
33603385
gotoerror_return;
33613386
}
33623387
/* OK, we read the message; mark data consumed */
@@ -3370,6 +3395,8 @@ PQconnectPoll(PGconn *conn)
33703395
/* Get the type of request. */
33713396
if (pqGetInt((int*)&areq,4,conn))
33723397
{
3398+
/* can't happen because we checked the length already */
3399+
libpq_append_conn_error(conn,"received invalid authentication request");
33733400
gotoerror_return;
33743401
}
33753402
msgLength-=4;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp