Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 216908 - TPE Invert GID misbehavior
Summary: TPE Invert GID misbehavior
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Hardened (show other bugs)
Hardware: AMD64 Linux
: High major (vote)
Assignee: The Gentoo Linux Hardened Kernel Team (OBSOLETE)
URL:
Whiteboard:
Keywords:
: 319745 (view as bug list)
Depends on:
Blocks:
 
Reported: 2008-04-08 16:01 UTC by Christian Holler
Modified: 2012-10-13 23:57 UTC (History)
6 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
Kernel config on the -r7 system (kernel.config,38.28 KB, text/plain)
2008-04-08 16:19 UTC, Christian Holler
Details
grsec-2.1.11-2.6.2X-tpe_all_invert-fix.patch (grsec-2.1.11-2.6.2X-tpe_all_invert-fix.patch,625 bytes, patch)
2008-04-08 21:31 UTC, Gordon Malm (RETIRED)
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Holler 2008-04-08 16:01:13 UTC
Hello all,

I found a very strange behavior of the TPE feature in hardened. The kernel configuration is as follows: (verified with hardened 2.6.23-r7 and -r9)

/proc/sys/kernel/grsecurity/tpe: 1
/proc/sys/kernel/grsecurity/tpe_gid: 1005
/proc/sys/kernel/grsecurity/tpe_restrict_all: 1

With two users A and B , which are BOTH in the tpe_gid group (and should therefore be excluded from TPE), user B now cannot execute files which are both owned and writable only by user A, and contained in a directory writable only by user A. If I change the directory owner to root, or B, then I can execute the file. See Steps to reproduce for a simple example.

Reproducible: Always

Steps to Reproduce:
1. You need 2 user accounts to test, in my case those were apache and mailman (causing the initial problems)
2. Add these 2 users to your TPE_GID group (1005)
3. Create a new directory /test (mkdir /test)
4. Create a file to execute inside (touch /test/blah && chmod +x /test/blah)
5. Set owners to second user (chown -R mailman:mailman /test)
6. Try to execute /test/blah as the second user (su -s /bin/bash apache , then /test/blah)
7. Check dmesg for the error

Actual Results:  
apache@ourserver / $ /test/blah
bash: /test/blah: Permission denied

dmesg:

grsec: From 134.96.247.46: denied untrusted exec of /test/blah by /bin/bash[bash:13620] uid/euid:81/81 gid/egid:81/81, parent /bin/bash[bash:13416] uid/euid:81/81 gid/egid:81/81

although

# getent group 1005
grsec_tpetrust:!:1005:portage,apache,mailman

# ls -alR /test/
/test/:
total 8
drwxr-xr-x  2 mailman mailman 4096 Apr  8 17:31 .
drwxr-xr-x 25 root    users   4096 Apr  8 17:48 ..
-rwxr-xr-x  1 mailman mailman    0 Apr  8 17:31 blah


Expected Results:  
Since both users are trusted, the file should have been executed properly. If the trusted user which runs the file also owns the contained directory (but not the writable(!) binary) , this is also the case, therefore this behavior is nonsense.



We verified this behavior both on AMD64 and x86, with both kernels r7 and r9.

From my point of view, it seemed already unreasonable that a user is still restricted somehow even if it is already in the TPE exclude group. If I set a user to be excluded from TPE, then I expect it to be excluded, but that doesn't happen either. The above behavior is a more special case where only trusted users are involved and no "untrusted" user is involved anywhere and still exec() gets denied. In my opinion, not only this very special behavior should be fixed, but the whole TPE exclude thing should be reviewed carefully. 

This behavior also breaks mailman completely on hardened systems with TPE!


emerge --info:

