From f3c3a1aa33bc3a34a5bef94d3643c3702cf925c6 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Thu, 19 Jun 2014 09:07:17 -0400 Subject: [PATCH] Remove execute_no_trans from unconfineddomain. execute_no_trans controls whether a domain can execve a program without switching to another domain. Exclude this permission from unconfineddomain, add it back to init, init_shell, and recovery for files in / and /system, and to kernel for files in / (to permit execution of init prior to setcon). Prohibit it otherwise for the kernel domain via neverallow. This ensures that if a kernel task attempts to execute a kernel usermodehelper for which no domain transition is defined, the exec will fail. Change-Id: Ie7b2349923672dd4f5faf7c068a6e5994fd0e4e3 Signed-off-by: Stephen Smalley --- init.te | 6 ++++++ init_shell.te | 4 ++++ kernel.te | 16 ++++++++++++++++ recovery.te | 4 ++++ unconfined.te | 10 +++++----- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/init.te b/init.te index 3f4d706..069f041 100644 --- a/init.te +++ b/init.te @@ -6,6 +6,12 @@ tmpfs_domain(init) allow init self:capability { sys_rawio mknod }; +# Run helpers from / or /system without changing domain. +# We do not include exec_type here since generally those +# should always involve a domain transition. +allow init rootfs:file execute_no_trans; +allow init system_file:file execute_no_trans; + # Running e2fsck or mkswap via fs_mgr. allow init dev_type:blk_file rw_file_perms; diff --git a/init_shell.te b/init_shell.te index d2e4d74..51dbd07 100644 --- a/init_shell.te +++ b/init_shell.te @@ -4,3 +4,7 @@ type init_shell, domain; domain_auto_trans(init, shell_exec, init_shell) permissive_or_unconfined(init_shell) + +# Run helpers from / or /system without changing domain. +allow init_shell rootfs:file execute_no_trans; +allow init_shell system_file:file execute_no_trans; diff --git a/kernel.te b/kernel.te index 08ccbf5..0844624 100644 --- a/kernel.te +++ b/kernel.te @@ -1,6 +1,9 @@ # Life begins with the kernel. type kernel, domain; +# Run /init before we have switched domains. +allow kernel rootfs:file execute_no_trans; + # setcon to init domain. allow kernel self:process setcurrent; allow kernel init:process dyntransition; @@ -38,3 +41,16 @@ allow kernel self:security setcheckreqprot; # The initial task starts in the kernel domain (assigned via # initial_sid_contexts), but nothing ever transitions to it. neverallow domain kernel:process { transition dyntransition }; + +# The kernel domain is never entered via an exec, nor should it +# ever execute a program outside the rootfs without changing to another domain. +# If you encounter an execute_no_trans denial on the kernel domain, then +# possible causes include: +# - The program is a kernel usermodehelper. In this case, define a domain +# for the program and domain_auto_trans() to it. +# - You failed to setcon u:r:init:s0 in your init.rc and thus your init +# program was left in the kernel domain and is now trying to execute +# some other program. Fix your init.rc file. +# - You are running an exploit which switched to the init task credentials +# and is then trying to exec a shell or other program. You lose! +neverallow kernel { file_type fs_type -rootfs }:file { entrypoint execute_no_trans }; diff --git a/recovery.te b/recovery.te index e98cf44..13c21c2 100644 --- a/recovery.te +++ b/recovery.te @@ -15,6 +15,10 @@ recovery_only(` # Set security contexts on files that are not known to the loaded policy. allow recovery self:capability2 mac_admin; + # Run helpers from / or /system without changing domain. + allow recovery rootfs:file execute_no_trans; + allow recovery system_file:file execute_no_trans; + # Mount filesystems. allow recovery rootfs:dir mounton; allow recovery fs_type:filesystem ~relabelto; diff --git a/unconfined.te b/unconfined.te index ce51f30..97a7da1 100644 --- a/unconfined.te +++ b/unconfined.te @@ -60,18 +60,18 @@ allow unconfineddomain { -shell_data_file }:{ dir lnk_file sock_file fifo_file } ~relabelto; allow unconfineddomain exec_type:dir r_dir_perms; -allow unconfineddomain exec_type:file { rx_file_perms execmod }; +allow unconfineddomain exec_type:file { r_file_perms execute execmod }; allow unconfineddomain exec_type:lnk_file r_file_perms; allow unconfineddomain system_file:dir r_dir_perms; -allow unconfineddomain system_file:file { rx_file_perms execmod }; +allow unconfineddomain system_file:file { r_file_perms execute execmod }; allow unconfineddomain system_file:lnk_file r_file_perms; allow unconfineddomain { fs_type -usermodehelper -proc_security -contextmount_type -}:{ chr_file file } ~{entrypoint execmod execute relabelto}; -allow unconfineddomain {dev_type -kmem_device}:{ chr_file file } ~{entrypoint execmod execute relabelto}; +}:{ chr_file file } ~{entrypoint execute_no_trans execmod execute relabelto}; +allow unconfineddomain {dev_type -kmem_device}:{ chr_file file } ~{entrypoint execute_no_trans execmod execute relabelto}; allow unconfineddomain { file_type -keystore_data_file @@ -80,7 +80,7 @@ allow unconfineddomain { -exec_type -security_file -shell_data_file -}:{ chr_file file } ~{entrypoint execmod execute relabelto}; +}:{ chr_file file } ~{entrypoint execute_no_trans execmod execute relabelto}; allow unconfineddomain rootfs:file execute; allow unconfineddomain contextmount_type:dir r_dir_perms; allow unconfineddomain contextmount_type:notdevfile_class_set r_file_perms;