Starting unrealircd after upgrade and reboot to hardened profile fails. No log information available. Uncommented the '&>/dev/null" in the /etc/init.d/unrealircd startup script and restarted showed the following error: * Loading IRCd configuration .. * unrealircd.conf:36: loadmodule /usr/lib/unrealircd/modules/commands.so: failed to load: tmp/FD48F6C0.commands.so: failed to map segment from shared object: Permission denied [error] IRCd configuration failed to load Running /usr/bin/unrealircd manually as root works fine, but is not practical for obvious reasons ;) Reproducible: Always Steps to Reproduce: 1. Rebuild system using hardened profile 1-a. rm /etc/make.profile && ln -s /usr/portage/profiles/hardened/x86/2.6/ 1-b. emerge --oneshot binutils gcc virtual/libc 1-c. emerge -e system 1-d. emerge -e world 1-e. emerge hardened-sources 1-f. compiled and installed hardened-sources 1-g. reboot 2. Change the /etc/init.d/unrealircd script and remove the '&>/dev/null' to show all startup errors 3. /etc/init.d/unrealircd start Actual Results: * Caching service dependencies ... [ ok ] * Starting unrealircd ... _ _ _ ___________ _____ _ | | | | | |_ _| ___ \/ __ \ | | | | | |_ __ _ __ ___ __ _| | | | | |_/ /| / \/ __| | | | | | '_ \| '__/ _ \/ _` | | | | | / | | / _` | | |_| | | | | | | __/ (_| | |_| |_| |\ \ | \__/\ (_| | \___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_| v3.2.7 using TRE 0.7.5 (LGPL) using OpenSSL 0.9.8g 19 Oct 2007 using zlib 1.2.3 * Loading IRCd configuration .. * unrealircd.conf:36: loadmodule /usr/lib/unrealircd/modules/commands.so: failed to load: tmp/FD48F6C0.commands.so: failed to map segment from shared object: Permission denied [error] IRCd configuration failed to load /tmp is mounted in memory and is noexec. <snip from /etc/fstab> none /tmp tmpfs noexec 0 0 emerge --info *********************************************************************************************** Portage 2.1.4.4 (hardened/x86/2.6, gcc-3.4.6, glibc-2.6.1-r0, 2.6.23-hardened-r7 i686) ================================================================= System uname: 2.6.23-hardened-r7 i686 Intel(R) Pentium(R) 4 CPU 2.40GHz Timestamp of tree: Tue, 01 Apr 2008 23:45:01 +0000 distcc 2.18.3 i686-pc-linux-gnu (protocols 1 and 2) (default port 3632) [disabled] app-shells/bash: 3.2_p17-r1 dev-lang/python: 2.4.4-r9 dev-python/pycrypto: 2.0.1-r6 sys-apps/baselayout: 1.12.11.1 sys-apps/sandbox: 1.2.18.1-r2 sys-devel/autoconf: 2.13, 2.61-r1 sys-devel/automake: 1.10 sys-devel/binutils: 2.18-r1 sys-devel/gcc-config: 1.4.0-r4 sys-devel/libtool: 1.5.26 virtual/os-headers: 2.6.23-r3 ACCEPT_KEYWORDS="x86" CBUILD="i686-pc-linux-gnu" CFLAGS="-O2 -march=pentium4 -pipe -fomit-frame-pointer" CHOST="i686-pc-linux-gnu" CONFIG_PROTECT="/etc /var/bind" CONFIG_PROTECT_MASK="/etc/env.d /etc/gconf /etc/revdep-rebuild /etc/terminfo /etc/udev/rules.d" CXXFLAGS="-O2 -march=pentium4 -pipe -fomit-frame-pointer" DISTDIR="/usr/distfiles" FEATURES="distlocks metadata-transfer sandbox sfperms strict unmerge-orphans userfetch" GENTOO_MIRRORS="ftp://gentoo.mirrors.tds.net/gentoo" MAKEOPTS="-j1" PKGDIR="/usr/portage/packages" PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --stats --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages" PORTAGE_TMPDIR="/var/tmp" PORTDIR="/usr/portage" PORTDIR_OVERLAY="/usr/overlay" SYNC="rsync://rsync.us.gentoo.org/gentoo-portage" USE="acl acpi berkdb bzip2 cracklib crypt gd hardened midi mmx nptl nptlonly pam pcre pic readline samba sse sse2 ssl tcpd threads urandom vim-syntax x86 xorg zlib" ALSA_CARDS="ali5451 als4000 atiixp atiixp-modem bt87x ca0106 cmipci emu10k1 emu10k1x ens1370 ens1371 es1938 es1968 fm801 hda-intel intel8x0 intel8x0m maestro3 trident usb-audio via82xx via82xx-modem ymfpci" ALSA_PCM_PLUGINS="adpcm alaw asym copy dmix dshare dsnoop empty extplug file hooks iec958 ioplug ladspa lfloat linear meter mulaw multi null plug rate route share shm softvol" APACHE2_MODULES="actions alias auth_basic auth_digest authn_anon authn_dbd authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache dav dav_fs dav_lock dbd deflate dir disk_cache env expires ext_filter file_cache filter headers ident imagemap include info log_config logio mem_cache mime mime_magic negotiation proxy proxy_ajp proxy_balancer proxy_connect proxy_http rewrite setenvif so speling status unique_id userdir usertrack vhost_alias" ELIBC="glibc" INPUT_DEVICES="mouse keyboard" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" USERLAND="GNU" VIDEO_CARDS="apm ark chips cirrus cyrix dummy fbdev glint i128 i740 i810 imstt mach64 mga neomagic nsc nv r128 radeon rendition s3 s3virge savage siliconmotion sis sisusb tdfx tga trident tseng v4l vesa vga via vmware voodoo" Unset: CPPFLAGS, CTARGET, EMERGE_DEFAULT_OPTS, INSTALL_MASK, LANG, LC_ALL, LDFLAGS, LINGUAS, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS
Seems to be a hardened problem.
Try strace..
Created attachment 154485 [details] strace of /usr/bin/unrealircd run as unrealircd user
open("tmp/C30FF564.commands.so", O_RDONLY) = 3 ... mmap2(NULL, 476256, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = -1 EACCES (Permission denied) This looks to me to have nothing to do with hardened really but rather due to your nonexec dirs. Ie you can't mmap() with PROT_EXEC from a dir thats mounted with noexec.
The .so might also lack a +x bit. Notice the invalid cross links.
The noexec flag for /tmp has been in place for over a year, and physically moved the server between offices in that time so it shouldn't be causing the problem. Plus, if the noexec was the problem, why does it work when running it as root instead of the unrealircd user. In my understanding, noexec doesn't care what user you are, and that's part of it's benefit...
It looks like the main module that is loaded does have the execute bit, but I can't tell on the /tmp copy. Those are created and cleaned faster than I know how to check. # ls -l /usr/lib/unrealircd/modules/commands.so -rwxr-xr-x 1 root root 434832 May 27 07:06 /usr/lib/unrealircd/modules/commands.so
I disabled tpe in /proc/sys/grsecurity/tpe and that allows me to execute the /usr/bin/unrealircd program as the unrealircd user. If I had to guess, I'd say the /tmp/[rand].commands.so copy of the file is owned by the unrealircd user and that gets blocked by the tpe options. Is there some way to disable copying the *.so files to /tmp before loading them? Or is there a patch that will do this?
(In reply to comment #8) > I disabled tpe in /proc/sys/grsecurity/tpe and that allows me to execute the > /usr/bin/unrealircd program as the unrealircd user. If I had to guess, I'd say > the /tmp/[rand].commands.so copy of the file is owned by the unrealircd user > and that gets blocked by the tpe options. > > Is there some way to disable copying the *.so files to /tmp before loading > them? Or is there a patch that will do this? > As a workaround you can configure the kernel to exclude a group from TPE restrictions. Otherwise looks like a design issue to be taken up with upstream imo. Leaving comments/decisions on this bug to solar though.
Created attachment 154757 [details, diff] unrealircd-3.2.7-r2-notmpmods.patch - disables copying modules before loading I don't like the idea of adding a daemon user to the tpe trusted group, that isn't an option for me. I've dug around the code a bit and created the attached patch and an overlay ebuild that applies the patch. It seems to work ok on a test machine, I'm going to update the production machine and test it there tomorrow. Can this be forwarded to a maintainer and/or upstream to verify that the patch is ok? I'd like to verify that by not copying the modules it won't cause other problems.
Chris, Can you personally take your patch to the upstream maintainers? That is the great thing about FOSS. Everybody shares.
Added to unrealircd's bug tracking system under their gentoo patch review thread. http://bugs.unrealircd.org/view.php?id=3705 Sorry about the delay. I'll mark the bug as UPSTEAM as soon as I get a confirmation from them.
(In reply to comment #4) > This looks to me to have nothing to do with hardened really but rather due to > your nonexec dirs. Ie you can't mmap() with PROT_EXEC from a dir thats mounted > with noexec. > This. First, I wanted to point out that the temporary .so is not stored in /tmp, but rather /etc/unrealircd/tmp, which by default is a symlink to /var/lib/unrealircd. Anyway, I reproduced this and got the same original failure but only when I remounted my /var as noexec. If you have a similar setup, I would assume that's the problem and nothing to do with tpe, however I question this as you said it worked fine for you as root. Also invalid cross link errors should be normal if Unreal's /etc and /var are on separate partitions.
(In reply to comment #9) > As a workaround you can configure the kernel to exclude a group from TPE > restrictions. Otherwise looks like a design issue to be taken up with upstream > imo. As the patch has not been taken upstream, I have followed Gordon suggestion. This is my rellevant kernel config: CONFIG_GRKERNSEC_TPE=y CONFIG_GRKERNSEC_TPE_ALL=y CONFIG_GRKERNSEC_TPE_INVERT=y CONFIG_GRKERNSEC_TPE_GID=10 and I have added unrealircd to the wheel group. I am now able to start and stop unrealircd. Thanks!
Is this reproducible on unrealircd-3.2.9 ? If not, I think this bug should be RESOLVED INVALID .
(In reply to comment #15) > Is this reproducible on unrealircd-3.2.9 ? If not, I think this bug should > be RESOLVED INVALID . I don’t think unrealircd has changed its module loading strategy. I don’t have a hardened system to test this on; maybe I should, maybe Gentoo should patch UnrealIRCd to act more like a system daemon and stop copying module files around.
This is cannot be fixed for the same reasons as upstream explained: https://bugs.unrealircd.org/view.php?id=3705