Portage 2.1.4.4 (default-linux/amd64/2006.1, gcc-4.1.2, glibc-2.6.1-r0, 2.6.23-hardened-r7 x86_64)
=================================================================
System uname: 2.6.23-hardened-r7 x86_64 Dual-Core AMD Opteron(tm) Processor 2214
Timestamp of tree: Tue, 08 Apr 2008 00:45:01 +0000
app-shells/bash:     3.2_p17-r1
dev-java/java-config: 1.3.7, 2.1.4
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.4_p6, 1.5, 1.6.3, 1.7.9-r1, 1.8.5-r3, 1.9.6-r2, 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="amd64"
CBUILD="x86_64-pc-linux-gnu"
CFLAGS="-pipe -O2 -march=opteron -fomit-frame-pointer -fforce-addr"
CHOST="x86_64-pc-linux-gnu"
CONFIG_PROTECT="/etc"
CONFIG_PROTECT_MASK="/etc/env.d /etc/env.d/java/ /etc/fonts/fonts.conf /etc/gconf /etc/php/apache2-php5/ext-active/ /etc/php/cgi-php5/ext-active/ /etc/php/cli-php5/ext-active/ /etc/revdep-rebuild /etc/terminfo /etc/texmf/web2c /etc/udev/rules.d"
CXXFLAGS="-pipe -O2 -march=opteron -fomit-frame-pointer -fforce-addr"
DISTDIR="/usr/portage/distfiles"
FEATURES="ccache distlocks metadata-transfer parallel-fetch sandbox sfperms strict unmerge-orphans userfetch userpriv usersandbox"
GENTOO_MIRRORS="http://gentoo.intergenia.de/ ftp://ftp.gentoo.mesh-solutions.com/gentoo/ http://gentoo.inode.at/ ftp://gentoo.inode.at/source/ http://ftp.easynet.nl/mirror/gentoo/ ftp://ftp.easynet.nl/mirror/gentoo/ http://linux.rz.ruhr-uni-bochum.de/download/gentoo-mirror/ http://www.ibiblio.org/pub/Linux/distributions/gentoo http://distfiles.gentoo.org http://www.ibiblio.org/pub/Linux/distributions/gentoo"
LINGUAS="en"
MAKEOPTS="-j4"
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/local/portage"
SYNC="rsync://rsync.de.gentoo.org/gentoo-portage"
USE="acl amd64 apache2 bash-completion berkdb bzip2 cli cracklib crypt cups dri expat fortran gdbm gpm iconv ipv6 isdnlog jpeg kerberos ldap logrotate mbox midi mudflap ncurses nptl nptlonly openmp pam pcre pdf perl png pop3d ppds pppd python readline reflection sasl session spl ssl tcltk threads tiff unicode xorg zlib" ALSA_CARDS="ali5451 als4000 atiixp atiixp-modem bt87x ca0106 cmipci 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="keyboard mouse evdev" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LINGUAS="en" USERLAND="GNU" VIDEO_CARDS="apm ark chips cirrus cyrix dummy fbdev glint i128 i810 mach64 mga neomagic 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, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS
Comment 1 Gordon Malm (RETIRED) gentoo-dev 2008-04-08 16:08:11 UTC
Please attach your kernel config as well.  Thanks.
Comment 2 Christian Holler 2008-04-08 16:19:12 UTC
Created attachment 149109 [details]
Kernel config on the -r7 system
Comment 3 Christian Holler 2008-04-08 21:28:21 UTC
I've just read again the description of the TPE settings, as well as the kernel source code that implements TPE and it seems to me that this behavior is indeed intended. If the INVERT option is on, then those in the exclude group are as well restricted according to the TPE_ALL option.

The behavior with TPE_INVERT and TPE_ALL at once enabled is not straight forward though, the description of the invert option says "If you say Y here, the group you specify in the TPE configuration will decide what group TPE restrictions will be *disabled* for.". This is not true with the TPE_ALL option enabled as well. Maybe the behavior with TPE_ALL+TPE_INVERT should be reviewed, it is however not a coding bug, rather a design/description problem.
Comment 4 Gordon Malm (RETIRED) gentoo-dev 2008-04-08 21:30:30 UTC
Confirmed the behavior reported by the OP.  Incoming patch changes behavior to that desired by OP.

I believe the existing behavior probably is a bug and not what upstream grsec had in mind, but I'll let spender speak for himself.  CCing him here now.
Comment 5 Gordon Malm (RETIRED) gentoo-dev 2008-04-08 21:31:13 UTC
Created attachment 149138 [details, diff]
grsec-2.1.11-2.6.2X-tpe_all_invert-fix.patch

