linux-xiaomi-chiron/security
Tyler Hicks 176377d97d ima: Pre-parse the list of keyrings in a KEY_CHECK rule
The ima_keyrings buffer was used as a work buffer for strsep()-based
parsing of the "keyrings=" option of an IMA policy rule. This parsing
was re-performed each time an asymmetric key was added to a kernel
keyring for each loaded policy rule that contained a "keyrings=" option.

An example rule specifying this option is:

 measure func=KEY_CHECK keyrings=a|b|c

The rule says to measure asymmetric keys added to any of the kernel
keyrings named "a", "b", or "c". The size of the buffer size was
equal to the size of the largest "keyrings=" value seen in a previously
loaded rule (5 + 1 for the NUL-terminator in the previous example) and
the buffer was pre-allocated at the time of policy load.

The pre-allocated buffer approach suffered from a couple bugs:

1) There was no locking around the use of the buffer so concurrent key
   add operations, to two different keyrings, would result in the
   strsep() loop of ima_match_keyring() to modify the buffer at the same
   time. This resulted in unexpected results from ima_match_keyring()
   and, therefore, could cause unintended keys to be measured or keys to
   not be measured when IMA policy intended for them to be measured.

2) If the kstrdup() that initialized entry->keyrings in ima_parse_rule()
   failed, the ima_keyrings buffer was freed and set to NULL even when a
   valid KEY_CHECK rule was previously loaded. The next KEY_CHECK event
   would trigger a call to strcpy() with a NULL destination pointer and
   crash the kernel.

Remove the need for a pre-allocated global buffer by parsing the list of
keyrings in a KEY_CHECK rule at the time of policy load. The
ima_rule_entry will contain an array of string pointers which point to
the name of each keyring specified in the rule. No string processing
needs to happen at the time of asymmetric key add so iterating through
the list and doing a string comparison is all that's required at the
time of policy check.

In the process of changing how the "keyrings=" policy option is handled,
a couple additional bugs were fixed:

1) The rule parser accepted rules containing invalid "keyrings=" values
   such as "a|b||c", "a|b|", or simply "|".

2) The /sys/kernel/security/ima/policy file did not display the entire
   "keyrings=" value if the list of keyrings was longer than what could
   fit in the fixed size tbuf buffer in ima_policy_show().

Fixes: 5c7bac9fb2 ("IMA: pre-allocate buffer to hold keyrings string")
Fixes: 2b60c0eced ("IMA: Read keyrings= option from the IMA policy")
Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-08-31 17:45:02 -04:00
..
apparmor Minor fixes for v5.9. 2020-08-11 14:30:36 -07:00
bpf bpf: lsm: Initialize the BPF LSM hooks 2020-03-30 01:34:00 +02:00
integrity ima: Pre-parse the list of keyrings in a KEY_CHECK rule 2020-08-31 17:45:02 -04:00
keys Minor fixes for v5.9. 2020-08-11 14:30:36 -07:00
loadpin block: move block-related definitions out of fs.h 2020-06-24 09:16:02 -06:00
lockdown Merge branch 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security 2020-06-02 17:36:24 -07:00
safesetid security/safesetid: Replace rcu_swap_protected() with rcu_replace_pointer() 2019-10-30 08:45:57 -07:00
selinux cap-checkpoint-restore-v5.9 2020-08-04 15:02:07 -07:00
smack Smack: prevent underflow in smk_set_cipso() 2020-07-27 13:35:12 -07:00
tomoyo mm/gup: remove task_struct pointer for all gup code 2020-08-12 10:58:04 -07:00
yama sysctl: pass kernel pointers to ->proc_handler 2020-04-27 02:07:40 -04:00
commoncap.c exec: Compute file based creds only once 2020-05-29 22:00:54 -05:00
device_cgroup.c device_cgroup: Cleanup cgroup eBPF device filter code 2020-04-13 14:41:54 -04:00
inode.c Merge branch 'work.mount0' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-07-19 10:42:02 -07:00
Kconfig Replace HTTP links with HTTPS ones: security 2020-08-06 12:00:05 -07:00
Kconfig.hardening security: allow using Clang's zero initialization for stack variables 2020-06-16 02:06:23 -07:00
lsm_audit.c audit: purge audit_log_string from the intra-kernel audit API 2020-07-21 11:12:31 -04:00
Makefile device_cgroup: Cleanup cgroup eBPF device filter code 2020-04-13 14:41:54 -04:00
min_addr.c sysctl: pass kernel pointers to ->proc_handler 2020-04-27 02:07:40 -04:00
security.c security: Fix hook iteration and default value for inode_copy_up_xattr 2020-06-23 16:39:23 -07:00