On 11/7/18 2:04 AM, Ishara Fernando wrote:
Thanks Stephen , so below are the details of my SELinux setup


*Centos Version* : CentOS release 6.2 (Final)
*Kernel version* : 2.6.32-220.el6.x86_64
*RPM package* : selinux-policy-mls-3.7.19-312.el6.noarch

That's quite old. Any particular reason you aren't at least on the latest CentOS 6.x release if not CentOS 7.x? CentOS/Fedora/RHEL-specific questions likely should go to the Fedora selinux list,
https://lists.fedoraproject.org/admin/lists/selinux.lists.fedoraproject.org/


*cat /etc/selinux/mls/contexts/securetty_types *
console_device_t
sysadm_tty_device_t
user_tty_device_t
staff_tty_device_t
auditadm_tty_device_t
secureadm_tty_device_t
user_devpts_t
sshd_devpts_t

*
*
*sestatus -v *
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        mls

Process contexts:
Current context:                system_u:system_r:sshd_t:s0-s15:c0.c1023

Your shell shouldn't be running in sshd_t; sshd should have transitioned to a user context (like root:sysadm_r:sysadm_t:... or staff_u:staff_r:staff_t:... or user_u:user_r:user_t:...). Were there errors from sshd in /var/log/secure or elsewhere?

Init context:                   unknown (Permission denied)

File contexts:
Controlling term:               system_u:object_r:sshd_devpts_t:s0
/etc/passwd                     system_u:object_r:etc_t:s0
/bin/bash                       system_u:object_r:shell_exec_t:s0
/bin/sh                         system_u:object_r:bin_t:s0 -> system_u:object_r:shell_exec_t:s0
/usr/sbin/sshd                  system_u:object_r:sshd_exec_t:s0


*Regarding the httpd process , i started the process by switching to a new role as follows , so that's why it has obtained the sshd_t type on the 'httpd' process*

[root@msc-ishara-system1 ~]# newrole -l s4-s5:c1,c2
Password:

[root@msc-ishara-system1 ~]# id -Z
system_u:system_r:*sshd_t*:s4-s5:c1,c2*
*
[root@msc-ishara-system1 ~]# /etc/init.d/httpd start

You first need to be in a proper user context before you do anything else. Otherwise any processes you start are likely to be in the wrong context too.

I created a CentOS 6.10 VM, installed the mls policy, changed /etc/selinux/config to specify permissive and mls, touched /.autorelabel, rebooted to relabel filesystems, then changed /etc/selinux/config to enforcing and rebooted again. If I try to ssh in as root, I get an error ("Unable to get valid context for root") and the connection is closed; /var/log/secure contains some additional error reporting from sshd. That seems like a bug in selinux-policy-mls.

If I run the following command:
# semanage login -m -s staff_u root # map root to staff role
then I can ssh in as root albeit with some errors about accessing /root files.

Then I can do the following to switch to the sysadm role:
# newrole -r sysadm_r

I can't directly run /etc/init.d/httpd at all:
# /etc/init.d/httpd start
-bash: /etc/init.d/httpd: Permission denied

Or via service:
# service httpd start
env: /etc/init.d/httpd: Permission denied

I think -mls policy required the use of run_init to run init scripts in the proper context, ala the original SELinux policy:
# run_init /etc/init.d/httpd start
# ps -eZ | grep httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1704 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1706 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1707 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1708 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1709 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1710 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1711 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1712 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1713 ? 00:00:00 httpd

However, if I switch levels before trying to do this, it fails:
# newrole -l s4-s5:c1,c2
# run_init /etc/init.d/httpd restart
execvp: Permission denied

