]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
chsh, chfn: remove readline support [CVE-2022-0563]
authorKarel Zak <kzak@redhat.com>
Thu, 10 Feb 2022 11:03:17 +0000 (12:03 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 14 Feb 2022 11:27:40 +0000 (12:27 +0100)
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 <rory.mackie@trailofbits.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
login-utils/Makemodule.am
login-utils/chfn.c
login-utils/chsh.c

index 75c0a67569204b6dbec14c20153c94520f8d7aa3..2d0547a16b63447c3318a3a09c16294fcfe8d4de 100644 (file)
@@ -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
index ece5cdce020aeade3ace40094a5e61252d3ac10f..8f00d156e32bddb10441f9a273400e1b14b4ffee 100644 (file)
 # include "auth.h"
 #endif
 
-#ifdef HAVE_LIBREADLINE
-# define _FUNCTION_DEF
-# include <readline/readline.h>
-#endif
-
 struct finfo {
        char *full_name;
        char *office;
@@ -228,24 +223,21 @@ static char *ask_new_field(struct chfn_control *ctl, const char *question,
 {
        int len;
        char *buf = NULL; /* leave initialized to NULL or getline segfaults */
-#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(' ');
                fflush(stdout);
+
                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);
index 3b446beeb64eec9cc53cf86b2ab086fe1db66638..b7e70174897eb3464cfd084a12cf12dfa90c4cae 100644 (file)
@@ -50,7 +50,6 @@
 # include "selinux-utils.h"
 #endif
 
-
 #ifdef HAVE_LIBUSER
 # include <libuser/user.h>
 # include "libuser.h"
 # include "auth.h"
 #endif
 
-#ifdef HAVE_LIBREADLINE
-# define _FUNCTION_DEF
-# include <readline/readline.h>
-#endif
-
 struct sinfo {
        char *username;
        char *shell;
@@ -121,33 +115,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,22 +165,18 @@ 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(' ');
        fflush(stdout);
+
        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);