| From: | Takeshi Ideriha <iderihatakeshi(at)gmail(dot)com> |
|---|---|
| To: | Prashant Kumar <crprashant(at)hotmail(dot)com>, "pgsql-hackers(at)lists(dot)postgresql(dot)org" <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: [PATCH] pgcrypto: Fix sha-crypt rounds= values that do not fit in int (BUG #19743) |
| Date: | 2026-10-26 07:50:57 |
| Message-ID: | 705b0b25-dec3-426a-9431-d181925eb20c@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Prashant
On 2026/10/23 23:30, Prashant Kumar wrote:
> 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.
Thank you for the patch. In practice, most people would use gen_salt()
to generate the salt. But directly passing the raw salt strings is also
valid, so it needs some fixing.
How about using strtol or strtoi64 instead of strtoint to handle the
rounds value that is out of the integer bounds? I attached my patch
using strtoi64. We can handle the out-of-bound positive and negative
value by taking advantage of current px_crypt_shacrypt logic. We can
omit the check if the round values is positive or negative. I use
strtoi64 so that we can cope with the platform difference. (Windows
treats long type as 4 bytes.) What do you think?
> + rounds_overflow = (errno == ERANGE);
Most of the similar postgresql code is just like "if (errno == ERANGE)"
instead of using another variable.
Regarding errno, I may be wrong but I'm thinking we can omit this check
by using strtoi64 (strtol) since underflow or overflow value will change
to LONG_MIN or LONG_MAX and fall into the current bound check logic.
This is another point. I noticed the reference implementation[*] assumes
round value is only positive since it just uses strtoul though there is
no value check if it's negative or not. We might be OK to turn negative
rounds value to error since negative rounds value does not make any sense.
[*] https://www.akkadia.org/drepper/SHA-crypt.txt
Regards,
Takeshi Ideriha
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-Fix-clamp-behaviour-when-rounds-is-out-of-bounds-.patch | text/plain | 1.9 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Hayato Kuroda (Fujitsu) | 2026-10-26 08:26:10 | RE: Incorrect CONTEXT reported for errors from parallel apply worker in logical replication |
| Previous Message | Jim Jones | 2026-10-26 07:39:00 | Re: Reject access to unlogged tables in contrib modules |