aboutsummaryrefslogtreecommitdiff
path: root/libpam
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2023-12-12 09:40:20 +0100
committerDmitry V. Levin <ldv@strace.io>2023-12-31 08:00:00 +0000
commit3c61d2f6f9843dc54c13a3c6b023563c041feaa4 (patch)
tree4108df445353bb324b6359b244789d6888bd20cd /libpam
parentc1432a2d057a4006bf2258c0e166a61c8e1f141f (diff)
downloadpam-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.c11
-rw-r--r--libpam/pam_misc.c20
-rw-r--r--libpam/pam_private.h3
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);