Repoman crash on just after message "Downloading http://www.gentoo.org/dtd/metadata.dtd" with "Segmentation fault"
emerge info: portage # emerge info !!! SELinux not loaded: SELinux is not enabled. Portage 2.0.51.22-r2 (selinux/2005.1/x86, gcc-3.3.6, glibc-2.3.5-r1, 2.6.11-hardened-r15-xxxxx i686) ================================================================= System uname: 2.6.11-hardened-r15-xxxxx i686 Intel(R) Celeron(R) CPU 2.40GHz Gentoo Base System version 1.6.13 ccache version 2.3 [disabled] dev-lang/python: 2.3.5-r2 sys-apps/sandbox: 1.2.12 sys-devel/autoconf: 2.13, 2.59-r6 sys-devel/automake: 1.4_p6, 1.5, 1.6.3, 1.7.9-r1, 1.8.5-r3, 1.9.6 sys-devel/binutils: 2.15.92.0.2-r10 sys-devel/libtool: 1.5.18-r1 virtual/os-headers: 2.6.11-r2 ACCEPT_KEYWORDS="x86" AUTOCLEAN="yes" CBUILD="i686-pc-linux-gnu" CFLAGS="-O2 -mcpu=i686 -fomit-frame-pointer" CHOST="i686-pc-linux-gnu" CONFIG_PROTECT="/etc /usr/kde/2/share/config /usr/kde/3/share/config /usr/share/config /var/qmail/control" CONFIG_PROTECT_MASK="/etc/gconf /etc/terminfo /etc/env.d" CXXFLAGS="-O2 -mcpu=i686 -fomit-frame-pointer" DISTDIR="/usr/portage/distfiles" FEATURES="autoconfig distlocks sandbox selinux sfperms strict" GENTOO_MIRRORS="ftp://ftp.roedu.net/pub/mirrors/gentoo.org" PKGDIR="/usr/portage/packages" PORTAGE_TMPDIR="/var/tmp" PORTDIR="/usr/portage" PORTDIR_OVERLAY="/usr/portage_2" SYNC="rsync://rsync.europe.gentoo.org/gentoo-portage" USE="aalib adns apm bash-completition berkdb bzip2 clamav crypt curl gd gpm hardened hardenedphp lids ncurses pam perl pic pie png postgres python readline reiserfs selinux sse ssl x86 xml2 zlib userland_GNU kernel_linux elibc_glibc" Unset: ASFLAGS, CTARGET, LANG, LC_ALL, LDFLAGS, LINGUAS, MAKEOPTS last lines of strace repoman: open("/usr/portage/distfiles/.locks/metadata.dtd.portage_lockfile", O_RDWR|O_CREAT|O_LARGEFILE, 0660) = 3 fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}, 0x582a81c0) = 0 stat64("/usr/portage/distfiles/.locks/metadata.dtd.portage_lockfile", {st_mode=S_IFREG|0660, st_size=0, ...}) = 0 stat64("/usr/portage/distfiles/metadata.dtd", 0x582a8380) = -1 ENOENT (No such file or directory) stat64("/usr/portage/distfiles/metadata.dtd", 0x582a81c0) = -1 ENOENT (No such file or directory) access("/usr/portage/distfiles/metadata.dtd", W_OK) = -1 ENOENT (No such file or directory) write(2, ">>> Downloading http://www.gento"..., 55>>> Downloading http://www.gentoo.org/dtd/metadata.dtd ) = 55 open("/proc/self/attr/current", O_RDONLY|O_LARGEFILE) = 4 read(4, 0x14e06208, 4095) = -1 EINVAL (Invalid argument) close(4) = 0 --- SIGSEGV (Segmentation fault) @ 0 (0) --- +++ killed by SIGSEGV +++
What is your FETCHCOMMAND set to?
did you use enforcing mode? what error do you receive in dmesg after you run the repoman command? if your entire filesystem labeled as it should be? do a make -C /etc/security/selinux/src/policy restorelabels what is the output of `id` ?
I'm not convinced this is a selinux problem. For one, selinux isn't even enabled, as noted by the first message after running emerge info. So this causes none of the selinux-specific code in portage to be used (os.error is raised by import selinux). If selinux was enabled, the only reason something would fail with a segfault because of selinux would be that the program gets denied and is broken and thus doesn't handle the permission denied. Looking at the strace, it doesnt appear that FETCHCOMMAND has even been executed yet. I doublechecked portage.fetch, and the selinux code is still only executed if selinux_enabled.
I don't believe this to be a selinux bug, but it would seem that it is involved. Python just doesn't segfault on a regular healthy system. What is "/proc/self/attr/current"? Tracing through the code from the last print, I believe that the line of code that would create a system call is os.access(myc, os.X_OK) where myc is "/bin/bash". Not sure if that is helpful at all..
either way, it isnt a portage bug
The enforcing was off, and it never get to fetch command. After the reboot seem that he problem disappear and I can reproduce again.
Ups! :( After the reboot seem that the problem disappear and I can't reproduce again.
the bug can only be replicated if I boot my selinux machine with selinux=0. i will attach a small python script (excerpt from portage.py) that can show you where the problem might be. if I run it on my system the output is: ./test.py Not loaded, exception OSError SELinux is not enabled. selinux_enabled returned 0 selinux_enabled returned 1 which is very weird. if I make a C test program that only prints the return code is_selinux_enabled(), it will always report the correct result.
Created attachment 68806 [details] Little script that demonstrate the bug
More precisely the “main” of portage.py is called to times by repoman and the checks are executed twice. The first time is working OK but the second time it fails and leaves the selinux_enabled=1, and the program is crashing on con=selinux.getcontext() The following code from portage.py is guilty for the wrong checks: if 'selinux' in settings["USE"].split(" "): try: import selinux selinux_enabled=1 except OSError, e: writemsg(red("!!! SELinux not loaded: ")+str(e)+"\n") selinux_enabled=0 except ImportError: writemsg(red("!!! SELinux module not found.")+" Please verify that it was installed.\n") selinux_enabled=0 else: selinux_enabled=0
Created attachment 68822 [details, diff] A patch for fixing the problem I found a method to fix de problem. I had to learn python for this :( Here is the patch. The idea is that if the check was alredy made (and selinux allredy imported) skip the probe.
Comment on attachment 68822 [details, diff] A patch for fixing the problem patch doesn't exactly fix the problem..
jasons, what's occuring here is the python <2.4 bug (thought they fixed it in 2.4) where failed module imports (partial, really) are added to sys.modules. a 'fix' of sorts is upon catching the importerror try: del sys.modules["selinux"] except KeyError: pass The usual reload(portage) to regenerate settings in repoman is what's triggering it. It shouldn't be reloading, course, nor should python/portage eating itself like this. ;) That and turning off your selinux use flag, since you're _telling_ portage to load this crap ;)
Created attachment 68854 [details, diff] yoink the module if it fails. rephrasing comment #13, since I was half awake when I made it... It doesn't allow for reloads to change the selinux enabled state, which *can* occur validly via use flags (the inverse of your setup, USE="-selinux" when the capabilities were booted with). Meanwhile, stuck a sys.modules cleanup into svn.
InCVS also, since it's pretty minor.
Chris, why aren't you throwing an ImportError btw when selinux capabilities aren't present but selinux import is attempted? Additionally, why are you choking on import of selinux? Makes it hard to do the usual pydoc run on it.
Well we throw the oserror since its not an import error if selinux is disabled, because not all functions require selinux to be enabled. If this is not the typical behavior python modules, or if you have other ideas, I'm open to suggestion.
Created attachment 68907 [details, diff] selinux.prx patch Reworking of the selinux.prx source, throw OSError on func attempts, not on import; tagged in some documentation also. spb, suspect you're the one who gets to test this :)
As for testing the changes to the selinux module, sed -i -e 's:selinux_enabled=selinux.enabled:' portage.py covers it in conjunction with the earlier patch I posted here.
Portage side of this is out. I'll re-remove the dependency so this doesn't block a release. :)
updated python-selinux is stable