History

Merge branch 'validate-policy-rules' into next-integrity

From "ima: Fix rule parsing bugs and extend KEXEC_CMDLINE rule support" coverletter. This series ultimately extends the supported IMA rule conditionals for the KEXEC_CMDLINE hook function. As of today, there's an imbalance in IMA language conditional support for KEXEC_CMDLINE rules in comparison to KEXEC_KERNEL_CHECK and KEXEC_INITRAMFS_CHECK rules. The KEXEC_CMDLINE rules do not support *any* conditionals so you cannot have a sequence of rules like this: dont_measure func=KEXEC_KERNEL_CHECK obj_type=foo_t dont_measure func=KEXEC_INITRAMFS_CHECK obj_type=foo_t dont_measure func=KEXEC_CMDLINE obj_type=foo_t measure func=KEXEC_KERNEL_CHECK measure func=KEXEC_INITRAMFS_CHECK measure func=KEXEC_CMDLINE Instead, KEXEC_CMDLINE rules can only be measured or not measured and there's no additional flexibility in today's implementation of the KEXEC_CMDLINE hook function. With this series, the above sequence of rules becomes valid and any calls to kexec_file_load() with a kernel and initramfs inode type of foo_t will not be measured (that includes the kernel cmdline buffer) while all other objects given to a kexec_file_load() syscall will be measured. There's obviously not an inode directly associated with the kernel cmdline buffer but this patch series ties the inode based decision making for KEXEC_CMDLINE to the kernel's inode. I think this will be intuitive to policy authors. While reading IMA code and preparing to make this change, I realized that the buffer based hook functions (KEXEC_CMDLINE and KEY_CHECK) are quite special in comparison to longer standing hook functions. These buffer based hook functions can only support measure actions and there are some restrictions on the conditionals that they support. However, the rule parser isn't enforcing any of those restrictions and IMA policy authors wouldn't have any immediate way of knowing that the policy that they wrote is invalid. For example, the sequence of rules above parses successfully in today's kernel but the "dont_measure func=KEXEC_CMDLINE ..." rule is incorrectly handled in ima_match_rules(). The dont_measure rule is *always* considered to be a match so, surprisingly, no KEXEC_CMDLINE measurements are made. While making the rule parser more strict, I realized that the parser does not correctly free all of the allocated memory associated with an ima_rule_entry when going down some error paths. Invalid policy loaded by the policy administrator could result in small memory leaks.

Mimi Zohar committed 6 years ago

Commit a068d932 parents 34e980b 483417710 files · +184 −94Browse files

Unified · Split

10 files
  1. include/linux/ima.h +2 −2
  2. kernel/kexec_file.c +1 −1
  3. security/integrity/ima/ima.h +6 −7
  4. security/integrity/ima/ima_api.c +1 −1
  5. security/integrity/ima/ima_appraise.c +1 −1
  6. security/integrity/ima/ima_asymmetric_keys.c +1 −1
  7. security/integrity/ima/ima_main.c +17 −6
  8. security/integrity/ima/ima_modsig.c +0 −20
  9. security/integrity/ima/ima_policy.c +154 −54
  10. security/integrity/ima/ima_queue_keys.c +1 −1
