]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
chsh: use getline() to support arbitrarily long lines
authorSami Kerola <kerolasa@iki.fi>
Sun, 14 Dec 2014 22:50:44 +0000 (22:50 +0000)
committerSami Kerola <kerolasa@iki.fi>
Mon, 5 Jan 2015 22:52:50 +0000 (22:52 +0000)
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>
login-utils/chsh.c

index 2245f4161c076a256050e4c394db8e2f4d6ff5a2..9ed4d06e5e6277eb8cc5b45e25237338ebcbae83 100644 (file)
@@ -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;
 }