And the denial is due to the change in levels:
# ausearch -i -m AVC -ts recent
type=SYSCALL msg=audit(11/07/2018 09:37:14.703:318) : arch=x86_64 syscall=execve success=no exit=-13(Permission denied) a0=0x7fffaf68a871 a1=0x7fffaf6893d0 a2=0x7fffaf6893e8 a3=0x7fffaf689030 items=0 ppid=1824 pid=1838 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=7 comm=run_init exe=/usr/sbin/run_init subj=staff_u:sysadm_r:run_init_t:s4-s5:c1,c2 key=(null) type=AVC msg=audit(11/07/2018 09:37:14.703:318) : avc: denied { transition } for pid=1838 comm=run_init path=/etc/rc.d/init.d/httpd dev=dm-0 ino=133288 scontext=staff_u:sysadm_r:run_init_t:s4-s5:c1,c2 tcontext=system_u:system_r:initrc_t:s0-s15:c0.c1023 tclass=process

run_init always tries to run the init script in the initrc_context, so you'd lose the caller's level even if you altered policy to allow this.

If I define a range_transition policy rule instead to automatically start httpd in that level:
# cat > httpdtrans.te <<EOF
policy_module(httpdtrans, 1.0)

require {
        type initrc_t;
        type httpd_exec_t;
        type httpd_t;
}

range_transition initrc_t httpd_exec_t:process s4 - s5:c1,c2;

mls_rangetrans_source(initrc_t)
mls_rangetrans_target(httpd_t)
EOF
# make -f /usr/share/selinux/devel/Makefile httpdtrans.pp
# semodule -i httpdtrans.pp

And then try to start httpd:
# run_init /etc/init.d/httpd start
Starting httpd:                                            [FAILED]

it still fails but due to various denials when httpd tries to write to various directories/files that are labeled s0.

# ausearch -i -m AVC -ts recent
type=SYSCALL msg=audit(11/07/2018 10:13:37.915:445) : arch=x86_64 syscall=open success=no exit=-13(Permission denied) a0=0x5565fcd6a070 a1=O_RDWR|O_CREAT|O_EXCL a2=0600 a3=0x7ffd99b94c80 items=0 ppid=2324 pid=2325 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=7 comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s4-s5:c1,c2 key=(null) type=AVC msg=audit(11/07/2018 10:13:37.915:445) : avc: denied { write } for pid=2325 comm=httpd name=tmp dev=dm-0 ino=12 scontext=system_u:system_r:httpd_t:s4-s5:c1,c2 tcontext=system_u:object_r:tmp_t:s0-s15:c0.c1023 tclass=dir
----
type=SYSCALL msg=audit(11/07/2018 10:13:37.919:450) : arch=x86_64 syscall=open success=no exit=-13(Permission denied) a0=0x5565fcde6e88 a1=O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC a2=0666 a3=0x7f9275f59af0 items=0 ppid=2324 pid=2325 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=7 comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s4-s5:c1,c2 key=(null) type=AVC msg=audit(11/07/2018 10:13:37.919:450) : avc: denied { append } for pid=2325 comm=httpd name=error_log dev=dm-0 ino=261766 scontext=system_u:system_r:httpd_t:s4-s5:c1,c2 tcontext=system_u:object_r:httpd_log_t:s0 tclass=file

You'd have to run httpd with a private /tmp and label httpd's persistent data directories/files appropriately to make that work. Doing this without using containers or VMs looks painful. And if using containers/VMs, you'd get MCS labeling and isolation for free under the default targeted policy, without needing to use MLS.



[root@msc-ishara-system1 ~]# ps auxZ  |  grep -i httpd
system_u:system_r:*sshd_t*:s4-s5:c1,c2 root 29220 0.0  0.4 262888  9244 ?        Ss   00:18   0:00 /usr/sbin/httpd system_u:system_r:*sshd_t*:s4-s5:c1,c2 apache 29223 0.0  0.2 262888 5264 ?       S    00:18   0:00 /usr/sbin/httpd

*
*
*And on the mlsconstraint statements for file read , i see the following constrain *

