]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
main: make add_consoles_from_file more robust
authorKevin Murphy <kemurphy@andrew.cmu.edu>
Sun, 22 Apr 2012 06:06:42 +0000 (02:06 -0400)
committerRay Strode <rstrode@redhat.com>
Wed, 25 Apr 2012 20:01:38 +0000 (16:01 -0400)
add_consoles_from_file was a little fast and loose in its parsing.

This commit makes it a little more fault tolerant.

Patch split from larger patch, and modified by Ray Strode.

src/main.c

index de6c0fcfa40369c42c7f1c3400219f368ed5d436..705f5b2b1b7990882abedc162e25a1186d5b8d48 100644 (file)
@@ -1880,6 +1880,8 @@ add_consoles_from_file (state_t         *state,
 {
   int fd;
   char contents[512] = "";
+  ssize_t contents_length;
+  int num_consoles;
   const char *remaining_file_contents;
   char *console;
 
@@ -1893,7 +1895,9 @@ add_consoles_from_file (state_t         *state,
     }
 
   ply_trace ("reading file");
-  if (read (fd, contents, sizeof (contents)) <= 0)
+  contents_length = read (fd, contents, sizeof (contents));
+
+  if (contents_length <= 0)
     {
       ply_trace ("couldn't read it: %m");
       close (fd);
@@ -1902,46 +1906,56 @@ add_consoles_from_file (state_t         *state,
   close (fd);
 
   remaining_file_contents = contents;
+  num_consoles = 0;
 
   console = NULL;
-  while (remaining_file_contents != '\0')
+  while (remaining_file_contents < contents + contents_length)
     {
+      size_t console_length;
       char *end;
       char *console_device;
 
-      console = strdup (remaining_file_contents);
-      remaining_file_contents += strlen (console);
-
-      end = strpbrk (console, " ");
-
-      if (end != NULL)
-        {
-          *end = '\0';
-          remaining_file_contents++;
-        }
+      /* Advance past any leading whitespace */
+      remaining_file_contents += strspn (remaining_file_contents, " \n\t\v");
 
-      if (console[0] == '\0')
+      if (*remaining_file_contents == '\0')
         {
-          free (console);
+          /* There's nothing left after the whitespace, we're done */
           break;
         }
 
-      /* if we are in a weird case force details,
-       * so the user probably doesn't care about
-       * graphical splashes
+      console = strdup (remaining_file_contents);
+
+      /* Find trailing whitespace and NUL terminate.  If strcspn
+       * doesn't find whitespace, it gives us the length of the string
+       * until the next NUL byte, which we'll just overwrite with
+       * another NUL byte anyway. */
+      console_length = strcspn (console, " \n\t\v");
+      console[console_length] = '\0';
+
+      /* If this console is anything besides tty0, then the user is sort
+       * of a weird case (uses a serial console or whatever) and they
+       * most likely don't want a graphical splash, so force details.
        */
       if (strcmp (console, "tty0") != 0)
         state->should_force_details = true;
 
-      asprintf (&console_device, "/dev/%s", console);
-      free (console);
-      console = NULL;
+      asprintf (&console_device, "/dev/%s", remaining_file_contents);
 
       ply_trace ("console %s found!", console_device);
       ply_hashtable_insert (consoles, console_device, console_device);
+      num_consoles++;
+
+      /* Move past the parsed console string, and the whitespace we
+       * may have found above.  If we found a NUL above and not whitespace,
+       * then we're going to jump past the end of the buffer and the loop
+       * will terminate
+       */
+      remaining_file_contents += console_length + 1;
     }
 
-  return true;
+  /* Fail if there was nothing to read */
+  return num_consoles > 0;
 }
 
 static void