Bug 684008

Summary: pE for /sbin/init has special logic that makes it unboundable
Product: Red Hat Enterprise Linux 6 Reporter: Eric Paris <eparis>
Component: kernelAssignee: Eric Paris <eparis>
Status: CLOSED ERRATA QA Contact: Jan Malanik <jmalanik>
Severity: unspecified Docs Contact:
Priority: high    
Version: 6.1CC: arozansk, jmalanik, mzywusko
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: kernel-2.6.32-130.el6 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-05-23 20:43:41 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Eric Paris 2011-03-10 21:46:46 UTC
In order to drop capabilities system wide we need to reduce the capability set of all userspace tasks.  This includes /sbin/init.  The problem is that the kernel has special logic when setting pE for /sbin/init.  Hopefully the upstream maintainers will agree this logic is unnecessary and we can drop it.  If not this whole effort might be in vain...

Upstream posting to discuss issue:
http://marc.info/?l=linux-security-module&m=129979322027008&w=2

text of original upstream posting:

As most of you know by now I'm trying to limit/drop capabilities system
wide and running into problems.  I finally have a nearly working
implementation but I still have problems with the init task.  My basic
premise is that I'm dropping capabilities from pI pE pP and pB(set)
inside an initrd before I launch the real /sbin/init.  The assumption
was that all userspace tasks would thus not be able to attain the
dropped capabilities.  (We all know the problems usermodehelper caused
with this situation.) I have, however, hit a problem with the global
init task itself.  We have special case logic, which I don't understand,
inside security/commoncap.c::cap_bprm_set_creds() which looks like so:

        /* For init, we want to retain the capabilities set in the initial
         * task.  Thus we skip the usual capability rules
         */
        if (!is_global_init(current)) {
                if (effective)
                        new->cap_effective = new->cap_permitted;
                else
                        cap_clear(new->cap_effective);
        }

Which causes my init task to end up with caps like:
	Name:   init
	Pid:    1
	PPid:   0
	CapInh: 0000000000000000
	CapPrm: fffffffffffcffff
	CapEff: fffffffffffffeff
	CapBnd: fffffffffffcffff

What you notice is that although pP, pI, and pB are being handled
properly pE is not.  pE is getting the CAP_INIT_EFF_SET (unrelated, why
do we still drop CAP_SETPCAP from this task?) and I don't have a way to
drop it.

Why do we have/need this logic?  If init wants to drop capabilities
across exec why shouldn't it be allowed to?  I commented out the corner
case and it seemed to work just fine with CapEff: fffffffffffcffff.

What's the logic here?  Can I drop it?

-Eric

Comment 2 Eric Paris 2011-03-12 00:20:15 UTC
upstream didn't believe the logic made any sense either.  I posted a patch to remove the logic for 6.1 BUT I included a new command line options caps_bound_init to enable the new change just to be safe....

Comment 3 RHEL Program Management 2011-03-12 00:39:18 UTC
This request was evaluated by Red Hat Product Management for inclusion
in a Red Hat Enterprise Linux maintenance release. Product Management has 
requested further review of this request by Red Hat Engineering, for potential
inclusion in a Red Hat Enterprise Linux Update release for currently deployed 
products. This request is not yet committed for inclusion in an Update release.

Comment 8 Aristeu Rozanski 2011-04-07 14:14:35 UTC
Patch(es) available on kernel-2.6.32-130.el6

Comment 11 Jan Malanik 2011-04-27 08:04:08 UTC
I can't verified it.
I tried kernel 2.6.32-125 and -130. I did 3 drops(cap_chown, cap_kill, both) for each kernel. In every case I see "fffffffffffffeff" in CapEff. I used dracut 004-50. 
Any ideas?

Comment 13 Eric Paris 2011-04-27 12:58:24 UTC
Did you use the correct command line including caps_bound_init ?

Comment 14 Jan Malanik 2011-04-29 06:22:54 UTC
IĀ used:
dracut -i /etc/caps.conf /etc/cmdline -a caps --add-drivers "`cat lsmod`" -f /boot/init_drop_kill_125.img "2.6.32-125.el6.x86_64"

where: cat /etc/caps.conf
rd.caps=1 
rd.caps.initdrop=cap_kill #cap_chown, or both
rd.caps.disablemodules=1 
rd.caps.disablekexec=1
rdloaddriver=autofs4,sunrpc,ipv6,dm_mirror,dm_region_hash,dm_log,uinput,power_meter,ses,enclosure,sg,dcdbas,microcode,serio_raw,ghes,hed,k10temp,hwmon,amd64_edac_mod,edac_core,edac_mce_amd,i2c_piix4,i2c_core,ext4,mbcache,jbd2,sr_mod,cdrom,sd_mod,crc_t10dif,ahci,megaraid_sas,dm_mod

/etc/cmdline doesn't exist
in "lsmod" file I have got list of modules.
Last parameter I changed for every kernel(-130,-125)

I uised configuration based on https://bugzilla.redhat.com/show_bug.cgi?id=677340#c12

Comment 15 Eric Paris 2011-04-29 13:36:50 UTC
Inside grub add "caps_bound_init" to the kernel line.  This patch is only activated when that is added to the cmdline.

Comment 16 Jan Malanik 2011-05-02 14:44:37 UTC
succesfully verified on -130 kernel for drop kill+chown I can see:
CapPrm: ffffffffffffffde
CapEff: ffffffffffffffde
CapBnd: ffffffffffffffde

Comment 17 errata-xmlrpc 2011-05-23 20:43:41 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHSA-2011-0542.html