Re: Enforcing directory access control using categories

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2017-06-22 at 08:17 -0700, Bill D wrote:
> On 06/22/2017 07:56 AM, Stephen Smalley wrote:
> 
> > On Wed, 2017-06-21 at 14:19 -0700, Bill D wrote:
> > > On 06/21/2017 11:26 AM, Stephen Smalley wrote:
> > > 
> > > > On Wed, 2017-06-21 at 10:12 -0700, Bill D wrote:
> > > > > On 06/21/2017 09:23 AM, Stephen Smalley wrote:
> > > > > 
> > > > > > On Wed, 2017-06-21 at 08:58 -0700, Bill D wrote:
> > > > > > > Hello,
> > > > > > > 
> > > > > > > Is it possible to enforce directory read/write/execute
> > > > > > > control
> > > > > > > using
> > > > > > > categories?
> > > > > > > 
> > > > > > > For example, using a category, I would like Linux users
> > > > > > > assigned
> > > > > > > to
> > > > > > > that
> > > > > > > category to have read/write/execute rights to directory
> > > > > > > /opt/foo.
> > > > > > > 
> > > > > > > Other Linux users that do not have that category assigned
> > > > > > > should
> > > > > > > not
> > > > > > > have read/write/execute access to /opt/foo
> > > > > > > 
> > > > > > > I know this can be done with normal DAC procedures using
> > > > > > > groups
> > > > > > > and/or
> > > > > > > file permission tools such as chmod and chown.
> > > > > > > 
> > > > > > > And I also know that it can done with SELinux TE (i.e
> > > > > > > create
> > > > > > > an
> > > > > > > SELinux
> > > > > > > security policy)
> > > > > > > 
> > > > > > > But can it be done by using just categories?
> > > > > > 
> > > > > > Yes, that is how sandbox, libvirt, docker, and other tools
> > > > > > isolate
> > > > > > sandboxes, VMs, containers, etc.  And Android uses it for
> > > > > > user
> > > > > > isolation and potentially app isolation in the
> > > > > > future.  Categories
> > > > > > are
> > > > > > suitable when your primary goal is isolation.
> > > > > > 
> > > > > > In Fedora, you would need to mark the user domains as MCS
> > > > > > constrained
> > > > > > since that is no longer the default.  Depending on your
> > > > > > particular
> > > > > > goals, you might need to revise the MCS constraints, but
> > > > > > they
> > > > > > may
> > > > > > be
> > > > > > sufficient as is.
> > > > > 
> > > > > Thank you for the information.  I am using RHEL 6.9 and
> > > > > CentOS
> > > > > 6.9.
> > > > > 
> > > > > Any pointers on how to mark the user domains as MCS
> > > > > constrained
> > > > > and
> > > > > how
> > > > > to view the existing MCS constraints for verification?
> > > > 
> > > > Didn't Philip Seeley provide instructions for using categories
> > > > in
> > > > the
> > > > earlier discussion of controlling execution of Java JAR files?
> > > 
> > > Yes, I got that.
> > > 
> > > 
> > > > Looks like RHEL6 defined mcs_untrusted_proc(), while modern
> > > > Fedora
> > > > defines mcs_constrained() (in
> > > > /usr/share/selinux/devel/include/kernel/mcs.if). So, if you
> > > > wanted
> > > > to
> > > > just use user_t for the users, you would do something like:
> > > > 
> > > > # Make user_t MCS constrained.
> > > > $ cat mcsconstrained.te
> > > > require {
> > > > 	type user_t;
> > > > }
> > > > # NB: use mcs_constrained() if on Fedora or RHEL 7.
> > > > mcs_untrusted_proc(user_t)
> > > > 
> > > > # Build and install the above policy module.
> > > > $ make -f /usr/share/selinux/devel/Makefile mcsconstrained.pp
> > > > $ semodule -i mcsconstrained.pp
> > > > 
> > > > # Define a SELinux user that is authorized only for category 0.
> > > > $ semanage user -a -R user_r -rs0:c0 c0user_u
> > > > 
> > > > # Define a SELinux user that is authorized only for category 1.
> > > > $ semanage user -a -R user_r -rs0:c1 c1user_u
> > > > 
> > > > # Add a user with category 0 access.
> > > > $ useradd -Z c0user_u jack
> > > > 
> > > > # Add a user with category 1 access.
> > > > $ useradd -Z c1user_u mary
> > > > 
> > > > # Restrict /opt/foo to category 1 users.
> > > > $ semanage fcontext -a -t usr_t -r s0:c1 "/opt/foo(/.*)?"
> > > > $ restorecon -RF /opt/foo
> > > > 
> > > > Then login as jack and see if you can access /opt/foo, and
> > > > ditto
> > > > for
> > > > mary.
> > > > 
> > > > I suspect you are better off testing to confirm correct
> > > > operation
> > > > than
> > > > trying to read the constraints, but if you really want them,
> > > > you
> > > > can
> > > > see a version disassembled from binary policy via seinfo --
> > > > constrain,
> > > > or can just download the .src.rpm for selinux-policy and
> > > > extract
> > > > the
> > > > mcs file from it.  Looks like RHEL6 did not yet support
> > > > attribute
> > > > preservation in constraints, and still displayed them in
> > > > postfix
> > > > form,
> > > > so the seinfo --constrain output isn't very human-friendly (it
> > > > has
> > > > since improved).
> > > 
> > > I have tried your steps without success.  Here is what I did:
> > > 
> > > $ cat /etc/redhat-release
> > > Red Hat Enterprise Linux Server release 6.9 (Santiago)
> > > 
> > > # create the folder foo and a bash script
> > > $ mkdir -p /opt/foo
> > > $ echo 'echo hello' > /opt/foo/bar.sh
> > > $ chmod -R 770 /opt/foo
> > > $ chown -R admin:admin /opt/foo
> > > $ chcon -u system_u /opt/foo
> > > $ chcon -u system_u /opt/foo/bar.sh
> > > $ ls -aldtZ /opt/foo/ /opt/foo/bar.sh
> > > drwxrwx---. admin admin system_u:object_r:usr_t:SystemLow
> > > /opt/foo/
> > > -rwxrwx---. admin admin system_u:object_r:usr_t:SystemLow
> > > /opt/foo/bar.sh
> > > 
> > > $ getenforce
> > > Enforcing
> > > 
> > > $ setenforce 0
> > > 
> > > $ getenforce
> > > Permissive
> > > 
> > > $ vi /etc/selinux/targeted/setrans.conf
> > > 
> > > $ cat /etc/selinux/targeted/setrans.conf
> > > #
> > > # Multi-Category Security translation table for SELinux
> > > #
> > > # Uncomment the following to disable translation libary
> > > # disable=1
> > > #
> > > # Objects can be categorized with 0-1023 categories defined by
> > > the
> > > admin.
> > > # Objects can be in more than one category at a time.
> > > # Categories are stored in the system as c0-c1023.  Users can use
> > > this
> > > # table to translate the categories into a more meaningful
> > > output.
> > > # Examples:
> > > # s0:c0=CompanyConfidential
> > > # s0:c1=PatientRecord
> > > # s0:c2=Unclassified
> > > # s0:c3=TopSecret
> > > # s0:c1,c3=CompanyConfidentialRedHat
> > > s0:c0=CompanyConfidential
> > > s0:c1=PatientRecord
> > > s0=SystemLow
> > > s0-s0:c0.c1023=SystemLow-SystemHigh
> > > s0:c0.c1023=SystemHigh
> > > 
> > > $ service mcstrans restart
> > > Stopping
> > > mcstransd:                                        [  OK  ]
> > > Starting
> > > mcstransd:                                        [  OK  ]
> > > 
> > > $ chcat -L
> > > s0:c0                          CompanyConfidential
> > > s0:c1                          PatientRecord
> > > s0                             SystemLow
> > > s0-s0:c0.c1023                 SystemLow-SystemHigh
> > > s0:c0.c1023                    SystemHigh
> > > 
> > > $ cat mcsconstrained.te
> > > module mymcsmodule 1.0;
> > > 
> > > require {
> > >       type user_t;
> > > }
> > > # NB: use mcs_constrained() if on Fedora or RHEL 7.
> > > mcs_untrusted_proc(user_t)
> > > 
> > > # Build and install the above policy module.
> > > $ make -f /usr/share/selinux/devel/Makefile mcsconstrained.pp
> > > Compiling targeted mcsconstrained module
> > > /usr/bin/checkmodule:  loading policy configuration from
> > > tmp/mcsconstrained.tmp
> > > /usr/bin/checkmodule:  policy configuration loaded
> > > /usr/bin/checkmodule:  writing binary representation (version 10)
> > > to
> > > tmp/mcsconstrained.mod
> > > Creating targeted mcsconstrained.pp policy package
> > > rm tmp/mcsconstrained.mod tmp/mcsconstrained.mod.fc
> > > 
> > > $ semodule -i mcsconstrained.pp
> > > 
> > > # Define a SELinux user that is authorized only for category 0.
> > > $ semanage user -a -R user_r -rs0:c0 c0user_u
> > > 
> > > # Define a SELinux user that is authorized only for category 1.
> > > $ semanage user -a -R user_r -rs0:c1 c1user_u
> > > 
> > > # Add a user with category 0 access.
> > > $ useradd -Z c0user_u jack
> > > 
> > > # add jack to the admin group
> > > $ usermod -G admin jack
> > > 
> > > # Add a user with category 1 access.
> > > $ useradd -Z c1user_u mary
> > > 
> > > # add mary to the admin group
> > > $ usermod -G admin mary
> > > 
> > > # Restrict /opt/foo to category 1 users.
> > > $ semanage fcontext -a -t usr_t -r s0:c1 "/opt/foo(/.*)?"
> > > $ restorecon -RF /opt/foo
> > > 
> > > $ ls -aldtZ /opt/foo /opt/foo/bar.sh
> > > drwxrwx---. admin admin system_u:object_r:usr_t:PatientRecord
> > > /opt/foo
> > > -rwxrwx---. admin admin system_u:object_r:usr_t:PatientRecord
> > > /opt/foo/bar.sh
> > > 
> > > $ setenforce 1
> > > 
> > > Now logon as Linux user jack and notice that it is *not* able to
> > > write
> > > to /opt/foo and can't run /opt/foo/bar.sh which is expected
> > > 
> > > $ id
> > > uid=502(jack) gid=502(jack) groups=502(jack),501(admin)
> > > context=c0user_u:user_r:user_t:CompanyConfidential
> > > 
> > > $ id -Z
> > > c0user_u:user_r:user_t:CompanyConfidential
> > > 
> > > $ ls -aldtZ /opt/foo/ /opt/foo/bar.sh
> > > drwxrwx---. admin admin system_u:object_r:usr_t:PatientRecord
> > > /opt/foo/
> > > -rwxrwx---. admin admin system_u:object_r:usr_t:PatientRecord
> > > /opt/foo/bar.sh
> > > 
> > > $ touch /opt/foo/bar
> > > touch: cannot touch `/opt/foo/bar': Permission denied
> > > 
> > > $ /opt/foo/bar.sh
> > > -bash: /opt/foo/bar.sh: Permission denied
> > > 
> > > Now logon as Linux user mary and notice that it is able to run
> > > /opt/foo/bar.sh which is expected.
> > > However, mary is *not* able to write to /opt/foo which is *not*
> > > expected
> > > 
> > > $ id
> > > uid=503(mary) gid=503(mary) groups=503(mary),501(admin)
> > > context=c1user_u:user_r:user_t:PatientRecord
> > > 
> > > $ id -Z
> > > c1user_u:user_r:user_t:PatientRecord
> > > 
> > > $ ls -aldtZ /opt/foo/ /opt/foo/bar.sh
> > > drwxrwx---. admin admin system_u:object_r:usr_t:PatientRecord
> > > /opt/foo/
> > > -rwxrwx---. admin admin system_u:object_r:usr_t:PatientRecord
> > > /opt/foo/bar.sh
> > > 
> > > $ /opt/foo/bar.sh
> > > hello
> > > 
> > > $ touch /opt/foo/blah
> > > touch: cannot touch `/opt/foo/blah': Permission denied
> > > 
> > > Following is the denial details in /var/log/audit/audit.log:
> > > 
> > > type=AVC msg=audit(1498079143.988:16822): avc:  denied  { write }
> > > for
> > > pid=10393 comm="touch" name="foo" dev=dm-5 ino=3801089
> > > scontext=c1user_u:user_r:user_t:s0:c1
> > > tcontext=system_u:object_r:usr_t:s0:c1 tclass=dir
> > > type=SYSCALL msg=audit(1498079143.988:16822): arch=c000003e
> > > syscall=2
> > > success=no exit=-13 a0=7ffda4cab82d a1=941 a2=1b6 a3=7ffda4ca91d0
> > > items=2 ppid=10292 pid=10393 auid=503 uid=503 gid=503 euid=503
> > > suid=503
> > > fsuid=503 egid=503 sgid=503 fsgid=503 tty=pts2 ses=14
> > > comm="touch"
> > > exe="/bin/touch" subj=c1user_u:user_r:user_t:s0:c1 key="access"
> > > type=CWD msg=audit(1498079143.988:16822):  cwd="/home/mary"
> > > type=PATH msg=audit(1498079143.988:16822): item=0
> > > name="/opt/foo/"
> > > inode=3801089 dev=fd:05 mode=040770 ouid=501 ogid=501 rdev=00:00
> > > obj=system_u:object_r:usr_t:s0:c1 nametype=PARENT
> > > type=PATH msg=audit(1498079143.988:16822): item=1
> > > name="/opt/foo/blah"
> > > nametype=CREATE
> > > 
> > > Does it mean that we have to loosen up the access control for the
> > > usr_t
> > > type such as allowing it to write to directories?
> > > It seems like if we did that, then we would be opening up a
> > > security
> > > hole i.e. regular users can potentially write to the /usr
> > > directory?
> > 
> > Sorry, I should have suggested using another type for /opt/foo.
> > 
> > semanage fcontext -d "/opt/foo(/.*)?"
> > semanage fcontext -a -t user_home_dir_t -r s0:c1 "/opt/foo(/.*)?"
> > restorecon -RF /opt/foo
> 
> Thanks.  That resolves the issue of not being able to write to
> /opt/foo 
> but it now blocks executing /opt/foo/bar.sh as follows:
> 
> $ id
> uid=503(mary) gid=503(mary) groups=503(mary),501(admin) 
> context=c1user_u:user_r:user_t:PatientRecord
> 
> $ /opt/foo/bar.sh
> -bash: /opt/foo/bar.sh: Permission denied
> 
> And here are the file permissions for /opt/foo/bar.sh
> 
> # id
> uid=0(root) gid=0(root) groups=0(root) 
> context=unconfined_u:unconfined_r:unconfined_t:SystemLow-SystemHigh
> 
> # ls -aldtZ /opt/foo/bar.sh
> -rwxrwx---. admin admin
> system_u:object_r:user_home_dir_t:PatientRecord 
> /opt/foo/bar.sh
> 
> And here is the denial:
> 
> type=AVC msg=audit(1498144073.846:204627): avc:  denied  { execute } 
> for  pid=15033 comm="bash" name="bar.sh" dev=dm-5 ino=3801090 
> scontext=c1user_u:user_r:user_t:s0:c1 
> tcontext=system_u:object_r:user_home_dir_t:s0:c1 tclass=file
> type=SYSCALL msg=audit(1498144073.846:204627): arch=c000003e
> syscall=59 
> success=no exit=-13 a0=21bf870 a1=21b2f50 a2=21be210 a3=10 items=1 
> ppid=14879 pid=15033 auid=503 uid=503 gid=503 euid=503 suid=503 
> fsuid=503 egid=503 sgid=503 fsgid=503 tty=pts1 ses=155 comm="bash" 
> exe="/bin/bash" subj=c1user_u:user_r:user_t:s0:c1 key=(null)
> type=CWD msg=audit(1498144073.846:204627):  cwd="/home/mary"
> type=PATH msg=audit(1498144073.846:204627): item=0 
> name="/opt/foo/bar.sh" inode=3801090 dev=fd:05 mode=0100770 ouid=501 
> ogid=501 rdev=00:00 obj=system_u:object_r:user_home_dir_t:s0:c1 
> nametype=NORMAL

Sigh, if at first you don't succeed,
semanage fcontext -m -t user_home_t -r s0:c1 "/opt/foo(/.*)?"
restorecon -RF /opt/foo
_______________________________________________
selinux mailing list -- selinux@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to selinux-leave@xxxxxxxxxxxxxxxxxxxxxxx




[Index of Archives]     [Fedora Users]     [Fedora Desktop]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux