From 0a5c77e2809e337047d822efd74fb7e97d63cfea Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 22 Jan 2025 16:29:25 +0100 Subject: [PATCH] src/: Call passalloca() before a loop Calling passalloca() (which is a wrapper around alloca(3)) in a loop is dangerous, as it can trigger a stack overflow. Instead, allocate the buffer before the loop, and run getpass2() within the loop, which will reuse the buffer. Signed-off-by: Alejandro Colomar --- src/gpasswd.c | 8 +++++--- src/passwd.c | 7 +++++-- src/sulogin.c | 8 +++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/gpasswd.c b/src/gpasswd.c index 5b38b4f209..a8a227fe39 100644 --- a/src/gpasswd.c +++ b/src/gpasswd.c @@ -27,7 +27,8 @@ #include "exitcodes.h" #include "groupio.h" #include "nscd.h" -#include "pass/getpassa.h" +#include "pass/getpass2.h" +#include "pass/passalloca.h" #include "pass/passzero.h" #include "prototypes.h" #ifdef SHADOWGRP @@ -831,15 +832,16 @@ static void change_passwd (struct group *gr) */ printf (_("Changing the password for group %s\n"), group); + cp = passalloca(); for (retries = 0; retries < RETRIES; retries++) { - cp = getpassa(_("New Password: ")); + cp = getpass2(cp, _("New Password: ")); if (NULL == cp) { exit (1); } STRTCPY(pass, cp); passzero(cp); - cp = getpassa(_("Re-enter new password: ")); + cp = getpass2(cp, _("Re-enter new password: ")); if (NULL == cp) { MEMZERO(pass); exit (1); diff --git a/src/passwd.c b/src/passwd.c index 93203f74a8..a44e2de353 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -25,7 +25,9 @@ #include "defines.h" #include "getdef.h" #include "nscd.h" +#include "pass/getpass2.h" #include "pass/getpassa.h" +#include "pass/passalloca.h" #include "pass/passzero.h" #include "prototypes.h" #include "pwauth.h" @@ -293,8 +295,9 @@ static int new_password (const struct passwd *pw) } } else { warned = false; + cp = passalloca(); for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) { - cp = getpassa(_("New password: ")); + cp = getpass2(cp, _("New password: ")); if (NULL == cp) { MEMZERO(orig); MEMZERO(pass); @@ -328,7 +331,7 @@ static int new_password (const struct passwd *pw) warned = true; continue; } - cp = getpassa(_("Re-enter new password: ")); + cp = getpass2(cp, _("Re-enter new password: ")); if (NULL == cp) { MEMZERO(orig); MEMZERO(pass); diff --git a/src/sulogin.c b/src/sulogin.c index 4f1a233bfb..19bbc827de 100644 --- a/src/sulogin.c +++ b/src/sulogin.c @@ -21,7 +21,8 @@ #include "attr.h" #include "defines.h" #include "getdef.h" -#include "pass/getpassa.h" +#include "pass/getpass2.h" +#include "pass/passalloca.h" #include "pass/passzero.h" #include "prototypes.h" #include "pwauth.h" @@ -59,6 +60,7 @@ int main(int argc, char *argv[]) { int err = 0; + char *pass; char **envp = environ; TERMIO termio; struct passwd pwent = {}; @@ -129,8 +131,8 @@ main(int argc, char *argv[]) (void) signal (SIGALRM, catch_signals); /* exit if the timer expires */ (void) alarm (ALARM); /* only wait so long ... */ + pass = passalloca(); do { /* repeatedly get login/password pairs */ - char *pass; const char *prompt; if (pw_entry("root", &pwent) == -1) { /* get entry from password file */ @@ -151,7 +153,7 @@ main(int argc, char *argv[]) "(or give root password for system maintenance):"); /* get a password for root */ - pass = getpassa(prompt); + pass = getpass2(pass, prompt); /* * XXX - can't enter single user mode if root password is