Re: Enforcing directory access control using categories

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

 



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
_______________________________________________
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