diff --git a/.gitignore b/.gitignore index 47e4b932..dafd785c 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,4 @@ GTAGS \#*# /build/ +out/ diff --git a/arch/arm64/configs/heroqlte_chnzc_defconfig b/arch/arm64/configs/heroqlte_chnzc_defconfig old mode 100644 new mode 100755 index 8d652a21..a25b6034 --- a/arch/arm64/configs/heroqlte_chnzc_defconfig +++ b/arch/arm64/configs/heroqlte_chnzc_defconfig @@ -4577,6 +4577,8 @@ CONFIG_SECURITY_SELINUX=y # CONFIG_SECURITY_SELINUX_BOOTPARAM is not set # CONFIG_SECURITY_SELINUX_DISABLE is not set CONFIG_SECURITY_SELINUX_DEVELOP=y +# CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE is not set +CONFIG_SECURITY_SELINUX_NEVER_ENFORCE=y CONFIG_SECURITY_SELINUX_AVC_STATS=y CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig index bca1b74a..c02362ec 100644 --- a/security/selinux/Kconfig +++ b/security/selinux/Kconfig @@ -65,6 +65,20 @@ config SECURITY_SELINUX_DEVELOP can interactively toggle the kernel between enforcing mode and permissive mode (if permitted by the policy) via /selinux/enforce. +config SECURITY_SELINUX_ALWAYS_ENFORCE + bool "NSA SELinux Always Enforcing" + depends on SECURITY_SELINUX_DEVELOP + default n + help + This option will prevent anything from setting SELinux to permissive. + +config SECURITY_SELINUX_NEVER_ENFORCE + bool "NSA SELinux Never Enforcing" + depends on SECURITY_SELINUX_DEVELOP + default n + help + This option will prevent anything from setting SELinux to enforcing. + config SECURITY_SELINUX_AVC_STATS bool "NSA SELinux AVC Statistics" depends on SECURITY_SELINUX @@ -74,6 +88,16 @@ config SECURITY_SELINUX_AVC_STATS /selinux/avc/cache_stats, which may be monitored via tools such as avcstat. +config SECURITY_SELINUX_ENFORCING + int "NSA SELinux Enforcing default value" + depends on SECURITY_SELINUX && !SECURITY_SELINUX_DEVELOP + range 0 1 + default 1 + help + This option sets the value of selinux_enforcing, permanently + deciding whether the kernel should run in enforcing or + permissive mode. + config SECURITY_SELINUX_CHECKREQPROT_VALUE int "NSA SELinux checkreqprot default value" depends on SECURITY_SELINUX diff --git a/security/selinux/Makefile b/security/selinux/Makefile index f63dbd87..b309c750 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -11,12 +11,6 @@ endif endif endif -ifeq ($(SEC_BUILD_OPTION_PRODUCT_SHIP), true) -ifeq ($(SEC_BUILD_OPTION_SELINUX_ENFORCE),true) -EXTRA_CFLAGS += -DCONFIG_ALWAYS_ENFORCE=true -endif -endif - obj-$(CONFIG_SECURITY_SELINUX) := selinux.o selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \ diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 342e8c37..cfb91fa1 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -1052,12 +1052,13 @@ static noinline int avc_denied(u32 ssid, u32 tsid, } #endif -#ifdef CONFIG_ALWAYS_ENFORCE +#if defined(CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE) if (!(avd->flags & AVD_FLAGS_PERMISSIVE)) -#else - if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) -#endif return -EACCES; +#elif !defined(CONFIG_SECURITY_SELINUX_NEVER_ENFORCE) + if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) + return -EACCES; +#endif avc_update_node(AVC_CALLBACK_GRANT, requested, cmd, ssid, tsid, tclass, avd->seqno, NULL, flags); diff --git a/security/selinux/exports.c b/security/selinux/exports.c index 9838a409..9c4e4c9c 100644 --- a/security/selinux/exports.c +++ b/security/selinux/exports.c @@ -19,7 +19,7 @@ bool selinux_is_enabled(void) { -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE return true; #else return selinux_enabled; @@ -29,8 +29,10 @@ EXPORT_SYMBOL_GPL(selinux_is_enabled); bool selinux_is_enforcing(void) { -#ifdef CONFIG_ALWAYS_ENFORCE +#if defined(CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE) return true; +#elif defined(CONFIG_SECURITY_SELINUX_NEVER_ENFORCE) + return false; #else return selinux_enforcing; #endif diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index dbe3b97f..39921cff 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -186,8 +186,10 @@ static int __init enforcing_setup(char *str) { unsigned long enforcing; if (!kstrtoul(str, 0, &enforcing)) -#ifdef CONFIG_ALWAYS_ENFORCE +#if defined(CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE) selinux_enforcing = 1; +#elif defined(CONFIG_SECURITY_SELINUX_NEVER_ENFORCE) + selinux_enforcing = 0; #else selinux_enforcing = enforcing ? 1 : 0; #endif @@ -203,7 +205,7 @@ static int __init selinux_enabled_setup(char *str) { unsigned long enabled; if (!kstrtoul(str, 0, &enabled)) -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE selinux_enabled = 1; #else selinux_enabled = enabled ? 1 : 0; @@ -5714,7 +5716,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) "SELinux: unrecognized netlink message:" " protocol=%hu nlmsg_type=%hu sclass=%hu\n", sk->sk_protocol, nlh->nlmsg_type, sksec->sclass); -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE if (security_get_allow_unknown()) #else if (!selinux_enforcing || security_get_allow_unknown()) @@ -7201,7 +7203,7 @@ static struct security_operations selinux_ops = { static __init int selinux_init(void) { if (!security_module_enable(&selinux_ops)) { -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE selinux_enabled = 1; #else selinux_enabled = 0; @@ -7231,8 +7233,10 @@ static __init int selinux_init(void) if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) panic("SELinux: Unable to register AVC netcache callback\n"); -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE selinux_enforcing = 1; +#elif defined(CONFIG_SECURITY_SELINUX_NEVER_ENFORCE) + selinux_enforcing = 0; #endif if (selinux_enforcing) printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); @@ -7305,7 +7309,7 @@ static struct nf_hook_ops selinux_nf_ops[] = { static int __init selinux_nf_ip_init(void) { int err; -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE selinux_enabled = 1; #endif if (!selinux_enabled) diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 3165d4ed..059ea4a2 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -22,7 +22,7 @@ #ifdef CONFIG_SECURITY_SELINUX_DEVELOP extern int selinux_enforcing; #else -#define selinux_enforcing 1 +#define selinux_enforcing CONFIG_SECURITY_SELINUX_ENFORCING #endif /* diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 4782dfa5..2e7a9d07 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -137,7 +137,7 @@ struct operation { /* definitions of av_decision.flags */ // START_SEC_SELINUX_PORTING_COMMON -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE #define AVD_FLAGS_PERMISSIVE 0x0000 #else #define AVD_FLAGS_PERMISSIVE 0x0001 diff --git a/security/selinux/netif.c b/security/selinux/netif.c index 0d5e9bb6..1ba10f50 100644 --- a/security/selinux/netif.c +++ b/security/selinux/netif.c @@ -278,7 +278,7 @@ static __init int sel_netif_init(void) { int i; -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE selinux_enabled = 1; #endif diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index be07c25d..cb25566e 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c @@ -305,7 +305,7 @@ static __init int sel_netnode_init(void) { int iter; -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE selinux_enabled = 1; #endif diff --git a/security/selinux/netport.c b/security/selinux/netport.c index bd7052be..5f39da85 100644 --- a/security/selinux/netport.c +++ b/security/selinux/netport.c @@ -239,7 +239,7 @@ static __init int sel_netport_init(void) { int iter; -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE selinux_enabled = 1; #endif diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 39a607aa..c71948a4 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -173,7 +173,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, if (sscanf(page, "%d", &new_value) != 1) goto out; -#ifdef CONFIG_ALWAYS_ENFORCE +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE // If build is user build and enforce option is set, selinux is always enforcing new_value = 1; length = task_has_security(current, SECURITY__SETENFORCE); @@ -186,6 +186,18 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, avc_ss_reset(0); selnl_notify_setenforce(new_value); selinux_status_update_setenforce(new_value); +#elif defined(CONFIG_SECURITY_SELINUX_NEVER_ENFORCE) + // If build is user build and permissive option is set, selinux is always permissive + new_value = 0; + length = task_has_security(current, SECURITY__SETENFORCE); + audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, + "config_never_enforce - true; enforcing=%d old_enforcing=%d auid=%u ses=%u", + new_value, selinux_enforcing, + from_kuid(&init_user_ns, audit_get_loginuid(current)), + audit_get_sessionid(current)); + selinux_enforcing = new_value; + selnl_notify_setenforce(new_value); + selinux_status_update_setenforce(new_value); #else if (new_value != selinux_enforcing) { length = task_has_security(current, SECURITY__SETENFORCE); diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 61c327a5..4506ec7f 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -1500,9 +1500,9 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) goto bad; return 0; bad: -#ifndef CONFIG_ALWAYS_ENFORCE +#ifndef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE panic("SELinux:Failed to type read"); -#endif /*CONFIG_ALWAYS_ENFORCE*/ +#endif /*CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE*/ type_destroy(key, typdatum, NULL); return rc; } @@ -2511,9 +2511,9 @@ int policydb_read(struct policydb *p, void *fp) out: return rc; bad: -#ifndef CONFIG_ALWAYS_ENFORCE +#ifndef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE panic("SELinux:Failed to load policy"); -#endif /*CONFIG_ALWAYS_ENFORCE*/ +#endif /*CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE*/ policydb_destroy(p); goto out; } diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ae9fbf3b..62ac6bc7 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -771,12 +771,13 @@ out: kfree(n); kfree(t); -#ifdef CONFIG_ALWAYS_ENFORCE - selinux_enforcing = 1; -#endif +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE + return -EPERM; +#else if (!selinux_enforcing) return 0; return -EPERM; +#endif } int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, @@ -1526,12 +1527,13 @@ out: kfree(t); kfree(n); -#ifdef CONFIG_ALWAYS_ENFORCE - selinux_enforcing = 1; -#endif +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE + return -EACCES; +#else if (!selinux_enforcing) return 0; return -EACCES; +#endif } static void filename_compute_type(struct policydb *p, struct context *newcontext, @@ -1820,9 +1822,9 @@ static inline int convert_context_handle_invalid_context(struct context *context char *s; u32 len; -#ifdef CONFIG_ALWAYS_ENFORCE - selinux_enforcing = 1; -#endif +#ifdef CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE + return -EINVAL; +#else if (selinux_enforcing) return -EINVAL; @@ -1831,6 +1833,7 @@ static inline int convert_context_handle_invalid_context(struct context *context kfree(s); } return 0; +#endif } struct convert_context_args { diff --git a/security/selinux/ss/status.c b/security/selinux/ss/status.c index fe815507..92d618ea 100644 --- a/security/selinux/ss/status.c +++ b/security/selinux/ss/status.c @@ -58,8 +58,10 @@ struct page *selinux_kernel_status_page(void) status->version = SELINUX_KERNEL_STATUS_VERSION; status->sequence = 0; -#ifdef CONFIG_ALWAYS_ENFORCE +#if defined(CONFIG_SECURITY_SELINUX_ALWAYS_ENFORCE) status->enforcing = 1; +#elif defined(CONFIG_SECURITY_SELINUX_NEVER_ENFORCE) + status->enforcing = 0; #else status->enforcing = selinux_enforcing; #endif