]> 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 09:32:32 +0000 (10:32 +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 2508e14c9db84b25635f1a04adb775db9c834ee4..23c0f2dbea1a799224fcd2e0d2dc1a76fa465528 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,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);
index 3497120725decc969dd721ae83b503a0c4aaf068..ebcca1f748081d24838769f03f166fa6dd4161fd 100644 (file)
 # include "auth.h"
 #endif
 
-#ifdef HAVE_LIBREADLINE
-# define _FUNCTION_DEF
-# include <readline/readline.h>
-#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);