grsec-2.1.11-2.6.2X-tpe_all_invert-fix.patch
Comment 6 Gordon Malm (RETIRED) gentoo-dev 2008-04-08 21:34:36 UTC
(In reply to comment #3)
> I've just read again the description of the TPE settings, as well as the kernel
> source code that implements TPE and it seems to me that this behavior is indeed
> intended. If the INVERT option is on, then those in the exclude group are as
> well restricted according to the TPE_ALL option.
> 
> The behavior with TPE_INVERT and TPE_ALL at once enabled is not straight
> forward though, the description of the invert option says "If you say Y here,
> the group you specify in the TPE configuration will decide what group TPE
> restrictions will be *disabled* for.". This is not true with the TPE_ALL option
> enabled as well. Maybe the behavior with TPE_ALL+TPE_INVERT should be reviewed,
> it is however not a coding bug, rather a design/description problem.
> 

I can see where you were coming from originally.  Seems to me when using INVERT+GID to exclude users from TPE restrictions, it should exclude them from all TPE restrictions.  But perhaps there is indeed good reason not to.
Comment 7 Christian Holler 2008-04-08 21:41:34 UTC
(In reply to comment #6)
> 
> I can see where you were coming from originally.  Seems to me when using
> INVERT+GID to exclude users from TPE restrictions, it should exclude them from
> all TPE restrictions.  But perhaps there is indeed good reason not to.
> 

Yes, I agree, that needs to be carefully thought.

The first point is: if the INVERT does not disable all TPE restrictions for a user in the group, then the description needs to state that (otherwise it is confusing).

Secondly: If user A is in the group and INVERT is on, the restriction then would be, as far as I understood, that no other user should be able to modify the code that user A may run. This makes of course sense. However, if that other user is a trusted one as well (also in the group), then there is no security problem from my point of view.

Thirdly: In my example, the second user still was able to modify the file the first user runs, so that restriction didn't even work as it should, it was only directory based for some reason.
Comment 8 Brad Spengler 2008-04-08 21:51:20 UTC
Since you have TPE_INVERT enabled, the normal TPE algorithm is applying to all nonroot users that aren't in the trusted group.  TPE_ALL applies a separate, weaker, restriction against all nonroot users.  If you want the trusted group to not be restricted, the correct thing to have done would be to not enable TPE_ALL.

-Brad
Comment 9 Christian Holler 2008-04-08 21:53:51 UTC
(In reply to comment #8)
> Since you have TPE_INVERT enabled, the normal TPE algorithm is applying to all
> nonroot users that aren't in the trusted group.  TPE_ALL applies a separate,
> weaker, restriction against all nonroot users.  If you want the trusted group
> to not be restricted, the correct thing to have done would be to not enable
> TPE_ALL.
> 
> -Brad
> 

I just came to that conclusion as well, thank you very much for clarifying. Maybe the description in the kernel should be altered such that it reflects this more clearly.
Comment 10 Brad Spengler 2008-04-08 21:57:39 UTC
I agree, though the name of the TPE_ALL feature: "Partially restrict non-root users" is clear, its description doesn't clearly account for the presence of TPE_INVERT.

-Brad
Comment 11 Dirk Tilger 2010-07-12 21:36:38 UTC
*** Bug 319745 has been marked as a duplicate of this bug. ***
Comment 12 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2010-08-16 22:00:18 UTC
Can you check that the additional groups were loaded for your test user?
Comment 13 Anthony Basile gentoo-dev 2012-10-13 22:20:46 UTC
The recent changes in 

    hardened-sources-2.6.32-r134
    hardened-sources-3.2.31
    hardened-sources-3.6.1

clarify this issue, so this bug is done.  Please reopen if you still think there's an issue here.
Comment 14 Francisco Blas Izquierdo Riera (RETIRED) gentoo-dev 2012-10-13 23:57:58 UTC
I though I had wrotten a cool nice doc for TPE for something...
http://www.gentoo.org/proj/en/hardened/grsec-tpe.xml