diff options
author | Michael Paquier <michael@paquier.xyz> | 2019-06-17 22:14:04 +0900 |
---|---|---|
committer | Michael Paquier <michael@paquier.xyz> | 2019-06-17 22:14:04 +0900 |
commit | 27c464e42a9e3cb3779d1ea63b835a3e191682d6 (patch) | |
tree | 08286534e7eb331b7e2f09abc7ce048cb62303a3 | |
parent | 4c779ce324a15ffa0171160c52579130f25fcd3f (diff) | |
download | postgresql-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.c | 21 |
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; } |