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

[Libguestfs] [PATCH] Call febootstrap-supermin-helper using the new -u and -g options



Use febootstrap-supermin-helper's new -u and -g command line options to setuid,
rather than doing it in libguestfs.

This resolves an issue with the generation of the cached appliance checksum. The
checksum was being generated by a call to febootstrap-supermin-helper through
popen(). Unfortunately, a bash misfeature meant that euid would be reset to uid,
and the checksum was generated for uid, not euid. When virt-v2v is writing to a
RHEV target, uid == 0 and euid == 36, which resulted in a cached appliance being
created for root with permissions for uid 36.
---
 src/appliance.c |   51 +++++++++++++++++++++------------------------------
 1 files changed, 21 insertions(+), 30 deletions(-)

diff --git a/src/appliance.c b/src/appliance.c
index 2a955a1..8b1630e 100644
--- a/src/appliance.c
+++ b/src/appliance.c
@@ -161,11 +161,14 @@ calculate_supermin_checksum (guestfs_h *g, const char *supermin_path)
   char cmd[len];
   snprintf (cmd, len,
             "febootstrap-supermin-helper%s "
+            "-u %i "
+            "-g %i "
             "-f checksum "
             "-k '%s/kmod.whitelist' "
             "'%s/supermin.d' "
             host_cpu,
             g->verbose ? " --verbose" : "",
+            geteuid (), getegid (),
             supermin_path,
             supermin_path);
 
@@ -363,11 +366,7 @@ build_supermin_appliance (guestfs_h *g,
 }
 
 /* Run febootstrap-supermin-helper and tell it to generate the
- * appliance.  Note that we have to do an explicit fork/exec here.
- * 'system' goes via the shell, and on systems that have bash, bash
- * has a misfeature where it resets the euid to uid which breaks
- * virt-v2v.  'posix_spawn' was also considered but that doesn't allow
- * us to reset the umask.
+ * appliance.
  */
 static int
 run_supermin_helper (guestfs_h *g, const char *supermin_path,
@@ -378,6 +377,16 @@ run_supermin_helper (guestfs_h *g, const char *supermin_path,
   const char *argv[30];
   size_t i = 0;
 
+  char *uid;
+  if (asprintf (&uid, "%i", geteuid ()) == -1) {
+    perror ("asprintf");
+    _exit (EXIT_FAILURE);
+  }
+  char *gid;
+  if (asprintf (&gid, "%i", getegid ()) == -1) {
+    perror ("asprintf");
+    _exit (EXIT_FAILURE);
+  }
   char whitelist[pathlen + 32];
   snprintf (whitelist, pathlen + 32, "%s/kmod.whitelist", supermin_path);
   char supermin_d[pathlen + 32];
@@ -392,6 +401,10 @@ run_supermin_helper (guestfs_h *g, const char *supermin_path,
   argv[i++] = "febootstrap-supermin-helper";
   if (g->verbose)
     argv[i++] = "--verbose";
+  argv[i++] = "-u";
+  argv[i++] = uid;
+  argv[i++] = "-g";
+  argv[i++] = gid;
   argv[i++] = "-f";
   argv[i++] = "ext2";
   argv[i++] = "-k";
@@ -413,6 +426,9 @@ run_supermin_helper (guestfs_h *g, const char *supermin_path,
     if (g->verbose)
       guestfs___print_timestamped_argv (g, argv);
 
+    free (uid);
+    free (gid);
+
     int status;
     if (waitpid (pid, &status, 0) == -1) {
       perrorf (g, "waitpid");
@@ -432,31 +448,6 @@ run_supermin_helper (guestfs_h *g, const char *supermin_path,
    */
   umask (0022);
 
-  /* Set uid/gid in the child.  This is a workaround for a misfeature
-   * in bash which breaks virt-v2v - see the comment at the top of
-   * this function.
-   */
-  if (getuid () == 0) {
-    int egid = getegid ();
-    int euid = geteuid ();
-
-    if (egid != 0 || euid != 0) {
-      if (seteuid (0) == -1) {
-        perror ("seteuid");
-        _exit (EXIT_FAILURE);
-      }
-
-      if (setgid (egid) == -1) {
-        perror ("setgid");
-        _exit (EXIT_FAILURE);
-      }
-
-      if (setuid (euid) == -1) {
-        perror ("setuid");
-        _exit (EXIT_FAILURE);
-      }
-    }
-  }
   execvp ("febootstrap-supermin-helper", (char * const *) argv);
   perror ("execvp");
   _exit (EXIT_FAILURE);

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