aboutsummaryrefslogtreecommitdiff
path: root/libpam/pam_misc.c
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/pam_misc.c
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/pam_misc.c')
-rw-r--r--libpam/pam_misc.c20
1 files changed, 14 insertions, 6 deletions
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?"));