Hi hackers,

Attached is a patch for BUG #19743, reported by Ke Han [1]:
pgcrypto's crypt() parses the rounds= option of a sha256crypt /
sha512crypt salt with strtoint() and never checks errno, so a
value that does not fit in an int is silently reduced modulo
2^32 before the supported-range clamping runs.  For example,
rounds=4294968296 produces a hash computed with the minimum of
1000 rounds and no NOTICE at all, and rounds=4294967295 is
reported as "rounds=-1".

I reproduced this on current master (20devel) before fixing it.

The patch checks errno around the strtoint() call in
px_crypt_shacrypt().  On ERANGE the value is out of range in
the direction of its sign, so it is clamped to
PX_SHACRYPT_ROUNDS_MIN or PX_SHACRYPT_ROUNDS_MAX, matching the
existing clamp-with-NOTICE behaviour for in-range values, and
the NOTICEs now report the value as supplied instead of the
truncated conversion result.

Regression tests are added to crypt-shacrypt: negative overflow
cases for both $5$ and $6$, checked against full hashes, and
positive overflow cases run under a short statement_timeout so
the tests never actually compute ~1e9 rounds.  The pgcrypto
regression suite (25 tests) and the core regression suite
(239 tests) both pass with the patch applied.

This is my first patch submission; feedback is welcome.
Testing was done with AI assistance.

[1] https://postgr.es/m/[email protected]

Thanks,
Prashant Chinnam

Attachment: v1-0001-pgcrypto-Fix-sha-crypt-rounds-values-that-do-not-fit.patch
Description: v1-0001-pgcrypto-Fix-sha-crypt-rounds-values-that-do-not-fit.patch

Reply via email to