Still ongoing selinux policy and toolchain work in this area is needed and I should do more testing on a host machine with selinux disabled but this is the livecd patch I've got working as of today. I think that I want to make my print >> sys.stderr message actually be fatal. The reason for this is because setting selinux --disabled in the kickstart and not having /usr/sbin/lokkit results in an enabled livecd which doesn't work... No reason to just print a message and not stop the work if we know for sure the results are useless... This patch also has the f.close() fix that I sent yesterday, so it might not apply if you already applied that one... -Eric diff -Naupr imgcreate.orig/creator.py imgcreate/creator.py --- imgcreate.orig/creator.py 2008-05-06 12:16:08.000000000 -0400 +++ imgcreate/creator.py 2008-06-05 17:10:36.561313078 -0400 @@ -23,6 +23,7 @@ import sys import tempfile import shutil +import selinux import yum import rpm @@ -402,6 +403,52 @@ class ImageCreator(object): fstab.write(self._get_fstab()) fstab.close() + def __create_selinuxfs(self): + # if selinux exists on the host we need to lie to the chroot + if os.path.exists("/selinux/enforce"): + selinux_dir = self._instroot + "/selinux" + + # enforce=0 tells the chroot selinux is not enforcing + # policyvers=999 tell the chroot to make the highest version of policy it can + files = (('/enforce', '0'), + ('/policyvers', '999')) + for (file, value) in files: + fd = os.open(selinux_dir + file, os.O_WRONLY | os.O_TRUNC | os.O_CREAT) + os.write(fd, value) + os.close(fd) + + # we steal mls from the host system for now, might be best to always set it to 1???? + files = ("/mls",) + for file in files: + shutil.copyfile("/selinux" + file, selinux_dir + file) + + # make /load -> /dev/null so chroot policy loads don't hurt anything + os.mknod(selinux_dir + "/load", 0666 | stat.S_IFCHR, os.makedev(1, 3)) + + # selinux is on in the kickstart, so clean up as best we can to start + if kickstart.selinux_enabled(self.ks): + # label the fs like it is a root before the bind mounting + arglist = ["/sbin/setfiles", "-F", "-r", self._instroot, selinux.selinux_file_context_path(), self._instroot] + subprocess.call(arglist, close_fds = True) + # these dumb things don't get magically fixed, so make the user generic + for f in ("/proc", "/sys", "/selinux"): + arglist = ["/usr/bin/chcon", "-u", "system_u", self._instroot + f] + subprocess.call(arglist, close_fds = True) + + def __destroy_selinuxfs(self): + # if the system was running selinux clean up our lies + if os.path.exists("/selinux/enforce"): + files = ('/enforce', + '/policyvers', + '/mls', + '/load') + for file in files: + try: + os.unlink(self._instroot + "/selinux" + file) + except OSError: + pass + + def mount(self, base_on = None, cachedir = None): """Setup the target filesystem in preparation for an install. @@ -427,7 +474,7 @@ class ImageCreator(object): self._mount_instroot(base_on) - for d in ("/dev/pts", "/etc", "/boot", "/var/log", "/var/cache/yum"): + for d in ("/dev/pts", "/etc", "/boot", "/var/log", "/var/cache/yum", "/sys", "/proc", "/selinux"): makedirs(self._instroot + d) cachesrc = cachedir or (self.__builddir + "/yum-cache") @@ -439,10 +486,6 @@ class ImageCreator(object): (cachesrc, "/var/cache/yum")]: self.__bindmounts.append(BindChrootMount(f, self._instroot, dest)) - # /selinux should only be mounted if selinux is enabled (enforcing or permissive) - if kickstart.selinux_enabled(self.ks): - self.__bindmounts.append(BindChrootMount("/selinux", self._instroot, None)) - # Create minimum /dev origumask = os.umask(0000) devices = [('null', 1, 3, 0666), @@ -460,6 +503,8 @@ class ImageCreator(object): os.symlink('/proc/self/fd/2', self._instroot + "/dev/stderr") os.umask(origumask) + self.__create_selinuxfs() + self._do_bindmounts() os.symlink("../proc/mounts", self._instroot + "/etc/mtab") @@ -479,6 +524,8 @@ class ImageCreator(object): except OSError: pass + self.__destroy_selinuxfs() + self._undo_bindmounts() self._unmount_instroot() @@ -543,7 +590,17 @@ class ImageCreator(object): for pkg in kickstart.get_excluded(self.ks, self._get_excluded_packages()): ayum.deselectPackage(pkg) - + + # if the system is running selinux and the kickstart wants it disabled + # we need /usr/sbin/lokkit + def __can_handle_selinux(self, ayum): + has_req = 1 + file = "/usr/sbin/lokkit" + if not kickstart.selinux_enabled(self.ks) and os.path.exists("/selinux/enforce"): + has_req = ayum.installHasFile(file) + if not has_req: + print >> sys.stderr, "Dude, you need a package which provides %s for your selinux setup to work" %(file) + def install(self, repo_urls = {}): """Install packages into the install root. @@ -579,6 +636,9 @@ class ImageCreator(object): self.__select_packages(ayum) self.__select_groups(ayum) self.__deselect_packages(ayum) + + self.__can_handle_selinux(ayum) + ayum.runInstall() except yum.Errors.RepoError, e: raise CreatorError("Unable to download from repo : %s" % (e,)) diff -Naupr imgcreate.orig/kickstart.py imgcreate/kickstart.py --- imgcreate.orig/kickstart.py 2008-05-06 12:16:08.000000000 -0400 +++ imgcreate/kickstart.py 2008-06-04 14:56:35.033603440 -0400 @@ -369,14 +369,15 @@ class SelinuxConfig(KickstartConfig): path = self.path(fn) f = file(path, "w+") os.chmod(path, 0644) + f.close() if ksselinux.selinux == ksconstants.SELINUX_DISABLED: return - if not os.path.exists(self.path("/sbin/restorecon")): + if os.path.exists(self.path("/sbin/restorecon")): + self.call(["/sbin/restorecon", "-l", "-v", "-r", "-F", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/selinux", "/"]) + else: return - self.call(["/sbin/restorecon", "-l", "-v", "-r", "/"]) - def apply(self, ksselinux): if os.path.exists(self.path("/usr/sbin/lokkit")): args = ["/usr/sbin/lokkit", "-f", "--quiet", "--nostart"] diff -Naupr imgcreate.orig/yuminst.py imgcreate/yuminst.py --- imgcreate.orig/yuminst.py 2008-05-06 12:16:08.000000000 -0400 +++ imgcreate/yuminst.py 2008-06-05 17:00:00.574631892 -0400 @@ -79,7 +79,7 @@ class LiveCDYum(yum.YumBase): def selectPackage(self, pkg): """Select a given package. Can be specified with name.arch or name*""" return self.install(pattern = pkg) - + def deselectPackage(self, pkg): """Deselect package. Can be specified as name.arch or name*""" sp = pkg.rsplit(".", 2) @@ -138,6 +138,20 @@ class LiveCDYum(yum.YumBase): repo.setCallback(TextProgress()) self.repos.add(repo) return repo + + def installHasFile(self, file): + has_file = 0 + provides_pkg = self.whatProvides(file, None, None) + dlpkgs = map(lambda x: x.po, filter(lambda txmbr: txmbr.ts_state in ("i", "u"), self.tsInfo.getMembers())) + for p in dlpkgs: + for q in provides_pkg: + if (p == q): + has_file = 1 + if has_file: + return True + else: + return False + def runInstall(self): os.environ["HOME"] = "/" -- fedora-selinux-list mailing list fedora-selinux-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/fedora-selinux-list