Skip to content
Snippets Groups Projects
Commit 27c464e4 authored by Michael Paquier's avatar Michael Paquier
Browse files

Fix buffer overflow when processing SCRAM final message in libpq

When a client connects to a rogue server sending specifically-crafted
messages, this can suffice to execute arbitrary code as the operating
system account used by the client.

While on it, fix one error handling when decoding an incorrect salt
included in the first message received from server.

Author: Michael Paquier
Reviewed-by: Jonathan Katz, Heikki Linnakangas
Security: CVE-2019-10164
Backpatch-through: 10
parent 4c779ce3
No related branches found
No related tags found
No related merge requests found
...@@ -586,6 +586,12 @@ read_server_first_message(fe_scram_state *state, char *input) ...@@ -586,6 +586,12 @@ read_server_first_message(fe_scram_state *state, char *input)
state->saltlen = pg_b64_decode(encoded_salt, state->saltlen = pg_b64_decode(encoded_salt,
strlen(encoded_salt), strlen(encoded_salt),
state->salt); state->salt);
if (state->saltlen < 0)
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("malformed SCRAM message (invalid salt)\n"));
return false;
}
iterations_str = read_attr_value(&input, 'i', &conn->errorMessage); iterations_str = read_attr_value(&input, 'i', &conn->errorMessage);
if (iterations_str == NULL) if (iterations_str == NULL)
...@@ -616,6 +622,7 @@ read_server_final_message(fe_scram_state *state, char *input) ...@@ -616,6 +622,7 @@ read_server_final_message(fe_scram_state *state, char *input)
{ {
PGconn *conn = state->conn; PGconn *conn = state->conn;
char *encoded_server_signature; char *encoded_server_signature;
char *decoded_server_signature;
int server_signature_len; int server_signature_len;
state->server_final_message = strdup(input); state->server_final_message = strdup(input);
...@@ -651,15 +658,27 @@ read_server_final_message(fe_scram_state *state, char *input) ...@@ -651,15 +658,27 @@ read_server_final_message(fe_scram_state *state, char *input)
printfPQExpBuffer(&conn->errorMessage, printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("malformed SCRAM message (garbage at end of server-final-message)\n")); libpq_gettext("malformed SCRAM message (garbage at end of server-final-message)\n"));
server_signature_len = pg_b64_dec_len(strlen(encoded_server_signature));
decoded_server_signature = malloc(server_signature_len);
if (!decoded_server_signature)
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("out of memory\n"));
return false;
}
server_signature_len = pg_b64_decode(encoded_server_signature, server_signature_len = pg_b64_decode(encoded_server_signature,
strlen(encoded_server_signature), strlen(encoded_server_signature),
state->ServerSignature); decoded_server_signature);
if (server_signature_len != SCRAM_KEY_LEN) if (server_signature_len != SCRAM_KEY_LEN)
{ {
free(decoded_server_signature);
printfPQExpBuffer(&conn->errorMessage, printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("malformed SCRAM message (invalid server signature)\n")); libpq_gettext("malformed SCRAM message (invalid server signature)\n"));
return false; return false;
} }
memcpy(state->ServerSignature, decoded_server_signature, SCRAM_KEY_LEN);
free(decoded_server_signature);
return true; return true;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment