Skip to content

Commit

Permalink
chsh, chfn: remove readline support [CVE-2022-0563]
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
karelzak committed Feb 14, 2022
1 parent 86f89da commit 39a8198
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 53 deletions.
2 changes: 1 addition & 1 deletion login-utils/Makemodule.am
Expand Up @@ -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
Expand Down
14 changes: 2 additions & 12 deletions login-utils/chfn.c
Expand Up @@ -56,11 +56,6 @@
# include "auth.h"
#endif

#ifdef HAVE_LIBREADLINE
# define _FUNCTION_DEF
# include <readline/readline.h>
#endif

struct finfo {
char *full_name;
char *office;
Expand Down Expand Up @@ -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);
Expand Down
43 changes: 3 additions & 40 deletions login-utils/chsh.c
Expand Up @@ -58,11 +58,6 @@
# include "auth.h"
#endif

#ifdef HAVE_LIBREADLINE
# define _FUNCTION_DEF
# include <readline/readline.h>
#endif

struct sinfo {
char *username;
char *shell;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 39a8198

Please sign in to comment.