[ostree] ostbuild: Also allow making directories read-only



commit fb5ecdac429f5972c7e62e7fcd2eb5b2dc99219c
Author: Colin Walters <walters verbum org>
Date:   Tue Dec 6 19:36:42 2011 -0500

    ostbuild: Also allow making directories read-only

 src/ostbuild/ostbuild-user-chroot.c |  129 +++++++++++++++++++++++++++--------
 1 files changed, 101 insertions(+), 28 deletions(-)
---
diff --git a/src/ostbuild/ostbuild-user-chroot.c b/src/ostbuild/ostbuild-user-chroot.c
index 6781b38..f880aaf 100644
--- a/src/ostbuild/ostbuild-user-chroot.c
+++ b/src/ostbuild/ostbuild-user-chroot.c
@@ -65,6 +65,32 @@ fatal_errno (const char *message)
   exit (1);
 }
 
+typedef struct _BindMount BindMount;
+struct _BindMount {
+  const char *source;
+  const char *dest;
+
+  unsigned int readonly;
+
+  BindMount *next;
+};
+
+static BindMount *
+reverse_bind_mount_list (BindMount *mount)
+{
+  BindMount *prev = NULL;
+
+  while (mount)
+    {
+      BindMount *next = mount->next;
+      mount->next = prev;
+      prev = mount;
+      mount = next;
+    }
+
+  return prev;
+}
+
 int
 main (int      argc,
       char   **argv)
@@ -74,10 +100,12 @@ main (int      argc,
   const char *program;
   uid_t ruid, euid, suid;
   gid_t rgid, egid, sgid;
-  int after_bind_arg_index;
-  int i;
+  int after_mount_arg_index;
+  unsigned int n_mounts = 0;
+  const unsigned int max_mounts = 50; /* Totally arbitrary... */
   char **program_argv;
-  char **argv_iter;
+  BindMount *bind_mounts = NULL;
+  BindMount *bind_mount_iter;
 
   if (argc <= 0)
     return 1;
@@ -89,22 +117,57 @@ main (int      argc,
   if (argc < 1)
     fatal ("ROOTDIR argument must be specified");
 
-  after_bind_arg_index = 0;
-  argv_iter = argv;
-  while (after_bind_arg_index < argc
-         && strcmp (argv[after_bind_arg_index], "--bind") == 0)
+  after_mount_arg_index = 0;
+  while (after_mount_arg_index < argc)
     {
-      if ((argc - after_bind_arg_index) < 3)
-        fatal ("--bind takes two arguments");
-      after_bind_arg_index += 3;
-      argv_iter += 3;
+      const char *arg = argv[after_mount_arg_index];
+      BindMount *mount = NULL;
+
+      if (n_mounts >= max_mounts)
+        fatal ("Too many mounts (maximum of %u)", n_mounts);
+      n_mounts++;
+
+      if (strcmp (arg, "--mount-bind") == 0)
+        {
+          if ((argc - after_mount_arg_index) < 3)
+            fatal ("--mount-bind takes two arguments");
+
+          mount = malloc (sizeof (BindMount));
+          mount->source = argv[after_mount_arg_index+1];
+          mount->dest = argv[after_mount_arg_index+2];
+          mount->readonly = 0;
+          mount->next = bind_mounts;
+          
+          bind_mounts = mount;
+          after_mount_arg_index += 3;
+        }
+      else if (strcmp (arg, "--mount-readonly") == 0)
+        {
+          BindMount *mount;
+
+          if ((argc - after_mount_arg_index) < 2)
+            fatal ("--mount-readonly takes one argument");
+
+          mount = malloc (sizeof (BindMount));
+          mount->source = NULL;
+          mount->dest = argv[after_mount_arg_index+1];
+          mount->readonly = 1;
+          mount->next = bind_mounts;
+          
+          bind_mounts = mount;
+          after_mount_arg_index += 2;
+        }
+      else
+        break;
     }
+        
+  bind_mounts = reverse_bind_mount_list (bind_mounts);
 
-  if ((argc - after_bind_arg_index) < 2)
-    fatal ("usage: %s [--bind SOURCE DEST] ROOTDIR PROGRAM ARGS...", argv0);
-  chroot_dir = argv[after_bind_arg_index];
-  program = argv[after_bind_arg_index+1];
-  program_argv = argv + after_bind_arg_index + 1;
+  if ((argc - after_mount_arg_index) < 2)
+    fatal ("usage: %s [--mount-readonly DIR] [--mount-bind SOURCE DEST] ROOTDIR PROGRAM ARGS...", argv0);
+  chroot_dir = argv[after_mount_arg_index];
+  program = argv[after_mount_arg_index+1];
+  program_argv = argv + after_mount_arg_index + 1;
 
   if (getresgid (&rgid, &egid, &sgid) < 0)
     fatal_errno ("getresgid");
@@ -145,19 +208,29 @@ main (int      argc,
     fatal_errno ("mount(/, MS_PRIVATE | MS_REC)");
 
   /* Now let's set up our bind mounts */
-  for (i = 0; i < after_bind_arg_index; i += 3)
+  for (bind_mount_iter = bind_mounts; bind_mount_iter; bind_mount_iter = bind_mount_iter->next)
     {
-      const char *bind_arg = argv[0]; /* --bind */
-      const char *bind_source = argv[i+1];
-      const char *bind_target = argv[i+2];
-      char *bind_abs_target;
-
-      assert (strcmp (bind_arg, "--bind") == 0);
-
-      asprintf (&bind_abs_target, "%s%s", chroot_dir, bind_target);
-      if (mount (bind_source, bind_abs_target, NULL, MS_BIND | MS_PRIVATE, NULL) < 0)
-        fatal_errno ("mount (MS_BIND)");
-      free (bind_abs_target);
+      char *dest;
+
+      asprintf (&dest, "%s%s", chroot_dir, bind_mount_iter->dest);
+
+      if (bind_mount_iter->readonly)
+        {
+          if (mount (dest, dest,
+                     NULL, MS_BIND | MS_PRIVATE, NULL) < 0)
+            fatal_errno ("mount (MS_BIND)");
+          if (mount (dest, dest,
+                     NULL, MS_BIND | MS_PRIVATE | MS_REMOUNT | MS_RDONLY, NULL) < 0)
+            fatal_errno ("mount (MS_BIND | MS_RDONLY)");
+        }
+      else
+        {
+
+          if (mount (bind_mount_iter->source, dest,
+                     NULL, MS_BIND | MS_PRIVATE, NULL) < 0)
+            fatal_errno ("mount (MS_BIND)");
+        }
+      free (dest);
     }
 
   /* Actually perform the chroot. */



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