]> git.e2factory.org Git - e2factory.git/commitdiff
move chroot marker out of the chroot environment, fixing a possible
authorGordon Hecker <gh@emlix.com>
Thu, 2 Apr 2009 15:47:20 +0000 (17:47 +0200)
committerGordon Hecker <gh@emlix.com>
Wed, 22 Apr 2009 08:47:08 +0000 (10:47 +0200)
deadlock situation

Signed-off-by: Gordon Hecker <gh@emlix.com>
generic/e2-su-2.2.c
local/e2build.lua

index de9b7aa2be9074cb8aa90a99acde3ae5858713a3..8476eacfe38e7284199e521f858581ecb53b8456 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+/* chroot layout used with the _2_2 postfix commands
+ * call with e2-su-2.2 <command> <path> ...
+ *  path/emlix-chroot       - chroot marker file
+ *  path/                   - chroot environment
+ *
+ * This layout is broken: the chroot marker file can be deleted in chroot
+ * and early when removing chroot is not fully done.
+ * In that case e2factory refuses to use and even delete the chroot 
+ * environment, leaving the user with a chroot environment that only
+ * root may delete.
+ *
+ * The new chroot layout fixes this:
+ *
+ * chroot layout used with the _2_3 postfix commands
+ * call with e2-su-2.2 <command> <base> ...
+ *  base/e2factory-chroot   - chroot marker file
+ *  base/chroot/            - chroot environment
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -109,6 +128,17 @@ void assert_chroot_environment(char *path)
        return;
 }
 
+void assert_chroot_environment_2_3(char *base)
+{
+       char name[PATH_MAX];
+       snprintf(name, sizeof(name), "%s/e2factory-chroot", base);
+       name[sizeof(name)-1]=0;
+       if(access(name, R_OK)) {
+               perr("not a chroot environment");
+       }
+       return;
+}
+
 int main(int argc, char *argv[])
 {
        int rc;
@@ -119,8 +149,6 @@ int main(int argc, char *argv[])
                perr("too many arguments");
        }
        char *cmd = argv[1];
-       char *path = argv[2];
-       assert_chroot_environment(path);
        if(!strcmp(cmd, "chroot_2_2")) {
                /* chroot_2_2 <path> ... */
                int i;
@@ -128,6 +156,8 @@ int main(int argc, char *argv[])
                if(argc < 3) {
                        perr("too few arguments");
                }
