Am Freitag, dem 03.01.2025 um 23:57 +0800 schrieb Japin Li: > > Greate! I have some questions after using it. > > When I use the following query, it crashed! > > [local]:4012204 postgres=# select crypt('hello', > '$5$$6$rounds=10000$/Zg436s2vmTwsoSz'); > server closed the connection unexpectedly > This probably means the server terminated abnormally > before or while processing the request. > The connection to the server was lost. Attempting reset: Failed. > The connection to the server was lost. Attempting reset: Failed. > : !?> > > It is caused by checking the shacrypt digest. The following can fix > this crash, > but I'm unsure if it is correct. >
Hmm, can you provide a backtrace? I am currently debugging the CI results and i currently have a thinko in my code at crypt-sha.c:530, i am using the wrong length to copy the result buffer, see https://api.cirrus-ci.com/v1/artifact/task/6395274957946880/log/contrib/pgcrypto/log/postmaster.log ==33750==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc385204c7 at pc 0x7fd65a24814b bp 0x7ffc38520240 sp 0x7ffc3851f9f0 READ of size 128 at 0x7ffc385204c7 thread T0 #0 0x7fd65a24814a in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_intercep tors.inc:827 #1 0x7fd64c37c25f in px_crypt_shacrypt /tmp/cirrus-ci- build/contrib/pgcrypto/crypt-sha.c:530 #2 0x7fd64c3993f0 in run_crypt_sha /tmp/cirrus-ci- build/contrib/pgcrypto/px-crypt.c:76 But i cannot reproduce your crash in this case, maybe this is related to the above issue... > @@ -151,8 +152,7 @@ px_crypt_shacrypt(const char *pw, const char > *salt, char *passwd, unsigned dstle > type = PGCRYPTO_SHA256CRYPT; > dec_salt_binary += strlen(magic_bytes[0]); > } > - > - if (strncmp(dec_salt_binary, magic_bytes[1], > strlen(magic_bytes[1])) == 0) > + else if (strncmp(dec_salt_binary, magic_bytes[1], > strlen(magic_bytes[1])) == 0) > { > type = PGCRYPTO_SHA512CRYPT; > dec_salt_binary += strlen(magic_bytes[1]); > Yeah, seems the check is not strict enough for the magic byte and i need to be more strict here. I am going to look into this. "$5$$6$" certainly is bogus enough that we should error out instead. > Another, if I run crypt with big rounds, it cannot be canceled, for > example: > > select crypt('hello', '$5$rounds=9999999999$/Zg436s2vmTwsoSz'); > > Maybe we should add CHECK_FOR_INTERRUPTS() in step 21. > > @@ -411,6 +411,7 @@ px_crypt_shacrypt(const char *pw, const char > *salt, char *passwd, unsigned dstle > * uses the notation "digest A/B" to describe this behavior. > */ > for (block = 0; block < rounds; block++) { > + CHECK_FOR_INTERRUPTS(); > > /* a) start digest B */ > px_md_reset(digestB); > Hmm not sure how expensive it is to check for interrupts for each block. Maybe its better to check for each 10.000 blocks or so. But i like the idea. Will investigate. Thanks for your review, Bernd