prepare-root: Properly check return value of snprintf()
authorUwe Kleine-König <u.kleine-koenig@baylibre.com>
Fri, 6 Feb 2026 11:56:25 +0000 (12:56 +0100)
committerColin Walters <walters@verbum.org>
Fri, 31 Jul 2026 11:44:20 +0000 (07:44 -0400)
When the target buffer is to small to hold the resulting string a value
larger or equal than the buffer's size is returned. (In pre C99
versions, snprintf returned -1 in this case, too.)

So to ensure that no truncated paths are used adapt the error checking
accordingly.

src/switchroot/ostree-prepare-root-static.c

index 2ff202fdb588e2a4feb86f38ffcd0fef02956d21..9efb77d90e9e4816b68d622f94aeff7ede1c3723 100644 (file)
@@ -121,8 +121,11 @@ resolve_deploy_path (const char *root_mountpoint)
     errx (EXIT_FAILURE, "Failed to read kernel cmdline");
   autofree char *ostree_cmdline = find_proc_cmdline_key (kernel_cmdline, "ostree");
 
-  if (snprintf (destpath, sizeof (destpath), "%s/%s", root_mountpoint, ostree_cmdline) < 0)
+  int ret = snprintf (destpath, sizeof (destpath), "%s/%s", root_mountpoint, ostree_cmdline);
+  if (ret < 0)
     err (EXIT_FAILURE, "failed to assemble ostree target path");
+  if (ret >= sizeof (destpath))
+    errx (EXIT_FAILURE, "path too long while assembling ostree target path");
   if (lstat (destpath, &stbuf) < 0)
     err (EXIT_FAILURE, "Couldn't find specified OSTree root '%s'", destpath);
   if (!S_ISLNK (stbuf.st_mode))
@@ -243,14 +246,22 @@ main (int argc, char *argv[])
    * it's handled by ostree-system-generator's boot.mount unit instead, which
    * supports soft-reboot. But this static path is used without systemd, so the
    * generator doesn't run and we must still do it here. */
-  if (snprintf (srcpath, sizeof (srcpath), "%s/boot/loader", root_mountpoint) < 0)
+  int ret = snprintf (srcpath, sizeof (srcpath), "%s/boot/loader", root_mountpoint);
+  if (ret < 0)
     err (EXIT_FAILURE, "failed to assemble /boot/loader path");
+  if (ret >= sizeof (srcpath))
+    errx (EXIT_FAILURE, "path too long while assembling /boot/loader path");
   if (lstat (srcpath, &stbuf) == 0 && S_ISLNK (stbuf.st_mode))
     {
       if (lstat ("boot", &stbuf) == 0 && S_ISDIR (stbuf.st_mode))
         {
-          if (snprintf (srcpath, sizeof (srcpath), "%s/boot", root_mountpoint) < 0)
+          ret = snprintf (srcpath, sizeof (srcpath), "%s/boot", root_mountpoint);
+          if (ret < 0)
             err (EXIT_FAILURE, "failed to assemble /boot path");
+          /*
+           * ret >= sizeof (srcpath) cannot happen here because then writing
+           * "${root_mountpoint}/boot/loader" above would have failed already.
+           */
           if (mount (srcpath, TMP_SYSROOT "/boot", NULL, MS_BIND | MS_SILENT, NULL) < 0)
             err (EXIT_FAILURE, "failed to bind mount %s to boot", srcpath);
         }