From 39a81981ac4b8a1f521db550afc117ccab9548cb Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 10 Feb 2022 12:03:17 +0100 Subject: [PATCH] chsh, chfn: remove readline support [CVE-2022-0563] The readline library uses INPUTRC= environment variable to get a path to the library config file. When the library cannot parse the specified file, it prints an error message containing data from the file. Unfortunately, the library does not use secure_getenv() (or a similar concept) to avoid vulnerabilities that could occur if set-user-ID or set-group-ID programs. Reported-by: Rory Mackie Signed-off-by: Karel Zak --- login-utils/Makemodule.am | 2 +- login-utils/chfn.c | 14 ++----------- login-utils/chsh.c | 43 +++------------------------------------ 3 files changed, 6 insertions(+), 53 deletions(-) diff --git a/login-utils/Makemodule.am b/login-utils/Makemodule.am index 75c0a67569..2d0547a16b 100644 --- a/login-utils/Makemodule.am +++ b/login-utils/Makemodule.am @@ -109,7 +109,7 @@ chfn_chsh_sources = \ login-utils/ch-common.c chfn_chsh_cflags = $(SUID_CFLAGS) $(AM_CFLAGS) chfn_chsh_ldflags = $(SUID_LDFLAGS) $(AM_LDFLAGS) -chfn_chsh_ldadd = libcommon.la $(READLINE_LIBS) +chfn_chsh_ldadd = libcommon.la if CHFN_CHSH_PASSWORD chfn_chsh_ldadd += -lpam diff --git a/login-utils/chfn.c b/login-utils/chfn.c index 2508e14c9d..23c0f2dbea 100644 --- a/login-utils/chfn.c +++ b/login-utils/chfn.c @@ -56,11 +56,6 @@ # include "auth.h" #endif -#ifdef HAVE_LIBREADLINE -# define _FUNCTION_DEF -# include -#endif - struct finfo { char *full_name; char *office; @@ -228,23 +223,18 @@ static char *ask_new_field(struct chfn_control *ctl, const char *question, { int len; char *buf; -#ifndef HAVE_LIBREADLINE size_t dummy = 0; -#endif if (!def_val) def_val = ""; while (true) { printf("%s [%s]:", question, def_val); __fpurge(stdin); -#ifdef HAVE_LIBREADLINE - rl_bind_key('\t', rl_insert); - if ((buf = readline(" ")) == NULL) -#else putchar(' '); + if (getline(&buf, &dummy, stdin) < 0) -#endif errx(EXIT_FAILURE, _("Aborted.")); + /* remove white spaces from string end */ ltrim_whitespace((unsigned char *) buf); len = rtrim_whitespace((unsigned char *) buf); diff --git a/login-utils/chsh.c b/login-utils/chsh.c index 3497120725..ebcca1f748 100644 --- a/login-utils/chsh.c +++ b/login-utils/chsh.c @@ -58,11 +58,6 @@ # include "auth.h" #endif -#ifdef HAVE_LIBREADLINE -# define _FUNCTION_DEF -# include -#endif - struct sinfo { char *username; char *shell; @@ -121,33 +116,6 @@ static void print_shells(void) endusershell(); } -#ifdef HAVE_LIBREADLINE -static char *shell_name_generator(const char *text, int state) -{ - static size_t len; - char *s; - - if (!state) { - setusershell(); - len = strlen(text); - } - - while ((s = getusershell())) { - if (strncmp(s, text, len) == 0) - return xstrdup(s); - } - return NULL; -} - -static char **shell_name_completion(const char *text, - int start __attribute__((__unused__)), - int end __attribute__((__unused__))) -{ - rl_attempted_completion_over = 1; - return rl_completion_matches(text, shell_name_generator); -} -#endif - /* * parse_argv () -- * parse the command line arguments, and fill in "pinfo" with any @@ -198,21 +166,16 @@ static char *ask_new_shell(char *question, char *oldshell) { int len; char *ans = NULL; -#ifdef HAVE_LIBREADLINE - rl_attempted_completion_function = shell_name_completion; -#else size_t dummy = 0; -#endif + if (!oldshell) oldshell = ""; printf("%s [%s]:", question, oldshell); -#ifdef HAVE_LIBREADLINE - if ((ans = readline(" ")) == NULL) -#else putchar(' '); + if (getline(&ans, &dummy, stdin) < 0) -#endif return NULL; + /* remove the newline at the end of ans. */ ltrim_whitespace((unsigned char *) ans); len = rtrim_whitespace((unsigned char *) ans); -- 2.47.2