include/linux/ima.h+2−2
@@ -25,7 +25,7 @@ extern int ima_post_read_file(struct file *file, void *buf, loff_t size, · 24 unmodified lines
25 enum kernel_read_file_id id);25 enum kernel_read_file_id id);
26extern void ima_post_path_mknod(struct dentry *dentry);26extern void ima_post_path_mknod(struct dentry *dentry);
27extern int ima_file_hash(struct file *file, char *buf, size_t buf_size);27extern int ima_file_hash(struct file *file, char *buf, size_t buf_size);
28extern void ima_kexec_cmdline(const void *buf, int size);28extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size);
29 29
30#ifdef CONFIG_IMA_KEXEC30#ifdef CONFIG_IMA_KEXEC
31extern void ima_add_kexec_buffer(struct kimage *image);31extern void ima_add_kexec_buffer(struct kimage *image);
@@ -103,7 +103,7 @@ static inline int ima_file_hash(struct file *file, char *buf, size_t buf_size) · 71 unmodified lines
103 return -EOPNOTSUPP;103 return -EOPNOTSUPP;
104}104}
105 105
106static inline void ima_kexec_cmdline(const void *buf, int size) {}106static inline void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) {}
107#endif /* CONFIG_IMA */107#endif /* CONFIG_IMA */
108 108
109#ifndef CONFIG_IMA_KEXEC109#ifndef CONFIG_IMA_KEXEC
kernel/kexec_file.c+1−1
@@ -287,7 +287,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, · 286 unmodified lines
287 goto out;287 goto out;
288 }288 }
289 289
290 ima_kexec_cmdline(image->cmdline_buf,290 ima_kexec_cmdline(kernel_fd, image->cmdline_buf,
291 image->cmdline_buf_len - 1);291 image->cmdline_buf_len - 1);
292 }292 }
293 293
security/integrity/ima/ima.h+6−7
@@ -265,7 +265,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, · 264 unmodified lines
265 struct evm_ima_xattr_data *xattr_value,265 struct evm_ima_xattr_data *xattr_value,
266 int xattr_len, const struct modsig *modsig, int pcr,266 int xattr_len, const struct modsig *modsig, int pcr,
267 struct ima_template_desc *template_desc);267 struct ima_template_desc *template_desc);
268void process_buffer_measurement(const void *buf, int size,268void process_buffer_measurement(struct inode *inode, const void *buf, int size,
269 const char *eventname, enum ima_hooks func,269 const char *eventname, enum ima_hooks func,
270 int pcr, const char *keyring);270 int pcr, const char *keyring);
271void ima_audit_measurement(struct integrity_iint_cache *iint,271void ima_audit_measurement(struct integrity_iint_cache *iint,
@@ -372,7 +372,6 @@ static inline int ima_read_xattr(struct dentry *dentry, · 100 unmodified lines
372#endif /* CONFIG_IMA_APPRAISE */372#endif /* CONFIG_IMA_APPRAISE */
373 373
374#ifdef CONFIG_IMA_APPRAISE_MODSIG374#ifdef CONFIG_IMA_APPRAISE_MODSIG
375bool ima_hook_supports_modsig(enum ima_hooks func);
376int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,375int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
377 struct modsig **modsig);376 struct modsig **modsig);
378void ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size);377void ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size);
@@ -382,11 +381,6 @@ int ima_get_raw_modsig(const struct modsig *modsig, const void **data, · 3 unmodified lines
382 u32 *data_len);381 u32 *data_len);
383void ima_free_modsig(struct modsig *modsig);382void ima_free_modsig(struct modsig *modsig);
384#else383#else
385static inline bool ima_hook_supports_modsig(enum ima_hooks func)
386{
387 return false;
388}
389
390static inline int ima_read_modsig(enum ima_hooks func, const void *buf,384static inline int ima_read_modsig(enum ima_hooks func, const void *buf,
391 loff_t buf_len, struct modsig **modsig)385 loff_t buf_len, struct modsig **modsig)
392{386{
@@ -420,6 +414,7 @@ static inline void ima_free_modsig(struct modsig *modsig) · 27 unmodified lines
420#ifdef CONFIG_IMA_LSM_RULES414#ifdef CONFIG_IMA_LSM_RULES
421 415
422#define security_filter_rule_init security_audit_rule_init416#define security_filter_rule_init security_audit_rule_init
417#define security_filter_rule_free security_audit_rule_free
423#define security_filter_rule_match security_audit_rule_match418#define security_filter_rule_match security_audit_rule_match
424 419
425#else420#else
@@ -430,6 +425,10 @@ static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr, · 4 unmodified lines
430 return -EINVAL;425 return -EINVAL;
431}426}
432 427
428static inline void security_filter_rule_free(void *lsmrule)
429{
430}
431
433static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,432static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
434 void *lsmrule)433 void *lsmrule)
435{434{
security/integrity/ima/ima_api.c+1−1
@@ -162,7 +162,7 @@ err_out: · 161 unmodified lines
162 162
163/**163/**
164 * ima_get_action - appraise & measure decision based on policy.164 * ima_get_action - appraise & measure decision based on policy.
165 * @inode: pointer to inode to measure165 * @inode: pointer to the inode associated with the object being validated
166 * @cred: pointer to credentials structure to validate166 * @cred: pointer to credentials structure to validate
167 * @secid: secid of the task being validated167 * @secid: secid of the task being validated
168 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXEC,168 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXEC,
security/integrity/ima/ima_appraise.c+1−1
@@ -328,7 +328,7 @@ int ima_check_blacklist(struct integrity_iint_cache *iint, · 327 unmodified lines
328 328
329 rc = is_binary_blacklisted(digest, digestsize);329 rc = is_binary_blacklisted(digest, digestsize);
330 if ((rc == -EPERM) && (iint->flags & IMA_MEASURE))330 if ((rc == -EPERM) && (iint->flags & IMA_MEASURE))
331 process_buffer_measurement(digest, digestsize,331 process_buffer_measurement(NULL, digest, digestsize,
332 "blacklisted-hash", NONE,332 "blacklisted-hash", NONE,
333 pcr, NULL);333 pcr, NULL);
334 }334 }
security/integrity/ima/ima_asymmetric_keys.c+1−1
@@ -58,7 +58,7 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key, · 57 unmodified lines
58 * if the IMA policy is configured to measure a key linked58 * if the IMA policy is configured to measure a key linked
59 * to the given keyring.59 * to the given keyring.
60 */60 */
61 process_buffer_measurement(payload, payload_len,61 process_buffer_measurement(NULL, payload, payload_len,
62 keyring->description, KEY_CHECK, 0,62 keyring->description, KEY_CHECK, 0,
63 keyring->description);63 keyring->description);
64}64}
security/integrity/ima/ima_main.c+17−6
@@ -726,6 +726,7 @@ int ima_load_data(enum kernel_load_data_id id) · 725 unmodified lines
726 726
727/*727/*
728 * process_buffer_measurement - Measure the buffer to ima log.728 * process_buffer_measurement - Measure the buffer to ima log.
729 * @inode: inode associated with the object being measured (NULL for KEY_CHECK)
729 * @buf: pointer to the buffer that needs to be added to the log.730 * @buf: pointer to the buffer that needs to be added to the log.
730 * @size: size of buffer(in bytes).731 * @size: size of buffer(in bytes).
731 * @eventname: event name to be used for the buffer entry.732 * @eventname: event name to be used for the buffer entry.
@@ -735,7 +736,7 @@ int ima_load_data(enum kernel_load_data_id id) · 3 unmodified lines
735 *736 *
736 * Based on policy, the buffer is measured into the ima log.737 * Based on policy, the buffer is measured into the ima log.
737 */738 */
738void process_buffer_measurement(const void *buf, int size,739void process_buffer_measurement(struct inode *inode, const void *buf, int size,
739 const char *eventname, enum ima_hooks func,740 const char *eventname, enum ima_hooks func,
740 int pcr, const char *keyring)741 int pcr, const char *keyring)
741{742{
@@ -768,7 +769,7 @@ void process_buffer_measurement(const void *buf, int size, · 26 unmodified lines
768 */769 */
769 if (func) {770 if (func) {
770 security_task_getsecid(current, &secid);771 security_task_getsecid(current, &secid);
771 action = ima_get_action(NULL, current_cred(), secid, 0, func,772 action = ima_get_action(inode, current_cred(), secid, 0, func,
772 &pcr, &template, keyring);773 &pcr, &template, keyring);
773 if (!(action & IMA_MEASURE))774 if (!(action & IMA_MEASURE))
774 return;775 return;
@@ -823,16 +824,26 @@ out: · 48 unmodified lines
823 824
824/**825/**
825 * ima_kexec_cmdline - measure kexec cmdline boot args826 * ima_kexec_cmdline - measure kexec cmdline boot args
827 * @kernel_fd: file descriptor of the kexec kernel being loaded
826 * @buf: pointer to buffer828 * @buf: pointer to buffer
827 * @size: size of buffer829 * @size: size of buffer
828 *830 *
829 * Buffers can only be measured, not appraised.831 * Buffers can only be measured, not appraised.
830 */832 */
831void ima_kexec_cmdline(const void *buf, int size)833void ima_kexec_cmdline(int kernel_fd, const void *buf, int size)
832{834{
833 if (buf && size != 0)835 struct fd f;
834 process_buffer_measurement(buf, size, "kexec-cmdline",836
835 KEXEC_CMDLINE, 0, NULL);837 if (!buf || !size)
838 return;
839
840 f = fdget(kernel_fd);
841 if (!f.file)
842 return;
843
844 process_buffer_measurement(file_inode(f.file), buf, size,
845 "kexec-cmdline", KEXEC_CMDLINE, 0, NULL);
846 fdput(f);
836}847}
837 848
838static int __init init_ima(void)849static int __init init_ima(void)
security/integrity/ima/ima_modsig.c+0−20
@@ -32,26 +32,6 @@ struct modsig { · 31 unmodified lines
32 u8 raw_pkcs7[];32 u8 raw_pkcs7[];
33};33};
34 34
35/**
36 * ima_hook_supports_modsig - can the policy allow modsig for this hook?
37 *
38 * modsig is only supported by hooks using ima_post_read_file(), because only
39 * they preload the contents of the file in a buffer. FILE_CHECK does that in
40 * some cases, but not when reached from vfs_open(). POLICY_CHECK can support
41 * it, but it's not useful in practice because it's a text file so deny.
42 */
43bool ima_hook_supports_modsig(enum ima_hooks func)
44{
45 switch (func) {
46 case KEXEC_KERNEL_CHECK:
47 case KEXEC_INITRAMFS_CHECK:
48 case MODULE_CHECK:
49 return true;
50 default:
51 return false;
52 }
53}
54
55/*35/*
56 * ima_read_modsig - Read modsig from buf.36 * ima_read_modsig - Read modsig from buf.
57 *37 *
security/integrity/ima/ima_policy.c+154−54
@@ -74,7 +74,7 @@ struct ima_rule_entry { · 73 unmodified lines
74 int pcr;74 int pcr;
75 struct {75 struct {
76 void *rule; /* LSM file metadata specific */76 void *rule; /* LSM file metadata specific */
77 void *args_p; /* audit value */77 char *args_p; /* audit value */
78 int type; /* audit type */78 int type; /* audit type */
79 } lsm[MAX_LSM_RULES];79 } lsm[MAX_LSM_RULES];
80 char *fsname;80 char *fsname;
@@ -258,9 +258,24 @@ static void ima_lsm_free_rule(struct ima_rule_entry *entry) · 177 unmodified lines
258 int i;258 int i;
259 259
260 for (i = 0; i < MAX_LSM_RULES; i++) {260 for (i = 0; i < MAX_LSM_RULES; i++) {
261 kfree(entry->lsm[i].rule);261 security_filter_rule_free(entry->lsm[i].rule);
262 kfree(entry->lsm[i].args_p);262 kfree(entry->lsm[i].args_p);
263 }263 }
264}
265
266static void ima_free_rule(struct ima_rule_entry *entry)
267{
268 if (!entry)
269 return;
270
271 /*
272 * entry->template->fields may be allocated in ima_parse_rule() but that
273 * reference is owned by the corresponding ima_template_desc element in
274 * the defined_templates list and cannot be freed here
275 */
276 kfree(entry->fsname);
277 kfree(entry->keyrings);
278 ima_lsm_free_rule(entry);
264 kfree(entry);279 kfree(entry);
265}280}
266 281
@@ -285,10 +300,13 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) · 18 unmodified lines
285 continue;300 continue;
286 301
287 nentry->lsm[i].type = entry->lsm[i].type;302 nentry->lsm[i].type = entry->lsm[i].type;
288 nentry->lsm[i].args_p = kstrdup(entry->lsm[i].args_p,303 nentry->lsm[i].args_p = entry->lsm[i].args_p;
289 GFP_KERNEL);304 /*
290 if (!nentry->lsm[i].args_p)305 * Remove the reference from entry so that the associated
291 goto out_err;306 * memory will not be freed during a later call to
307 * ima_lsm_free_rule(entry).
308 */
309 entry->lsm[i].args_p = NULL;
292 310
293 security_filter_rule_init(nentry->lsm[i].type,311 security_filter_rule_init(nentry->lsm[i].type,
294 Audit_equal,312 Audit_equal,
@@ -296,13 +314,9 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) · 1 unmodified line
296 &nentry->lsm[i].rule);314 &nentry->lsm[i].rule);
297 if (!nentry->lsm[i].rule)315 if (!nentry->lsm[i].rule)
298 pr_warn("rule for LSM \'%s\' is undefined\n",316 pr_warn("rule for LSM \'%s\' is undefined\n",
299 (char *)entry->lsm[i].args_p);317 nentry->lsm[i].args_p);
300 }318 }
301 return nentry;319 return nentry;
302
303out_err:
304 ima_lsm_free_rule(nentry);
305 return NULL;
306}320}
307 321
308static int ima_lsm_update_rule(struct ima_rule_entry *entry)322static int ima_lsm_update_rule(struct ima_rule_entry *entry)
@@ -315,11 +329,29 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry) · 6 unmodified lines
315 329
316 list_replace_rcu(&entry->list, &nentry->list);330 list_replace_rcu(&entry->list, &nentry->list);
317 synchronize_rcu();331 synchronize_rcu();
332 /*
333 * ima_lsm_copy_rule() shallow copied all references, except for the
334 * LSM references, from entry to nentry so we only want to free the LSM
335 * references and the entry itself. All other memory refrences will now
336 * be owned by nentry.
337 */
318 ima_lsm_free_rule(entry);338 ima_lsm_free_rule(entry);
339 kfree(entry);
319 340
320 return 0;341 return 0;
321}342}
322 343
344static bool ima_rule_contains_lsm_cond(struct ima_rule_entry *entry)
345{
346 int i;
347
348 for (i = 0; i < MAX_LSM_RULES; i++)
349 if (entry->lsm[i].args_p)
350 return true;
351
352 return false;
353}
354
323/*355/*
324 * The LSM policy can be reloaded, leaving the IMA LSM based rules referring356 * The LSM policy can be reloaded, leaving the IMA LSM based rules referring
325 * to the old, stale LSM policy. Update the IMA LSM based rules to reflect357 * to the old, stale LSM policy. Update the IMA LSM based rules to reflect
@@ -328,17 +360,10 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry) · 2 unmodified lines
328static void ima_lsm_update_rules(void)360static void ima_lsm_update_rules(void)
329{361{
330 struct ima_rule_entry *entry, *e;362 struct ima_rule_entry *entry, *e;
331 int i, result, needs_update;363 int result;
332 364
333 list_for_each_entry_safe(entry, e, &ima_policy_rules, list) {365 list_for_each_entry_safe(entry, e, &ima_policy_rules, list) {
334 needs_update = 0;366 if (!ima_rule_contains_lsm_cond(entry))
335 for (i = 0; i < MAX_LSM_RULES; i++) {
336 if (entry->lsm[i].args_p) {
337 needs_update = 1;
338 break;
339 }
340 }
341 if (!needs_update)
342 continue;367 continue;
343 368
344 result = ima_lsm_update_rule(entry);369 result = ima_lsm_update_rule(entry);
@@ -418,13 +443,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, · 73 unmodified lines
418{443{
419 int i;444 int i;
420 445
421 if ((func == KEXEC_CMDLINE) || (func == KEY_CHECK)) {446 if (func == KEY_CHECK) {
422 if ((rule->flags & IMA_FUNC) && (rule->func == func)) {447 return (rule->flags & IMA_FUNC) && (rule->func == func) &&
423 if (func == KEY_CHECK)448 ima_match_keyring(rule, keyring, cred);
424 return ima_match_keyring(rule, keyring, cred);
425 return true;
426 }
427 return false;
428 }449 }
429 if ((rule->flags & IMA_FUNC) &&450 if ((rule->flags & IMA_FUNC) &&
430 (rule->func != func && func != POST_SETATTR))451 (rule->func != func && func != POST_SETATTR))
@@ -886,10 +907,11 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, · 455 unmodified lines
886 &entry->lsm[lsm_rule].rule);907 &entry->lsm[lsm_rule].rule);
887 if (!entry->lsm[lsm_rule].rule) {908 if (!entry->lsm[lsm_rule].rule) {
888 pr_warn("rule for LSM \'%s\' is undefined\n",909 pr_warn("rule for LSM \'%s\' is undefined\n",
889 (char *)entry->lsm[lsm_rule].args_p);910 entry->lsm[lsm_rule].args_p);
890 911
891 if (ima_rules == &ima_default_rules) {912 if (ima_rules == &ima_default_rules) {
892 kfree(entry->lsm[lsm_rule].args_p);913 kfree(entry->lsm[lsm_rule].args_p);
914 entry->lsm[lsm_rule].args_p = NULL;
893 result = -EINVAL;915 result = -EINVAL;
894 } else916 } else
895 result = 0;917 result = 0;
@@ -949,6 +971,96 @@ static void check_template_modsig(const struct ima_template_desc *template) · 53 unmodified lines
949#undef MSG971#undef MSG
950}972}
951 973
974static bool ima_validate_rule(struct ima_rule_entry *entry)
975{
976 /* Ensure that the action is set and is compatible with the flags */
977 if (entry->action == UNKNOWN)
978 return false;
979
980 if (entry->action != MEASURE && entry->flags & IMA_PCR)
981 return false;
982
983 if (entry->action != APPRAISE &&
984 entry->flags & (IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED | IMA_CHECK_BLACKLIST))
985 return false;
986
987 /*
988 * The IMA_FUNC bit must be set if and only if there's a valid hook
989 * function specified, and vice versa. Enforcing this property allows
990 * for the NONE case below to validate a rule without an explicit hook
991 * function.
992 */
993 if (((entry->flags & IMA_FUNC) && entry->func == NONE) ||
994 (!(entry->flags & IMA_FUNC) && entry->func != NONE))
995 return false;
996
997 /*
998 * Ensure that the hook function is compatible with the other
999 * components of the rule
1000 */
1001 switch (entry->func) {
1002 case NONE:
1003 case FILE_CHECK:
1004 case MMAP_CHECK:
1005 case BPRM_CHECK:
1006 case CREDS_CHECK:
1007 case POST_SETATTR:
1008 case FIRMWARE_CHECK:
1009 case POLICY_CHECK:
1010 if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
1011 IMA_UID | IMA_FOWNER | IMA_FSUUID |
1012 IMA_INMASK | IMA_EUID | IMA_PCR |
1013 IMA_FSNAME | IMA_DIGSIG_REQUIRED |
1014 IMA_PERMIT_DIRECTIO))
1015 return false;
1016
1017 break;
1018 case MODULE_CHECK:
1019 case KEXEC_KERNEL_CHECK:
1020 case KEXEC_INITRAMFS_CHECK:
1021 if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
1022 IMA_UID | IMA_FOWNER | IMA_FSUUID |
1023 IMA_INMASK | IMA_EUID | IMA_PCR |
1024 IMA_FSNAME | IMA_DIGSIG_REQUIRED |
1025 IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED |
1026 IMA_CHECK_BLACKLIST))
1027 return false;
1028
1029 break;
1030 case KEXEC_CMDLINE:
1031 if (entry->action & ~(MEASURE | DONT_MEASURE))
1032 return false;
1033
1034 if (entry->flags & ~(IMA_FUNC | IMA_FSMAGIC | IMA_UID |
1035 IMA_FOWNER | IMA_FSUUID | IMA_EUID |
1036 IMA_PCR | IMA_FSNAME))
1037 return false;
1038
1039 break;
1040 case KEY_CHECK:
1041 if (entry->action & ~(MEASURE | DONT_MEASURE))
1042 return false;
1043
1044 if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_PCR |
1045 IMA_KEYRINGS))
1046 return false;
1047
1048 if (ima_rule_contains_lsm_cond(entry))
1049 return false;
1050
1051 break;
1052 default:
1053 return false;
1054 }
1055
1056 /* Ensure that combinations of flags are compatible with each other */
1057 if (entry->flags & IMA_CHECK_BLACKLIST &&
1058 !(entry->flags & IMA_MODSIG_ALLOWED))
1059 return false;
1060
1061 return true;
1062}
1063
952static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)1064static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
953{1065{
954 struct audit_buffer *ab;1066 struct audit_buffer *ab;
@@ -1126,8 +1238,6 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) · 171 unmodified lines
1126 keyrings_len = strlen(args[0].from) + 1;1238 keyrings_len = strlen(args[0].from) + 1;
1127 1239
1128 if ((entry->keyrings) ||1240 if ((entry->keyrings) ||
1129 (entry->action != MEASURE) ||
1130 (entry->func != KEY_CHECK) ||
1131 (keyrings_len < 2)) {1241 (keyrings_len < 2)) {
1132 result = -EINVAL;1242 result = -EINVAL;
1133 break;1243 break;
@@ -1267,15 +1377,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) · 133 unmodified lines
1267 AUDIT_SUBJ_TYPE);1377 AUDIT_SUBJ_TYPE);
1268 break;1378 break;
1269 case Opt_appraise_type:1379 case Opt_appraise_type:
1270 if (entry->action != APPRAISE) {
1271 result = -EINVAL;
1272 break;
1273 }
1274
1275 ima_log_string(ab, "appraise_type", args[0].from);1380 ima_log_string(ab, "appraise_type", args[0].from);
1276 if ((strcmp(args[0].from, "imasig")) == 0)1381 if ((strcmp(args[0].from, "imasig")) == 0)
1277 entry->flags |= IMA_DIGSIG_REQUIRED;1382 entry->flags |= IMA_DIGSIG_REQUIRED;
1278 else if (ima_hook_supports_modsig(entry->func) &&1383 else if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) &&
1279 strcmp(args[0].from, "imasig|modsig") == 0)1384 strcmp(args[0].from, "imasig|modsig") == 0)
1280 entry->flags |= IMA_DIGSIG_REQUIRED |1385 entry->flags |= IMA_DIGSIG_REQUIRED |
1281 IMA_MODSIG_ALLOWED;1386 IMA_MODSIG_ALLOWED;
@@ -1284,17 +1389,16 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) · 2 unmodified lines
1284 break;1389 break;
1285 case Opt_appraise_flag:1390 case Opt_appraise_flag:
1286 ima_log_string(ab, "appraise_flag", args[0].from);1391 ima_log_string(ab, "appraise_flag", args[0].from);
1287 if (strstr(args[0].from, "blacklist"))1392 if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) &&
1393 strstr(args[0].from, "blacklist"))
1288 entry->flags |= IMA_CHECK_BLACKLIST;1394 entry->flags |= IMA_CHECK_BLACKLIST;
1395 else
1396 result = -EINVAL;
1289 break;1397 break;
1290 case Opt_permit_directio:1398 case Opt_permit_directio:
1291 entry->flags |= IMA_PERMIT_DIRECTIO;1399 entry->flags |= IMA_PERMIT_DIRECTIO;
1292 break;1400 break;
1293 case Opt_pcr:1401 case Opt_pcr:
1294 if (entry->action != MEASURE) {
1295 result = -EINVAL;
1296 break;
1297 }
1298 ima_log_string(ab, "pcr", args[0].from);1402 ima_log_string(ab, "pcr", args[0].from);
1299 1403
1300 result = kstrtoint(args[0].from, 10, &entry->pcr);1404 result = kstrtoint(args[0].from, 10, &entry->pcr);
@@ -1332,7 +1436,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) · 31 unmodified lines
1332 break;1436 break;
1333 }1437 }
1334 }1438 }
1335 if (!result && (entry->action == UNKNOWN))1439 if (!result && !ima_validate_rule(entry))
1336 result = -EINVAL;1440 result = -EINVAL;
1337 else if (entry->action == APPRAISE)1441 else if (entry->action == APPRAISE)
1338 temp_ima_appraise |= ima_appraise_flag(entry->func);1442 temp_ima_appraise |= ima_appraise_flag(entry->func);
@@ -1381,7 +1485,7 @@ ssize_t ima_parse_add_rule(char *rule) · 42 unmodified lines
1381 1485
1382 result = ima_parse_rule(p, entry);1486 result = ima_parse_rule(p, entry);
1383 if (result) {1487 if (result) {
1384 kfree(entry);1488 ima_free_rule(entry);
1385 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,1489 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
1386 NULL, op, "invalid-policy", result,1490 NULL, op, "invalid-policy", result,
1387 audit_info);1491 audit_info);
@@ -1402,15 +1506,11 @@ ssize_t ima_parse_add_rule(char *rule) · 14 unmodified lines
1402void ima_delete_rules(void)1506void ima_delete_rules(void)
1403{1507{
1404 struct ima_rule_entry *entry, *tmp;1508 struct ima_rule_entry *entry, *tmp;
1405 int i;
1406 1509
1407 temp_ima_appraise = 0;1510 temp_ima_appraise = 0;
1408 list_for_each_entry_safe(entry, tmp, &ima_temp_rules, list) {1511 list_for_each_entry_safe(entry, tmp, &ima_temp_rules, list) {
1409 for (i = 0; i < MAX_LSM_RULES; i++)
1410 kfree(entry->lsm[i].args_p);
1411
1412 list_del(&entry->list);1512 list_del(&entry->list);
1413 kfree(entry);1513 ima_free_rule(entry);
1414 }1514 }
1415}1515}
1416 1516
@@ -1589,27 +1689,27 @@ int ima_policy_show(struct seq_file *m, void *v) · 172 unmodified lines
1589 switch (i) {1689 switch (i) {
1590 case LSM_OBJ_USER:1690 case LSM_OBJ_USER:
1591 seq_printf(m, pt(Opt_obj_user),1691 seq_printf(m, pt(Opt_obj_user),
1592 (char *)entry->lsm[i].args_p);1692 entry->lsm[i].args_p);
1593 break;1693 break;
1594 case LSM_OBJ_ROLE:1694 case LSM_OBJ_ROLE:
1595 seq_printf(m, pt(Opt_obj_role),1695 seq_printf(m, pt(Opt_obj_role),
1596 (char *)entry->lsm[i].args_p);1696 entry->lsm[i].args_p);
1597 break;1697 break;
1598 case LSM_OBJ_TYPE:1698 case LSM_OBJ_TYPE:
1599 seq_printf(m, pt(Opt_obj_type),1699 seq_printf(m, pt(Opt_obj_type),
1600 (char *)entry->lsm[i].args_p);1700 entry->lsm[i].args_p);
1601 break;1701 break;
1602 case LSM_SUBJ_USER:1702 case LSM_SUBJ_USER:
1603 seq_printf(m, pt(Opt_subj_user),1703 seq_printf(m, pt(Opt_subj_user),
1604 (char *)entry->lsm[i].args_p);1704 entry->lsm[i].args_p);
1605 break;1705 break;
1606 case LSM_SUBJ_ROLE:1706 case LSM_SUBJ_ROLE:
1607 seq_printf(m, pt(Opt_subj_role),1707 seq_printf(m, pt(Opt_subj_role),
1608 (char *)entry->lsm[i].args_p);1708 entry->lsm[i].args_p);
1609 break;1709 break;
1610 case LSM_SUBJ_TYPE:1710 case LSM_SUBJ_TYPE:
1611 seq_printf(m, pt(Opt_subj_type),1711 seq_printf(m, pt(Opt_subj_type),
1612 (char *)entry->lsm[i].args_p);1712 entry->lsm[i].args_p);
1613 break;1713 break;
1614 }1714 }
1615 seq_puts(m, " ");1715 seq_puts(m, " ");
security/integrity/ima/ima_queue_keys.c+1−1
@@ -158,7 +158,7 @@ void ima_process_queued_keys(void) · 157 unmodified lines
158 158
159 list_for_each_entry_safe(entry, tmp, &ima_keys, list) {159 list_for_each_entry_safe(entry, tmp, &ima_keys, list) {
160 if (!timer_expired)160 if (!timer_expired)
161 process_buffer_measurement(entry->payload,161 process_buffer_measurement(NULL, entry->payload,
162 entry->payload_len,162 entry->payload_len,
163 entry->keyring_name,163 entry->keyring_name,
164 KEY_CHECK, 0,164 KEY_CHECK, 0,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t