From 207a955af497af0d5f64f7132b465bf76f36b2be Mon Sep 17 00:00:00 2001 From: "Chao Li (Evan)" Date: Tue, 3 Nov 2026 14:21:05 +0800 Subject: [PATCH v1] Reject empty rounds values in pgcrypto's SHA-crypt salts Check that strtoint() consumed at least one digit when parsing the rounds option. Previously, an empty value was treated as zero and clamped to 1000. Report a syntax error instead, consistent with the existing handling of malformed rounds options. Add a regression test for an empty rounds value. Author: Chao Li --- contrib/pgcrypto/crypt-sha.c | 2 +- contrib/pgcrypto/expected/crypt-shacrypt.out | 6 ++++++ contrib/pgcrypto/sql/crypt-shacrypt.sql | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/contrib/pgcrypto/crypt-sha.c b/contrib/pgcrypto/crypt-sha.c index dfdea1f9bcf..0d37d8c9d9a 100644 --- a/contrib/pgcrypto/crypt-sha.c +++ b/contrib/pgcrypto/crypt-sha.c @@ -188,7 +188,7 @@ px_crypt_shacrypt(const char *pw, const char *salt, char *passwd, unsigned dstle char *endp; int srounds = strtoint(num, &endp, 10); - if (*endp != '$') + if (endp == num || *endp != '$') ereport(ERROR, errcode(ERRCODE_SYNTAX_ERROR), errmsg("could not parse salt options")); diff --git a/contrib/pgcrypto/expected/crypt-shacrypt.out b/contrib/pgcrypto/expected/crypt-shacrypt.out index f3b76d5e913..532dbed8e2a 100644 --- a/contrib/pgcrypto/expected/crypt-shacrypt.out +++ b/contrib/pgcrypto/expected/crypt-shacrypt.out @@ -42,6 +42,9 @@ ERROR: gen_salt: Incorrect number of rounds -- should fail, exceeds supported maximum rounds value UPDATE ctest SET salt = gen_salt('sha256crypt', 1000000000); ERROR: gen_salt: Incorrect number of rounds +-- should fail, empty rounds value +SELECT crypt('password', '$5$rounds=$salt'); +ERROR: could not parse salt options TRUNCATE ctest; -- $6$ is sha512crypt SELECT crypt('', '$6$Szzz0yzz'); @@ -83,6 +86,9 @@ ERROR: gen_salt: Incorrect number of rounds -- should fail, exceeds supported maximum rounds value UPDATE ctest SET salt = gen_salt('sha512crypt', 1000000000); ERROR: gen_salt: Incorrect number of rounds +-- should fail, empty rounds value +SELECT crypt('password', '$6$rounds=$salt'); +ERROR: could not parse salt options -- Extended tests taken from public domain code at -- https://www.akkadia.org/drepper/SHA-crypt.txt -- diff --git a/contrib/pgcrypto/sql/crypt-shacrypt.sql b/contrib/pgcrypto/sql/crypt-shacrypt.sql index 3ee826f61aa..e291c00bfa0 100644 --- a/contrib/pgcrypto/sql/crypt-shacrypt.sql +++ b/contrib/pgcrypto/sql/crypt-shacrypt.sql @@ -28,6 +28,9 @@ UPDATE ctest SET salt = gen_salt('sha256crypt', 10); -- should fail, exceeds supported maximum rounds value UPDATE ctest SET salt = gen_salt('sha256crypt', 1000000000); +-- should fail, empty rounds value +SELECT crypt('password', '$5$rounds=$salt'); + TRUNCATE ctest; -- $6$ is sha512crypt @@ -55,6 +58,9 @@ UPDATE ctest SET salt = gen_salt('sha512crypt', 10); -- should fail, exceeds supported maximum rounds value UPDATE ctest SET salt = gen_salt('sha512crypt', 1000000000); +-- should fail, empty rounds value +SELECT crypt('password', '$6$rounds=$salt'); + -- Extended tests taken from public domain code at -- https://www.akkadia.org/drepper/SHA-crypt.txt -- -- 2.50.1 (Apple Git-155)