+               char *path = argv[2];
+               assert_chroot_environment(path);
                arg[0] = basename(chroot_tool);
                arg[1] = path;
                for (i=3; i < argc; i++) {
@@ -145,6 +175,8 @@ int main(int argc, char *argv[])
                if(argc != 5) {
                        perr("wrong number of arguments");
                }
+               char *path = argv[2];
+               assert_chroot_environment(path);
                char *tartype = argv[3];
                char *file = argv[4];
                char *tararg = NULL;
@@ -174,6 +206,8 @@ int main(int argc, char *argv[])
                if(argc != 3) {
                        perr("wrong number of arguments");
                }
+               char *path = argv[2];
+               assert_chroot_environment(path);
                arg[0] = basename(chown_tool);
                arg[1] = "root:root";
                arg[2] = path;
@@ -189,6 +223,106 @@ int main(int argc, char *argv[])
                if(argc != 3) {
                        perr("wrong number of arguments");
                }
+               char *path = argv[2];
+               assert_chroot_environment(path);
+               arg[0] = basename(rm_tool);
+               arg[1] = "-r";
+               arg[2] = "-f";
+               arg[3] = path;
+               arg[4] = NULL;
+               print_arg(arg);
+               setuid_root();
+               rc = execv(rm_tool, arg);
+               perror("can't exec");
+               exit(99);
+       } else if(!strcmp(cmd, "chroot_2_3")) {
+               /* chroot_2_3 <base> ... */
+               int i;
+               char *arg[256];
+               if(argc < 3) {
+                       perr("too few arguments");
+               }
+               char *base = argv[2];
+               char path[PATH_MAX];
+               snprintf(path, sizeof(path), "%s/chroot", base);
+               path[sizeof(path)-1] = 0;
+               assert_chroot_environment_2_3(base);
+               arg[0] = basename(chroot_tool);
+               arg[1] = path;
+               for (i=3; i < argc; i++) {
+                       arg[i-1] = argv[i];
+               }
+               arg[i-1] = 0;
+               print_arg(arg);
+               setuid_root();
+               rc = execv(chroot_tool, arg);
+               perror("can't exec");
+               exit(99);
+       } else if(!strcmp(cmd, "extract_tar_2_3")) {
+               /* extract_tar_2_3 <base> <tartype> <file> */
+               char *arg[256];
+               if(argc != 5) {
+                       perr("wrong number of arguments");
+               }
+               char *base = argv[2];
+               assert_chroot_environment_2_3(base);
+               char path[PATH_MAX];
+               snprintf(path, sizeof(path), "%s/chroot", base);
+               path[sizeof(path)-1] = 0;
+               char *tartype = argv[3];
+               char *file = argv[4];
+               char *tararg = NULL;
+               if(!strcmp(tartype, "tar.gz")) {
+                       tararg = "-xzf";
+               } else if(!strcmp(tartype, "tar.bz2")) {
+                       tararg = "-xjf";
+               } else if(!strcmp(tartype, "tar")) {
+                       tararg = "-xf";
+               } else {
+                       perr("wrong tararg argument");
+               }
+               arg[0] = basename(tar_tool);
+               arg[1] = "-C";
+               arg[2] = path;
+               arg[3] = tararg;
+               arg[4] = file;
+               arg[5] = NULL;
+               print_arg(arg);
+               setuid_root();
+               rc = execv(tar_tool, arg);
+               perror("can't exec");
+               exit(99);
+       } else if(!strcmp(cmd, "set_permissions_2_3")) {
+               /* set_permissions_2_3 <base> */
+               char *arg[256];
+               if(argc != 3) {
+                       perr("wrong number of arguments");
+               }
+               char *base = argv[2];
+               assert_chroot_environment_2_3(base);
+               char path[PATH_MAX];
+               snprintf(path, sizeof(path), "%s/chroot", base);
+               path[sizeof(path)-1] = 0;
+               arg[0] = basename(chown_tool);
+               arg[1] = "root:root";
+               arg[2] = path;
+               arg[3] = NULL;
+               print_arg(arg);
+               setuid_root();
+               rc = execv(chown_tool, arg);
+               perror("can't exec");
+               exit(99);
+       } else if(!strcmp(cmd, "remove_chroot_2_3")) {
+               /* remove_chroot_2_3 <base> */
+               char *arg[256];
+               if(argc != 3) {
+                       perr("wrong number of arguments");
+               }
+               char *base = argv[2];
+               assert_chroot_environment_2_3(base);
+               char path[PATH_MAX];
+               snprintf(path, sizeof(path), "%s/chroot", base);
+               path[sizeof(path)-1] = 0;
                arg[0] = basename(rm_tool);
                arg[1] = "-r";
                arg[2] = "-f";
index 5057160e041084c709e813fd037f43e6c912a727..c4035635cba39131a6d761999d3fc3dc6ccbf0a1 100644 (file)
@@ -131,7 +131,9 @@ end
 -- @field mode       table:  the build mode policy
 -- @field release id string: the release name
 -- @field info       table: the info table
+-- @field base       string: path to the build directory
 -- @field c         string: path to the chroot
+-- @field chroot_marker string: path to chroot marker file
 -- @field T          string: absolute path to the temporary build directory
 --                           inside chroot
 -- @field Tc         string: same as c.T but relative to c
@@ -168,7 +170,9 @@ function e2build.build_config(info, r)
   tab.mode = nil -- XXX
   tab.location = nil -- XXX info.project_location
   tab.release_id = nil -- XXX release_id
-  tab.c = string.format("%s/%s/%s/chroot", tmpdir, project, r)
+  tab.base = string.format("%s/%s/%s", tmpdir, project, r)
+  tab.c = string.format("%s/chroot", tab.base)
+  tab.chroot_marker = string.format("%s/e2factory-chroot", tab.base)
   tab.T = string.format("%s/%s/%s/chroot/%s", tmpdir, project, r, builddir)
   tab.Tc = string.format("/%s", builddir)
   tab.r = string.format("%s", r)
@@ -213,13 +217,13 @@ function e2build.setup_chroot(info, r, return_flags)
   if not rc then
     return false, e:cat(re)
   end
-  local rc, re = e2lib.touch(res.build_config.c .. "/emlix-chroot")
+  local rc, re = e2lib.touch(res.build_config.chroot_marker)
   if not rc then
     return false, e:cat(re)
   end
-  -- e2-su set_permissions_2_2 <chroot_path>
-  local args = string.format("set_permissions_2_2 '%s'",
-                                                       res.build_config.c)
+  -- e2-su set_permissions_2_3 <chroot_path>
+  local args = string.format("set_permissions_2_3 '%s'",
+                                                       res.build_config.base)
   local rc, re = e2lib.e2_su_2_2(args)
   if not rc then
     return false, e:cat(re)
@@ -247,9 +251,9 @@ function e2build.setup_chroot(info, r, return_flags)
                e:append("unknown archive type for chroot file: %s", path)
                return false, e
        end
-       -- e2-su extract_tar_2_2 <path> <tartype> <file>
-       local args = string.format("extract_tar_2_2 '%s' '%s' '%s'",
-                                       res.build_config.c, tartype, path)
+       -- e2-su extract_tar_2_3 <path> <tartype> <file>
+       local args = string.format("extract_tar_2_3 '%s' '%s' '%s'",
+                                       res.build_config.base, tartype, path)
        local rc, re = e2lib.e2_su_2_2(args)
        if not rc then
          return false, e:cat(re)
@@ -270,9 +274,9 @@ function e2build.enter_playground(info, r, chroot_command)
   e2lib.log(4, "entering playground for " .. r .. " ...")
   local term = e2lib.terminal
   local e2_su = transport.get_tool("e2-su-2.2")
-  local cmd = string.format("%s %s chroot_2_2 '%s' %s",
+  local cmd = string.format("%s %s chroot_2_3 '%s' %s",
                                res.build_config.chroot_call_prefix, e2_su, 
-                               res.build_config.c, chroot_command)
+                               res.build_config.base, chroot_command)
   os.execute(cmd)
   -- return code depends on user commands. Ignore.
   return true, nil
@@ -283,14 +287,14 @@ function e2build.fix_permissions(info, r, return_flags)
   local rc, re
   local e = new_error("fixing permissions failed")
   e2lib.log(3, "fix permissions")
-  local args = string.format("chroot_2_2 '%s' chown -R root:root '%s'",
-                               res.build_config.c, res.build_config.Tc)
+  local args = string.format("chroot_2_3 '%s' chown -R root:root '%s'",
+                               res.build_config.base, res.build_config.Tc)
   rc, re = e2lib.e2_su_2_2(args)
   if not rc then
     return false, e:cat(re)
   end
-  local args = string.format("chroot_2_2 '%s' chmod -R u=rwX,go=rX '%s'",
-                               res.build_config.c, res.build_config.Tc)
+  local args = string.format("chroot_2_3 '%s' chmod -R u=rwX,go=rX '%s'",
+                               res.build_config.base, res.build_config.Tc)
   rc, re = e2lib.e2_su_2_2(args)
   if not rc then
     return false, e:cat(re)
@@ -318,9 +322,9 @@ function e2build.runbuild(info, r, return_flags)
                        res.build_config.Tc, res.build_config.scriptdir,
                                        res.build_config.build_driver_file)
   local e2_su = transport.get_tool("e2-su-2.2")
