grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Create environment block safely


From: Colin Watson
Subject: [PATCH] Create environment block safely
Date: Wed, 30 Sep 2009 23:54:30 +0100
User-agent: Mutt/1.5.18 (2008-05-17)

If grub-editenv create is interrupted, it's theoretically possible for
it to create an incomplete block that future grub-editenv calls won't
recognise. It would be better for it to atomically create either a
complete block or nothing. Any objections?

2009-09-30  Colin Watson  <address@hidden>

        * util/grub-editenv.c (create_envblk_file): Write new block with a
        .new suffix and then rename it into place, to ensure atomic
        creation.

Index: util/grub-editenv.c
===================================================================
--- util/grub-editenv.c (revision 2614)
+++ util/grub-editenv.c (working copy)
@@ -95,25 +95,31 @@ create_envblk_file (const char *name)
 {
   FILE *fp;
   char *buf;
+  char *namenew;
 
   buf = malloc (DEFAULT_ENVBLK_SIZE);
   if (! buf)
     grub_util_error ("out of memory");
 
-  fp = fopen (name, "wb");
+  asprintf (&namenew, "%s.new", name);
+  fp = fopen (namenew, "wb");
   if (! fp)
-    grub_util_error ("cannot open the file %s", name);
+    grub_util_error ("cannot open the file %s", namenew);
 
   memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
   memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#',
           DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
 
   if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) != DEFAULT_ENVBLK_SIZE)
-    grub_util_error ("cannot write to the file %s", name);
+    grub_util_error ("cannot write to the file %s", namenew);
 
   fsync (fileno (fp));
   free (buf);
   fclose (fp);
+
+  if (rename (namenew, name) < 0)
+    grub_util_error ("cannot rename the file %s to %s", namenew, name);
+  free (namenew);
 }
 
 static grub_envblk_t

-- 
Colin Watson                                       address@hidden




reply via email to

[Prev in Thread] Current Thread [Next in Thread]