aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2019-06-17 22:14:04 +0900
committerMichael Paquier <michael@paquier.xyz>2019-06-17 22:14:04 +0900
commit27c464e42a9e3cb3779d1ea63b835a3e191682d6 (patch)
tree08286534e7eb331b7e2f09abc7ce048cb62303a3
parent4c779ce324a15ffa0171160c52579130f25fcd3f (diff)
downloadpostgresql-27c464e42a9e3cb3779d1ea63b835a3e191682d6.tar.gz
postgresql-27c464e42a9e3cb3779d1ea63b835a3e191682d6.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 603ef4c0020..a42cea966c4 100644
--- a/src/interfaces/libpq/fe-auth-scram.c
+++ b/src/interfaces/libpq/fe-auth-scram.c
@@ -586,6 +586,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)
@@ -616,6 +622,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);
@@ -651,15 +658,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;
}