mlsconstrain { file } { read getattr execute  }
(  l1 l2  dom  t1 { sysadm_t aide_t system_cronjob_t ksmtuned_t sssd_t virtd_t xserver_t } ==  h1 l2  dom  &&  ||  t1 { bootloader_t pam_console_t logrotate_t dmidecode_t iptables_t auditadm_wm_t myuser_wm_t setfiles_mac_t initrc_t mcelog_t secadm_t sysadm_t fsadm_t getty_t kudzu_t lvm_t mdadm_t quota_t rpm_t xdm_t xguest_wm_t myuser2_wm_t setsebool_t newrole_t setrans_t user_wm_t local_login_t rpm_script_t tmpreaper_t devicekit_disk_t NetworkManager_t audisp_t auditd_t kernel_t crond_t cupsd_t hald_t init_t kdump_t klogd_t mount_t rshd_t sshd_t udev_t fsdaemon_t sssd_selinux_manager_t load_policy_t remote_login_t secadm_wm_t readahead_t system_dbusd_t staff_wm_t setfiles_t semanage_t consoletype_t auditctl_t rlogind_t vbetool_t } == ||  t2 { cupsd_var_run_t sssd_var_lib_t kvm_device_t null_device_t zero_device_t system_dbusd_var_run_t devlog_t devtty_t tmpfs_t xdm_t vhost_device_t httpd_bool_t tun_tap_device_t faillog_t setrans_t qemu_var_run_t anon_inodefs_t setrans_var_run_t crond_t cupsd_t ptmx_t *sshd_t* sssd_t virt_log_t system_dbusd_t proc_numa_t security_t initctl_t sudo_db_t syslogd_t xserver_t } ==  || );

Due to your kernel/policy version, the attribute names aren't preserved in the binary policy constraints so the above is the expanded list of types instead of showing the attribute name used in the source policy. You can see the attribute name in the source policy from the .src.rpm or from the upstream refpolicy. As noted above, sshd_t is exempted by the constraint so it isn't being confined for MLS file reads.

Also I would like to understand about the precedence check by the SELinux security server , assume if a *type is allowed* to read the file by the mlsconstrain statements as shown above , then does the security server check and compare for the security levels as well of the source process and the destination ? (In this case the apache process runs in *s4-s5:c1,c2 *, the linux user running the curl is mapped on SELinux user *s4-s5:c1,c2 *and the php file : /var/www/html/info.php is on *s0:c3 *)

The permission has to first be allowed by a TE allow rule, and then any constraints on the permission are evaluated and the permission is only allowed if all such constraints evaluate to true. This constraint includes the dominance comparison. In source form, the constraint is:
# the file "read" ops (note the check is dominance of the low level)
mlsconstrain { file } { read getattr execute }
        (( l1 dom l2 ) or
         (( t1 == mlsfilereadtoclr ) and ( h1 dom l2 )) or
         ( t1 == mlsfileread ) or
         ( t2 == mlstrustedobject ));

which means:
File read/getattr/execute permission are only allowed if:
1) the process low-level (l1) dominates the file low-level (l2), or
2) the process type (t1) has the mlsfilereadtoclr (read-up-to-clearance) atttribute and the process high-level (h1) dominates the file low-level (l2), or
3) the process type (t1) has the mlsfileread (read-up) attribute, or
4) the file type (t2) has the mlstrustedobject (e.g. /dev/null) attribute.

**

So in that case , any suggestions to bypass the constrain rule ?

I tried to create a new SELinux role so that it has no types at all (This didn't work though as it gets the selinux types for *user_u* for some reason) . Then I was planning to add just 1 new type (eg: testuser_t) and then map this new 'type' to the new SELinux role and then map this role to a Linux User . So in that case the Linux User will have one single type accessible and then I can run the 'curl' command on the apache endpoint to see if the Bell Lapadula condition works :) .

You would just need apache to run in its own domain (or any other domain that lacks mlsfileread). The problem you are currently having is that it is running in sshd's domain.
_______________________________________________
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.

Reply via email to