diff options
author | Tobias Stoeckmann <tobias@stoeckmann.org> | 2023-12-12 09:40:20 +0100 |
---|---|---|
committer | Dmitry V. Levin <ldv@strace.io> | 2023-12-31 08:00:00 +0000 |
commit | 3c61d2f6f9843dc54c13a3c6b023563c041feaa4 (patch) | |
tree | 4108df445353bb324b6359b244789d6888bd20cd /libpam | |
parent | c1432a2d057a4006bf2258c0e166a61c8e1f141f (diff) | |
download | pam-3c61d2f6f9843dc54c13a3c6b023563c041feaa4.tar.gz pam-3c61d2f6f9843dc54c13a3c6b023563c041feaa4.tar.bz2 pam-3c61d2f6f9843dc54c13a3c6b023563c041feaa4.zip |
libpam: support very long strings in _pam_mkargv
This support has to be added before arbitrarily long lines are allowed
in configuration files.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Diffstat (limited to 'libpam')
-rw-r--r-- | libpam/pam_handlers.c | 11 | ||||
-rw-r--r-- | libpam/pam_misc.c | 20 | ||||
-rw-r--r-- | libpam/pam_private.h | 3 |
3 files changed, 22 insertions, 12 deletions
diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c index 2030dbb8..aaf194fc 100644 --- a/libpam/pam_handlers.c +++ b/libpam/pam_handlers.c @@ -32,7 +32,7 @@ static void _pam_free_handlers_aux(struct handler **hp); static int _pam_add_handler(pam_handle_t *pamh , int must_fail, int other, int stack_level, int type , int *actions, const char *mod_path - , int argc, char **argv, int argvlen); + , int argc, char **argv, size_t argvlen); /* Values for module type */ @@ -77,7 +77,7 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f int handler_type = PAM_HT_MODULE; /* regular handler from a module */ int argc; char **argv; - int argvlen; + size_t argvlen; D(("LINE: %s", buf)); if (known_service != NULL) { @@ -235,7 +235,7 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f if (nexttok != NULL) { D(("list: %s",nexttok)); argvlen = _pam_mkargv(nexttok, &argv, &argc); - D(("argvlen = %d",argvlen)); + D(("argvlen = %zu",argvlen)); if (argvlen == 0) { /* memory allocation failed */ D(("failed to allocate argument vector")); @@ -247,7 +247,8 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f } } else { /* there are no arguments so fix by hand */ D(("empty argument list")); - argvlen = argc = 0; + argvlen = 0; + argc = 0; argv = NULL; } @@ -788,7 +789,7 @@ _pam_load_module(pam_handle_t *pamh, const char *mod_path, int handler_type) int _pam_add_handler(pam_handle_t *pamh , int handler_type, int other, int stack_level, int type , int *actions, const char *mod_path - , int argc, char **argv, int argvlen) + , int argc, char **argv, size_t argvlen) { struct loaded_module *mod = NULL; struct handler **handler_p; diff --git a/libpam/pam_misc.c b/libpam/pam_misc.c index a334f0f8..c91aa693 100644 --- a/libpam/pam_misc.c +++ b/libpam/pam_misc.c @@ -40,6 +40,7 @@ #include <limits.h> #include <stdarg.h> #include <stdlib.h> +#include <stdint.h> #include <stdio.h> #include <string.h> #include <syslog.h> @@ -150,10 +151,10 @@ char *_pam_memdup(const char *x, int len) /* Generate argv, argc from s */ /* caller must free(argv) */ -int _pam_mkargv(const char *s, char ***argv, int *argc) +size_t _pam_mkargv(const char *s, char ***argv, int *argc) { - int l; - int argvlen = 0; + size_t l; + size_t argvlen = 0; char **our_argv = NULL; D(("called: %s",s)); @@ -161,7 +162,7 @@ int _pam_mkargv(const char *s, char ***argv, int *argc) *argc = 0; l = strlen(s); - if (l) { + if (l && l < SIZE_MAX / (sizeof(char) + sizeof(char *))) { char **argvbuf; /* Overkill on the malloc, but not large */ argvlen = (l + 1) * (sizeof(char) + sizeof(char *)); @@ -173,15 +174,22 @@ int _pam_mkargv(const char *s, char ***argv, int *argc) char *tmp=NULL; char *tok; #ifdef PAM_DEBUG - int count=0; + unsigned count=0; #endif argvbufp = (char *) argvbuf + (l * sizeof(char *)); strcpy(argvbufp, s); D(("[%s]",argvbufp)); while ((tok = _pam_tokenize(argvbufp, &tmp))) { - D(("arg #%d",++count)); + D(("arg #%u",++count)); D(("->[%s]",tok)); *argvbuf++ = tok; + if (*argc == INT_MAX) { + pam_syslog(NULL, LOG_CRIT, + "pam_mkargv: too many arguments"); + argvlen = 0; + _pam_drop(our_argv); + break; + } (*argc)++; argvbufp = NULL; D(("loop again?")); diff --git a/libpam/pam_private.h b/libpam/pam_private.h index 8069b61c..df6872fa 100644 --- a/libpam/pam_private.h +++ b/libpam/pam_private.h @@ -16,6 +16,7 @@ #include "config.h" +#include <stddef.h> #include <syslog.h> #include <security/pam_appl.h> @@ -272,7 +273,7 @@ char *_pam_strdup(const char *s); char *_pam_memdup(const char *s, int len); -int _pam_mkargv(const char *s, char ***argv, int *argc); +size_t _pam_mkargv(const char *s, char ***argv, int *argc); void _pam_sanitize(pam_handle_t *pamh); |