diff options
author | Tobias Stoeckmann <tobias@stoeckmann.org> | 2023-12-10 14:20:32 +0000 |
---|---|---|
committer | Tobias Stoeckmann <tobias@stoeckmann.org> | 2023-12-11 21:02:31 +0100 |
commit | b8429cc8036cd23d075174d13eedc6d857e2b454 (patch) | |
tree | 961a80706e4bfa229cfe0c9ec127b28da7fe4fe4 /modules/pam_unix/support.c | |
parent | bf9ebc84c091f9f2d018aac2f9c2c4c4933e319e (diff) | |
download | pam-b8429cc8036cd23d075174d13eedc6d857e2b454.tar.gz pam-b8429cc8036cd23d075174d13eedc6d857e2b454.tar.bz2 pam-b8429cc8036cd23d075174d13eedc6d857e2b454.zip |
pam_unix: check str to integer conversions
Print an error in syslog if an integer could not be converted.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Diffstat (limited to 'modules/pam_unix/support.c')
-rw-r--r-- | modules/pam_unix/support.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index ec9a5725..9cc39ad7 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -46,6 +46,18 @@ int _make_remark(pam_handle_t * pamh, unsigned long long ctrl, return retval; } +static int _unix_strtoi(const char *str, int minval, int *result) +{ + char *ep; + long value = strtol(str, &ep, 10); + if (value < minval || value > INT_MAX || str == ep || *ep != '\0') { + *result = minval; + return -1; + } + *result = (int)value; + return 0; +} + /* * set the control flags for the UNIX module. */ @@ -126,9 +138,11 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, "option remember not allowed for this module type"); continue; } - *remember = strtol(str, NULL, 10); - if ((*remember == INT_MIN) || (*remember == INT_MAX)) - *remember = -1; + if (_unix_strtoi(str, -1, remember)) { + pam_syslog(pamh, LOG_ERR, + "option remember invalid [%s]", str); + continue; + } if (*remember > 400) *remember = 400; } else if (j == UNIX_MIN_PASS_LEN) { @@ -137,14 +151,22 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, "option minlen not allowed for this module type"); continue; } - *pass_min_len = atoi(str); + if (_unix_strtoi(str, 0, pass_min_len)) { + pam_syslog(pamh, LOG_ERR, + "option minlen invalid [%s]", str); + continue; + } } else if (j == UNIX_ALGO_ROUNDS) { if (rounds == NULL) { pam_syslog(pamh, LOG_ERR, "option rounds not allowed for this module type"); continue; } - *rounds = strtol(str, NULL, 10); + if (_unix_strtoi(str, 0, rounds)) { + pam_syslog(pamh, LOG_ERR, + "option rounds invalid [%s]", str); + continue; + } } ctrl &= unix_args[j].mask; /* for turning things off */ @@ -166,16 +188,24 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, /* Read number of rounds for sha256, sha512 and yescrypt */ if (off(UNIX_ALGO_ROUNDS, ctrl) && rounds != NULL) { - val = NULL; - if (on(UNIX_YESCRYPT_PASS, ctrl)) { - val = pam_modutil_search_key(pamh, LOGIN_DEFS, "YESCRYPT_COST_FACTOR"); - } else if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) { - val = pam_modutil_search_key(pamh, LOGIN_DEFS, "SHA_CRYPT_MAX_ROUNDS"); - } - if (val) { - *rounds = strtol(val, NULL, 10); - set(UNIX_ALGO_ROUNDS, ctrl); - free (val); + const char *key = NULL; + if (on(UNIX_YESCRYPT_PASS, ctrl)) + key = "YESCRYPT_COST_FACTOR"; + else if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) + key = "SHA_CRYPT_MAX_ROUNDS"; + else + key = NULL; + + if (key != NULL) { + val = pam_modutil_search_key(pamh, LOGIN_DEFS, key); + if (val) { + if (_unix_strtoi(val, 0, rounds)) + pam_syslog(pamh, LOG_ERR, + "option %s invalid [%s]", key, val); + else + set(UNIX_ALGO_ROUNDS, ctrl); + free (val); + } } } |