aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2019-06-17 22:13:57 +0900
committerMichael Paquier <michael@paquier.xyz>2019-06-17 22:13:57 +0900
commitb67421178880f9df337dc19b8601b54b99efbc78 (patch)
tree9811078ef059290bdbad80110960bced2250a8de
parent09ec55b933091cb5b0af99978718cb3d289c71b6 (diff)
downloadpostgresql-b67421178880f9df337dc19b8601b54b99efbc78.tar.gz
postgresql-b67421178880f9df337dc19b8601b54b99efbc78.zip
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
-rw-r--r--src/interfaces/libpq/fe-auth-scram.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.c
index 719570a45ce..babdc061984 100644
--- a/src/interfaces/libpq/fe-auth-scram.c
+++ b/src/interfaces/libpq/fe-auth-scram.c
@@ -580,6 +580,12 @@ read_server_first_message(fe_scram_state *state, char *input)
state->saltlen = pg_b64_decode(encoded_salt,
strlen(encoded_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);
if (iterations_str == NULL)
@@ -610,6 +616,7 @@ read_server_final_message(fe_scram_state *state, char *input)
{
PGconn *conn = state->conn;
char *encoded_server_signature;
+ char *decoded_server_signature;
int server_signature_len;
state->server_final_message = strdup(input);
@@ -645,15 +652,27 @@ read_server_final_message(fe_scram_state *state, char *input)
printfPQExpBuffer(&conn->errorMessage,
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,
strlen(encoded_server_signature),
- state->ServerSignature);
+ decoded_server_signature);
if (server_signature_len != SCRAM_KEY_LEN)
{
+ free(decoded_server_signature);
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("malformed SCRAM message (invalid server signature)\n"));
return false;
}
+ memcpy(state->ServerSignature, decoded_server_signature, SCRAM_KEY_LEN);
+ free(decoded_server_signature);
return true;
}