-  local cmd = string.format("%s %s chroot_2_2 '%s' %s", 
+  local cmd = string.format("%s %s chroot_2_3 '%s' %s", 
                                res.build_config.chroot_call_prefix, e2_su, 
-                               res.build_config.c, runbuild)
+                               res.build_config.base, runbuild)
   -- the build log is written to an external logfile
   local out = luafile.open(res.build_config.buildlog, "w")
   local function logto(output)
@@ -346,11 +350,15 @@ function e2build.chroot_cleanup(info, r, return_flags)
   if res.keep_chroot then
     return true, nil
   end
-  local args = string.format("remove_chroot_2_2 '%s'", res.build_config.c)
+  local args = string.format("remove_chroot_2_3 '%s'", res.build_config.base)
   local rc, re = e2lib.e2_su_2_2(args)
   if not rc then
     return e:cat(re)
   end
+  rc, re = e2lib.rm(res.build_config.chroot_marker)
+  if not rc then
+    return false, e:cat(re)
+  end
   local f = string.format("%s/playground", info.root)
   local s = e2util.stat(f)
   if s and s.type == "symbolic-link" then
@@ -376,8 +384,7 @@ end
 -- @return bool
 function e2build.chroot_exists(info, r)
   local res = info.results[r]
-  local f = string.format("%s/emlix-chroot", res.build_config.c)
-  return e2lib.isfile(f)
+  return e2lib.isfile(res.build_config.chroot_marker)
 end
 
 function e2build.sources(info, r, return_flags)