diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-10-31 07:18:41 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-10-31 07:18:41 -0700 |
commit | 00d7b468e94d23646bb58b1774f5bec33b7c9fb1 (patch) | |
tree | f694ebdf6167de879ea9614279bf51b50297ac4e /sysif.c | |
parent | 746dddd01f28dc4499825c855c42aa5e95d5055a (diff) | |
download | txr-00d7b468e94d23646bb58b1774f5bec33b7c9fb1.tar.gz txr-00d7b468e94d23646bb58b1774f5bec33b7c9fb1.tar.bz2 txr-00d7b468e94d23646bb58b1774f5bec33b7c9fb1.zip |
crypt: remove dubious validator.
The validate_salt function was introduced in commit
c3a0ceb2cea1a9d43f2baf5a2e63d0d712c8df19, February 2020.
I cannot reproduce the internal crash in crypt which
it alleges, and I neglected to mention the bad inputs
in the commit or add tests. I'm not able to reproduce
the alleged behavior in spite of trying all sorts of bad
inputs; and looking at the crypt source in glibc, I
don't see any obvious problem.
And so, on this Halowe'en, we exorcise the ghost
that has been haunting the crypt.
* sysif.c (salt_char_p, validate_salt): Static functions
removed.
(crypt_wrap): Don't call validate_salt, and so cwsalt
need not be tested for null.
* tests/018/crypt.tl: New file.
* txr.1: Mention that crypt_r is used if available, which
avoids static storage.
Diffstat (limited to 'sysif.c')
-rw-r--r-- | sysif.c | 81 |
1 files changed, 12 insertions, 69 deletions
@@ -2064,82 +2064,25 @@ static val getgrnam_wrap(val wname) #if HAVE_CRYPT || HAVE_CRYPT_R -static int salt_char_p(wchar_t ch) -{ - return ((ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || - (ch == '.') || (ch == '/')); -} - -static const wchar_t *validate_salt(const wchar_t *salt) -{ - const wchar_t *s = salt; - - if (salt_char_p(*s)) { - if (salt_char_p(*++s)) - return salt; - else - goto badsalt; - } - - if (*s++ != '$') - goto badsalt; - - switch (*s++) { - case '1': case '5': case '6': - break; - case '2': - if (*s >= 'a' && *s++ <= 'z') - break; - /* fallthrough */ - default: - goto badsalt; - } - - if (*s++ != '$') - goto badsalt; - - if (wcsncmp(s, L"rounds=", 7) == 0) { - size_t ispn = wcsspn(s += 7, L"0123456789"); - s += ispn; - if (*s++ != '$') - goto badsalt; - } - - while (salt_char_p(*s)) - s++; - - if (*s && *s != '$') - goto badsalt; - - return salt; - -badsalt: - errno = EINVAL; - return 0; -} - static val crypt_wrap(val wkey, val wsalt) { val self = lit("crypt"); const wchar_t *cwkey = c_str(wkey, self); - const wchar_t *cwsalt = validate_salt(c_str(wsalt, self)); - - if (cwsalt != 0) { - char *key = utf8_dup_to(cwkey); - char *salt = utf8_dup_to(cwsalt); + const wchar_t *cwsalt = c_str(wsalt, self); + char *key = utf8_dup_to(cwkey); + char *salt = utf8_dup_to(cwsalt); #if HAVE_CRYPT_R - struct crypt_data cd; - char *hash = (cd.initialized = 0, crypt_r(key, salt, &cd)); + struct crypt_data cd; + char *hash = (cd.initialized = 0, crypt_r(key, salt, &cd)); #else - char *hash = crypt(key, salt); + char *hash = crypt(key, salt); #endif - free(key); - free(salt); - if (hash != 0) - return string_utf8(hash); - } + + free(key); + free(salt); + + if (hash != 0) + return string_utf8(hash); uw_ethrowf(error_s, lit("crypt failed: ~d/~s"), num(errno), errno_to_str(errno), nao); |