From 065a752b426266462dc0e7d9ad5a9fe79e6be16a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20G=C3=B6ttsche?= Date: Tue, 28 Feb 2023 15:50:20 +0100 Subject: [PATCH] Drop alloca(3) alloca(3) fails silently if not enough memory can be allocated on the stack. Use checked dynamic allocation instead. Also drop unnecessary manual NUL assignment, ensured by snprintf(3). Co-developed-by: Alejandro Colomar Signed-off-by: Alejandro Colomar --- lib/alloc.h | 2 -- libmisc/getdate.y | 3 --- src/useradd.c | 6 +++++- src/usermod.c | 31 +++++++++++++++++++------------ 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/lib/alloc.h b/lib/alloc.h index 64984f3a8..2b1599cb1 100644 --- a/lib/alloc.h +++ b/lib/alloc.h @@ -20,13 +20,11 @@ #include "defines.h" -#define ALLOCARRAY(n, type) ((type *) alloca(sizeof(type) * (n))) #define CALLOC(n, type) ((type *) calloc(n, sizeof(type))) #define XCALLOC(n, type) ((type *) xcalloc(n, sizeof(type))) #define MALLOCARRAY(n, type) ((type *) mallocarray(n, sizeof(type))) #define XMALLOCARRAY(n, type) ((type *) xmallocarray(n, sizeof(type))) -#define ALLOCA(type) ALLOCARRAY(1, type) #define MALLOC(type) MALLOCARRAY(1, type) #define XMALLOC(type) XMALLOCARRAY(1, type) #define REALLOC(ptr, type) REALLOCARRAY(ptr, 1, type) diff --git a/libmisc/getdate.y b/libmisc/getdate.y index 0c07f7466..2e13e2dc9 100644 --- a/libmisc/getdate.y +++ b/libmisc/getdate.y @@ -12,9 +12,6 @@ #ifdef HAVE_CONFIG_H # include -# ifdef FORCE_ALLOCA_H -# include -# endif #endif /* Since the code of getdate.y is not included in the Emacs executable diff --git a/src/useradd.c b/src/useradd.c index e31236155..bb5f4bc81 100644 --- a/src/useradd.c +++ b/src/useradd.c @@ -2435,6 +2435,7 @@ static void create_mail (void) if (strcasecmp (create_mail_spool, "yes") == 0) { const char *spool; char *file; + size_t size; int fd; struct group *gr; gid_t gid; @@ -2449,7 +2450,8 @@ static void create_mail (void) if (NULL == spool) { return; } - file = ALLOCARRAY (strlen (prefix) + strlen (spool) + strlen (user_name) + 3, char); + size = strlen(prefix) + strlen(spool) + strlen(user_name) + 3; + file = XMALLOCARRAY(size, char); if (prefix[0]) sprintf (file, "%s/%s/%s", prefix, spool, user_name); else @@ -2465,6 +2467,8 @@ static void create_mail (void) #endif fd = open (file, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0); + free(file); + if (fd < 0) { perror (_("Creating mailbox file")); return; diff --git a/src/usermod.c b/src/usermod.c index db5d37a42..6a61576b0 100644 --- a/src/usermod.c +++ b/src/usermod.c @@ -2034,10 +2034,9 @@ static void move_mailbox (void) { const char *maildir; char* mailfile; - char* newmailfile; int fd; struct stat st; - size_t len; + size_t size; maildir = getdef_str ("MAIL_DIR"); #ifdef MAIL_SPOOL_DIR @@ -2048,8 +2047,8 @@ static void move_mailbox (void) if (NULL == maildir) { return; } - len = strlen (prefix) + strlen (maildir) + strlen (user_name) + 3; - mailfile = ALLOCARRAY (len, char); + size = strlen(prefix) + strlen(maildir) + strlen(user_name) + 3; + mailfile = XMALLOCARRAY(size, char); /* * O_NONBLOCK is to make sure open won't hang on mandatory locks. @@ -2058,14 +2057,13 @@ static void move_mailbox (void) * between stat and chown). --marekm */ if (prefix[0]) { - (void) snprintf (mailfile, len, "%s/%s/%s", + (void) snprintf (mailfile, size, "%s/%s/%s", prefix, maildir, user_name); } else { - (void) snprintf (mailfile, len, "%s/%s", + (void) snprintf (mailfile, size, "%s/%s", maildir, user_name); } - mailfile[len-1] = '\0'; fd = open (mailfile, O_RDONLY | O_NONBLOCK, 0); if (fd < 0) { @@ -2073,11 +2071,13 @@ static void move_mailbox (void) if (errno != ENOENT) { perror (mailfile); } + free(mailfile); return; } if (fstat (fd, &st) < 0) { perror ("fstat"); (void) close (fd); + free(mailfile); return; } if (st.st_uid != user_id) { @@ -2085,6 +2085,7 @@ static void move_mailbox (void) fprintf (stderr, _("%s: warning: %s not owned by %s\n"), Prog, mailfile, user_name); (void) close (fd); + free(mailfile); return; } if (uflg) { @@ -2103,17 +2104,19 @@ static void move_mailbox (void) (void) close (fd); if (lflg) { - len = strlen (prefix) + strlen (maildir) + strlen (user_newname) + 3; - newmailfile = ALLOCARRAY(len, char); + char* newmailfile; + size_t newsize; + + newsize = strlen(prefix) + strlen(maildir) + strlen(user_newname) + 3; + newmailfile = XMALLOCARRAY(newsize, char); if (prefix[0]) { - (void) snprintf (newmailfile, len, "%s/%s/%s", + (void) snprintf (newmailfile, newsize, "%s/%s/%s", prefix, maildir, user_newname); } else { - (void) snprintf (newmailfile, len, "%s/%s", + (void) snprintf (newmailfile, newsize, "%s/%s", maildir, user_newname); } - newmailfile[len - 1] = '\0'; if ( (link (mailfile, newmailfile) != 0) || (unlink (mailfile) != 0)) { perror (_("failed to rename mailbox")); @@ -2124,8 +2127,12 @@ static void move_mailbox (void) "changing mail file name", user_newname, user_newid, 1); } + + free(newmailfile); #endif } + + free(mailfile); } #endif -- 2.47.2