diff options
author | Sami Kerola | 2014-12-14 23:50:44 +0100 |
---|---|---|
committer | Sami Kerola | 2015-01-05 23:52:50 +0100 |
commit | 1cb122d5913e53338713ad3c4ff04b01e92725ac (patch) | |
tree | e9daae8b334547918a16533be2691c57cba9e63d /login-utils/chsh.c | |
parent | chfn, chsh: share illegal_passwd_chars() function (diff) | |
download | kernel-qcow2-util-linux-1cb122d5913e53338713ad3c4ff04b01e92725ac.tar.gz kernel-qcow2-util-linux-1cb122d5913e53338713ad3c4ff04b01e92725ac.tar.xz kernel-qcow2-util-linux-1cb122d5913e53338713ad3c4ff04b01e92725ac.zip |
chsh: use getline() to support arbitrarily long lines
Use of fgets() can make a single long line to be understood as two
entries, and someone could play tricks with the remainder part of the
buffer.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'login-utils/chsh.c')
-rw-r--r-- | login-utils/chsh.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/login-utils/chsh.c b/login-utils/chsh.c index 2245f4161..9ed4d06e5 100644 --- a/login-utils/chsh.c +++ b/login-utils/chsh.c @@ -87,8 +87,8 @@ static int get_shell_list(char *shell_name) { FILE *fp; int found; - int len; - char buf[PATH_MAX]; + char *buf = NULL; + size_t sz = 0, len; found = false; fp = fopen(_PATH_SHELLS, "r"); @@ -97,17 +97,17 @@ static int get_shell_list(char *shell_name) warnx(_("No known shells.")); return true; } - while (fgets(buf, sizeof(buf), fp) != NULL) { + while (getline(&buf, &sz, fp) != -1) { + len = strlen(buf); /* ignore comments */ if (*buf == '#') continue; - len = strlen(buf); + /* skip blank lines*/ + if (len < 2) + continue; /* strip the ending newline */ if (buf[len - 1] == '\n') buf[len - 1] = 0; - /* ignore lines that are too damn long */ - else - continue; /* check or output the shell */ if (shell_name) { if (!strcmp(shell_name, buf)) { @@ -118,6 +118,7 @@ static int get_shell_list(char *shell_name) printf("%s\n", buf); } fclose(fp); + free(buf); return found; } |