diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/Kconfig.hardening | 71 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 1 | ||||
-rw-r--r-- | security/integrity/platform_certs/efi_parser.c | 2 | ||||
-rw-r--r-- | security/security.c | 3 | ||||
-rw-r--r-- | security/selinux/hooks.c | 8 | ||||
-rw-r--r-- | security/selinux/include/classmap.h | 4 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 10 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 2 | ||||
-rw-r--r-- | security/smack/smack.h | 2 | ||||
-rw-r--r-- | security/smack/smack_access.c | 17 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 2 |
11 files changed, 81 insertions, 41 deletions
diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index a56c36470cb1..90cbaff86e13 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -29,6 +29,7 @@ choice prompt "Initialize kernel stack variables at function entry" default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS default INIT_STACK_ALL_PATTERN if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT_PATTERN + default INIT_STACK_ALL_ZERO if CC_HAS_AUTO_VAR_INIT_PATTERN default INIT_STACK_NONE help This option enables initialization of stack variables at @@ -39,11 +40,11 @@ choice syscalls. This chooses the level of coverage over classes of potentially - uninitialized variables. The selected class will be + uninitialized variables. The selected class of variable will be initialized before use in a function. config INIT_STACK_NONE - bool "no automatic initialization (weakest)" + bool "no automatic stack variable initialization (weakest)" help Disable automatic stack variable initialization. This leaves the kernel vulnerable to the standard @@ -80,7 +81,7 @@ choice and is disallowed. config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL - bool "zero-init anything passed by reference (very strong)" + bool "zero-init everything passed by reference (very strong)" depends on GCC_PLUGINS depends on !(KASAN && KASAN_STACK) select GCC_PLUGIN_STRUCTLEAK @@ -91,33 +92,44 @@ choice of uninitialized stack variable exploits and information exposures. + As a side-effect, this keeps a lot of variables on the + stack that can otherwise be optimized out, so combining + this with CONFIG_KASAN_STACK can lead to a stack overflow + and is disallowed. + config INIT_STACK_ALL_PATTERN - bool "0xAA-init everything on the stack (strongest)" + bool "pattern-init everything (strongest)" depends on CC_HAS_AUTO_VAR_INIT_PATTERN help - Initializes everything on the stack with a 0xAA - pattern. This is intended to eliminate all classes - of uninitialized stack variable exploits and information - exposures, even variables that were warned to have been - left uninitialized. + Initializes everything on the stack (including padding) + with a specific debug value. This is intended to eliminate + all classes of uninitialized stack variable exploits and + information exposures, even variables that were warned about + having been left uninitialized. Pattern initialization is known to provoke many existing bugs related to uninitialized locals, e.g. pointers receive - non-NULL values, buffer sizes and indices are very big. + non-NULL values, buffer sizes and indices are very big. The + pattern is situation-specific; Clang on 64-bit uses 0xAA + repeating for all types and padding except float and double + which use 0xFF repeating (-NaN). Clang on 32-bit uses 0xFF + repeating for all types and padding. config INIT_STACK_ALL_ZERO - bool "zero-init everything on the stack (strongest and safest)" + bool "zero-init everything (strongest and safest)" depends on CC_HAS_AUTO_VAR_INIT_ZERO help - Initializes everything on the stack with a zero - value. This is intended to eliminate all classes - of uninitialized stack variable exploits and information - exposures, even variables that were warned to have been - left uninitialized. - - Zero initialization provides safe defaults for strings, - pointers, indices and sizes, and is therefore - more suitable as a security mitigation measure. + Initializes everything on the stack (including padding) + with a zero value. This is intended to eliminate all + classes of uninitialized stack variable exploits and + information exposures, even variables that were warned + about having been left uninitialized. + + Zero initialization provides safe defaults for strings + (immediately NUL-terminated), pointers (NULL), indices + (index 0), and sizes (0 length), so it is therefore more + suitable as a production security mitigation than pattern + initialization. endchoice @@ -217,6 +229,25 @@ config INIT_ON_FREE_DEFAULT_ON touching "cold" memory areas. Most cases see 3-5% impact. Some synthetic workloads have measured as high as 8%. +config CC_HAS_ZERO_CALL_USED_REGS + def_bool $(cc-option,-fzero-call-used-regs=used-gpr) + +config ZERO_CALL_USED_REGS + bool "Enable register zeroing on function exit" + depends on CC_HAS_ZERO_CALL_USED_REGS + help + At the end of functions, always zero any caller-used register + contents. This helps ensure that temporary values are not + leaked beyond the function boundary. This means that register + contents are less likely to be available for side channels + and information exposures. Additionally, this helps reduce the + number of useful ROP gadgets by about 20% (and removes compiler + generated "write-what-where" gadgets) in the resulting kernel + image. This has a less than 1% performance impact on most + workloads. Image size growth depends on architecture, and should + be evaluated for suitability. For example, x86_64 grows by less + than 1%, and arm64 grows by about 5%. + endmenu endmenu diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index a734f7d5292c..465865412100 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -1024,6 +1024,7 @@ int ima_measure_critical_data(const char *event_label, event_label, hash, digest, digest_len); } +EXPORT_SYMBOL_GPL(ima_measure_critical_data); static int __init init_ima(void) { diff --git a/security/integrity/platform_certs/efi_parser.c b/security/integrity/platform_certs/efi_parser.c index 18f01f36fe6a..d98260f8402a 100644 --- a/security/integrity/platform_certs/efi_parser.c +++ b/security/integrity/platform_certs/efi_parser.c @@ -55,7 +55,7 @@ int __init parse_efi_signature_list( memcpy(&list, data, sizeof(list)); pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n", offs, - list.signature_type.b, list.signature_list_size, + &list.signature_type, list.signature_list_size, list.signature_header_size, list.signature_size); lsize = list.signature_list_size; diff --git a/security/security.c b/security/security.c index 09533cbb7221..9ffa9e9c5c55 100644 --- a/security/security.c +++ b/security/security.c @@ -58,10 +58,11 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = { [LOCKDOWN_MMIOTRACE] = "unsafe mmio", [LOCKDOWN_DEBUGFS] = "debugfs access", [LOCKDOWN_XMON_WR] = "xmon write access", + [LOCKDOWN_BPF_WRITE_USER] = "use of bpf to write user RAM", [LOCKDOWN_INTEGRITY_MAX] = "integrity", [LOCKDOWN_KCORE] = "/proc/kcore access", [LOCKDOWN_KPROBES] = "use of kprobes", - [LOCKDOWN_BPF_READ] = "use of bpf to read kernel RAM", + [LOCKDOWN_BPF_READ_KERNEL] = "use of bpf to read kernel RAM", [LOCKDOWN_PERF] = "unsafe use of perf", [LOCKDOWN_TRACEFS] = "use of tracefs", [LOCKDOWN_XMON_RW] = "xmon read and write access", diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b0032c42333e..6517f221d52c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1330,7 +1330,9 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc return SECCLASS_SMC_SOCKET; case PF_XDP: return SECCLASS_XDP_SOCKET; -#if PF_MAX > 45 + case PF_MCTP: + return SECCLASS_MCTP_SOCKET; +#if PF_MAX > 46 #error New address family defined, please update this function. #endif } @@ -3325,6 +3327,8 @@ static int selinux_inode_setxattr(struct user_namespace *mnt_userns, } ab = audit_log_start(audit_context(), GFP_ATOMIC, AUDIT_SELINUX_ERR); + if (!ab) + return rc; audit_log_format(ab, "op=setxattr invalid_context="); audit_log_n_untrustedstring(ab, value, audit_size); audit_log_end(ab); @@ -6552,6 +6556,8 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) ab = audit_log_start(audit_context(), GFP_ATOMIC, AUDIT_SELINUX_ERR); + if (!ab) + return error; audit_log_format(ab, "op=fscreate invalid_context="); audit_log_n_untrustedstring(ab, value, audit_size); audit_log_end(ab); diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 62d19bccf3de..084757ff4390 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -246,6 +246,8 @@ struct security_class_mapping secclass_map[] = { NULL } }, { "xdp_socket", { COMMON_SOCK_PERMS, NULL } }, + { "mctp_socket", + { COMMON_SOCK_PERMS, NULL } }, { "perf_event", { "open", "cpu", "kernel", "tracepoint", "read", "write", NULL } }, { "lockdown", @@ -255,6 +257,6 @@ struct security_class_mapping secclass_map[] = { { NULL } }; -#if PF_MAX > 45 +#if PF_MAX > 46 #error New address family defined, please update secclass_map. #endif diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index defc5ef35c66..0ae1b718194a 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -874,7 +874,7 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) rc = sidtab_init(s); if (rc) { pr_err("SELinux: out of memory on SID table init\n"); - goto out; + return rc; } head = p->ocontexts[OCON_ISID]; @@ -885,7 +885,7 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) if (sid == SECSID_NULL) { pr_err("SELinux: SID 0 was assigned a context.\n"); sidtab_destroy(s); - goto out; + return -EINVAL; } /* Ignore initial SIDs unused by this kernel. */ @@ -897,12 +897,10 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) pr_err("SELinux: unable to load initial SID %s.\n", name); sidtab_destroy(s); - goto out; + return rc; } } - rc = 0; -out: - return rc; + return 0; } int policydb_class_isvalid(struct policydb *p, unsigned int class) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index d84c77f370dc..e5f1b2757a83 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1673,6 +1673,8 @@ static int compute_sid_handle_invalid_context( if (context_struct_to_string(policydb, newcontext, &n, &nlen)) goto out; ab = audit_log_start(audit_context(), GFP_ATOMIC, AUDIT_SELINUX_ERR); + if (!ab) + goto out; audit_log_format(ab, "op=security_compute_sid invalid_context="); /* no need to record the NUL with untrusted strings */ diff --git a/security/smack/smack.h b/security/smack/smack.h index c3cfbdf4944a..99c3422596ab 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -302,7 +302,7 @@ int smack_populate_secattr(struct smack_known *skp); /* * Shared data. */ -extern int smack_enabled; +extern int smack_enabled __initdata; extern int smack_cipso_direct; extern int smack_cipso_mapped; extern struct smack_known *smack_net_ambient; diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 1f391f6a3d47..d2186e2757be 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -81,23 +81,22 @@ int log_policy = SMACK_AUDIT_DENIED; int smk_access_entry(char *subject_label, char *object_label, struct list_head *rule_list) { - int may = -ENOENT; struct smack_rule *srp; list_for_each_entry_rcu(srp, rule_list, list) { if (srp->smk_object->smk_known == object_label && srp->smk_subject->smk_known == subject_label) { - may = srp->smk_access; - break; + int may = srp->smk_access; + /* + * MAY_WRITE implies MAY_LOCK. + */ + if ((may & MAY_WRITE) == MAY_WRITE) + may |= MAY_LOCK; + return may; } } - /* - * MAY_WRITE implies MAY_LOCK. - */ - if ((may & MAY_WRITE) == MAY_WRITE) - may |= MAY_LOCK; - return may; + return -ENOENT; } /** diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 223a6da0e6dc..cacbe7518519 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -54,7 +54,7 @@ static DEFINE_MUTEX(smack_ipv6_lock); static LIST_HEAD(smk_ipv6_port_list); struct kmem_cache *smack_rule_cache; -int smack_enabled; +int smack_enabled __initdata; #define A(s) {"smack"#s, sizeof("smack"#s) - 1, Opt_##s} static struct { |