aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetko Manolov <petkan@mip-labs.com>2015-12-02 10:47:56 -0500
committerMimi Zohar <zohar@linux.vnet.ibm.com>2015-12-15 10:01:43 -0500
commit80eae209d63ac6361c7b445f7e7e41f39c044772 (patch)
treedb99b638e2688529f6f61756ffae56b64a95311b
parent41c89b64d7184a780f12f2cccdabe65cb2408893 (diff)
IMA: allow reading back the current IMA policy
It is often useful to be able to read back the IMA policy. It is even more important after introducing CONFIG_IMA_WRITE_POLICY. This option allows the root user to see the current policy rules. Signed-off-by: Zbigniew Jasinski <z.jasinski@samsung.com> Signed-off-by: Petko Manolov <petkan@mip-labs.com> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
-rw-r--r--security/integrity/ima/Kconfig10
-rw-r--r--security/integrity/ima/ima.h15
-rw-r--r--security/integrity/ima/ima_fs.c29
-rw-r--r--security/integrity/ima/ima_policy.c207
4 files changed, 253 insertions, 8 deletions
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 8d5e6e0e0937..e54a8a8dae94 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -118,6 +118,16 @@ config IMA_WRITE_POLICY
118 118
119 If unsure, say N. 119 If unsure, say N.
120 120
121config IMA_READ_POLICY
122 bool "Enable reading back the current IMA policy"
123 depends on IMA
124 default y if IMA_WRITE_POLICY
125 default n if !IMA_WRITE_POLICY
126 help
127 It is often useful to be able to read back the IMA policy. It is
128 even more important after introducing CONFIG_IMA_WRITE_POLICY.
129 This option allows the root user to see the current policy rules.
130
121config IMA_APPRAISE 131config IMA_APPRAISE
122 bool "Appraise integrity measurements" 132 bool "Appraise integrity measurements"
123 depends on IMA 133 depends on IMA
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 9e82367f5190..917407fb7e94 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -166,6 +166,10 @@ void ima_update_policy(void);
166void ima_update_policy_flag(void); 166void ima_update_policy_flag(void);
167ssize_t ima_parse_add_rule(char *); 167ssize_t ima_parse_add_rule(char *);
168void ima_delete_rules(void); 168void ima_delete_rules(void);
169void *ima_policy_start(struct seq_file *m, loff_t *pos);
170void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos);
171void ima_policy_stop(struct seq_file *m, void *v);
172int ima_policy_show(struct seq_file *m, void *v);
169 173
170/* Appraise integrity measurements */ 174/* Appraise integrity measurements */
171#define IMA_APPRAISE_ENFORCE 0x01 175#define IMA_APPRAISE_ENFORCE 0x01
@@ -250,5 +254,12 @@ static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
250{ 254{
251 return -EINVAL; 255 return -EINVAL;
252} 256}
253#endif /* CONFIG_IMA_LSM_RULES */ 257#endif /* CONFIG_IMA_TRUSTED_KEYRING */
254#endif 258
259#ifdef CONFIG_IMA_READ_POLICY
260#define POLICY_FILE_FLAGS (S_IWUSR | S_IRUSR)
261#else
262#define POLICY_FILE_FLAGS S_IWUSR
263#endif /* CONFIG_IMA_WRITE_POLICY */
264
265#endif /* __LINUX_IMA_H */
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index a3cf5c0ab501..eebb985fd083 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -311,14 +311,31 @@ enum ima_fs_flags {
311 311
312static unsigned long ima_fs_flags; 312static unsigned long ima_fs_flags;
313 313
314#ifdef CONFIG_IMA_READ_POLICY
315static const struct seq_operations ima_policy_seqops = {
316 .start = ima_policy_start,
317 .next = ima_policy_next,
318 .stop = ima_policy_stop,
319 .show = ima_policy_show,
320};
321#endif
322
314/* 323/*
315 * ima_open_policy: sequentialize access to the policy file 324 * ima_open_policy: sequentialize access to the policy file
316 */ 325 */
317static int ima_open_policy(struct inode *inode, struct file *filp) 326static int ima_open_policy(struct inode *inode, struct file *filp)
318{ 327{
319 /* No point in being allowed to open it if you aren't going to write */ 328 if (!(filp->f_flags & O_WRONLY)) {
320 if (!(filp->f_flags & O_WRONLY)) 329#ifndef CONFIG_IMA_READ_POLICY
321 return -EACCES; 330 return -EACCES;
331#else
332 if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
333 return -EACCES;
334 if (!capable(CAP_SYS_ADMIN))
335 return -EPERM;
336 return seq_open(filp, &ima_policy_seqops);
337#endif
338 }
322 if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags)) 339 if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
323 return -EBUSY; 340 return -EBUSY;
324 return 0; 341 return 0;
@@ -335,6 +352,9 @@ static int ima_release_policy(struct inode *inode, struct file *file)
335{ 352{
336 const char *cause = valid_policy ? "completed" : "failed"; 353 const char *cause = valid_policy ? "completed" : "failed";
337 354
355 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
356 return 0;
357
338 pr_info("IMA: policy update %s\n", cause); 358 pr_info("IMA: policy update %s\n", cause);
339 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, 359 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
340 "policy_update", cause, !valid_policy, 0); 360 "policy_update", cause, !valid_policy, 0);
@@ -345,6 +365,7 @@ static int ima_release_policy(struct inode *inode, struct file *file)
345 clear_bit(IMA_FS_BUSY, &ima_fs_flags); 365 clear_bit(IMA_FS_BUSY, &ima_fs_flags);
346 return 0; 366 return 0;
347 } 367 }
368
348 ima_update_policy(); 369 ima_update_policy();
349#ifndef CONFIG_IMA_WRITE_POLICY 370#ifndef CONFIG_IMA_WRITE_POLICY
350 securityfs_remove(ima_policy); 371 securityfs_remove(ima_policy);
@@ -358,6 +379,7 @@ static int ima_release_policy(struct inode *inode, struct file *file)
358static const struct file_operations ima_measure_policy_ops = { 379static const struct file_operations ima_measure_policy_ops = {
359 .open = ima_open_policy, 380 .open = ima_open_policy,
360 .write = ima_write_policy, 381 .write = ima_write_policy,
382 .read = seq_read,
361 .release = ima_release_policy, 383 .release = ima_release_policy,
362 .llseek = generic_file_llseek, 384 .llseek = generic_file_llseek,
363}; 385};
@@ -395,8 +417,7 @@ int __init ima_fs_init(void)
395 if (IS_ERR(violations)) 417 if (IS_ERR(violations))
396 goto out; 418 goto out;
397 419
398 ima_policy = securityfs_create_file("policy", 420 ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
399 S_IWUSR,
400 ima_dir, NULL, 421 ima_dir, NULL,
401 &ima_measure_policy_ops); 422 &ima_measure_policy_ops);
402 if (IS_ERR(ima_policy)) 423 if (IS_ERR(ima_policy))
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 10a0a9b9e22d..2f4e0f5f31e2 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -18,6 +18,7 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/rculist.h> 19#include <linux/rculist.h>
20#include <linux/genhd.h> 20#include <linux/genhd.h>
21#include <linux/seq_file.h>
21 22
22#include "ima.h" 23#include "ima.h"
23 24
@@ -458,8 +459,8 @@ enum {
458 Opt_obj_user, Opt_obj_role, Opt_obj_type, 459 Opt_obj_user, Opt_obj_role, Opt_obj_type,
459 Opt_subj_user, Opt_subj_role, Opt_subj_type, 460 Opt_subj_user, Opt_subj_role, Opt_subj_type,
460 Opt_func, Opt_mask, Opt_fsmagic, 461 Opt_func, Opt_mask, Opt_fsmagic,
461 Opt_uid, Opt_euid, Opt_fowner, 462 Opt_fsuuid, Opt_uid, Opt_euid, Opt_fowner,
462 Opt_appraise_type, Opt_fsuuid, Opt_permit_directio 463 Opt_appraise_type, Opt_permit_directio
463}; 464};
464 465
465static match_table_t policy_tokens = { 466static match_table_t policy_tokens = {
@@ -828,3 +829,205 @@ void ima_delete_rules(void)
828 kfree(entry); 829 kfree(entry);
829 } 830 }
830} 831}
832
833#ifdef CONFIG_IMA_READ_POLICY
834enum {
835 mask_exec = 0, mask_write, mask_read, mask_append
836};
837
838static char *mask_tokens[] = {
839 "MAY_EXEC",
840 "MAY_WRITE",
841 "MAY_READ",
842 "MAY_APPEND"
843};
844
845enum {
846 func_file = 0, func_mmap, func_bprm,
847 func_module, func_firmware, func_post
848};
849
850static char *func_tokens[] = {
851 "FILE_CHECK",
852 "MMAP_CHECK",
853 "BPRM_CHECK",
854 "MODULE_CHECK",
855 "FIRMWARE_CHECK",
856 "POST_SETATTR"
857};
858
859void *ima_policy_start(struct seq_file *m, loff_t *pos)
860{
861 loff_t l = *pos;
862 struct ima_rule_entry *entry;
863
864 rcu_read_lock();
865 list_for_each_entry_rcu(entry, ima_rules, list) {
866 if (!l--) {
867 rcu_read_unlock();
868 return entry;
869 }
870 }
871 rcu_read_unlock();
872 return NULL;
873}
874
875void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos)
876{
877 struct ima_rule_entry *entry = v;
878
879 rcu_read_lock();
880 entry = list_entry_rcu(entry->list.next, struct ima_rule_entry, list);
881 rcu_read_unlock();
882 (*pos)++;
883
884 return (&entry->list == ima_rules) ? NULL : entry;
885}
886
887void ima_policy_stop(struct seq_file *m, void *v)
888{
889}
890
891#define pt(token) policy_tokens[token + Opt_err].pattern
892#define mt(token) mask_tokens[token]
893#define ft(token) func_tokens[token]
894
895int ima_policy_show(struct seq_file *m, void *v)
896{
897 struct ima_rule_entry *entry = v;
898 int i = 0;
899 char tbuf[64] = {0,};
900
901 rcu_read_lock();
902
903 if (entry->action & MEASURE)
904 seq_puts(m, pt(Opt_measure));
905 if (entry->action & DONT_MEASURE)
906 seq_puts(m, pt(Opt_dont_measure));
907 if (entry->action & APPRAISE)
908 seq_puts(m, pt(Opt_appraise));
909 if (entry->action & DONT_APPRAISE)
910 seq_puts(m, pt(Opt_dont_appraise));
911 if (entry->action & AUDIT)
912 seq_puts(m, pt(Opt_audit));
913
914 seq_puts(m, " ");
915
916 if (entry->flags & IMA_FUNC) {
917 switch (entry->func) {
918 case FILE_CHECK:
919 seq_printf(m, pt(Opt_func), ft(func_file));
920 break;
921 case MMAP_CHECK:
922 seq_printf(m, pt(Opt_func), ft(func_mmap));
923 break;
924 case BPRM_CHECK:
925 seq_printf(m, pt(Opt_func), ft(func_bprm));
926 break;
927 case MODULE_CHECK:
928 seq_printf(m, pt(Opt_func), ft(func_module));
929 break;
930 case FIRMWARE_CHECK:
931 seq_printf(m, pt(Opt_func), ft(func_firmware));
932 break;
933 case POST_SETATTR:
934 seq_printf(m, pt(Opt_func), ft(func_post));
935 break;
936 default:
937 snprintf(tbuf, sizeof(tbuf), "%d", entry->func);
938 seq_printf(m, pt(Opt_func), tbuf);
939 break;
940 }
941 seq_puts(m, " ");
942 }
943
944 if (entry->flags & IMA_MASK) {
945 if (entry->mask & MAY_EXEC)
946 seq_printf(m, pt(Opt_mask), mt(mask_exec));
947 if (entry->mask & MAY_WRITE)
948 seq_printf(m, pt(Opt_mask), mt(mask_write));
949 if (entry->mask & MAY_READ)
950 seq_printf(m, pt(Opt_mask), mt(mask_read));
951 if (entry->mask & MAY_APPEND)
952 seq_printf(m, pt(Opt_mask), mt(mask_append));
953 seq_puts(m, " ");
954 }
955
956 if (entry->flags & IMA_FSMAGIC) {
957 snprintf(tbuf, sizeof(tbuf), "0x%lx", entry->fsmagic);
958 seq_printf(m, pt(Opt_fsmagic), tbuf);
959 seq_puts(m, " ");
960 }
961
962 if (entry->flags & IMA_FSUUID) {
963 seq_puts(m, "fsuuid=");
964 for (i = 0; i < ARRAY_SIZE(entry->fsuuid); ++i) {
965 switch (i) {
966 case 4:
967 case 6:
968 case 8:
969 case 10:
970 seq_puts(m, "-");
971 }
972 seq_printf(m, "%x", entry->fsuuid[i]);
973 }
974 seq_puts(m, " ");
975 }
976
977 if (entry->flags & IMA_UID) {
978 snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->uid));
979 seq_printf(m, pt(Opt_uid), tbuf);
980 seq_puts(m, " ");
981 }
982
983 if (entry->flags & IMA_EUID) {
984 snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->uid));
985 seq_printf(m, pt(Opt_euid), tbuf);
986 seq_puts(m, " ");
987 }
988
989 if (entry->flags & IMA_FOWNER) {
990 snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->fowner));
991 seq_printf(m, pt(Opt_fowner), tbuf);
992 seq_puts(m, " ");
993 }
994
995 for (i = 0; i < MAX_LSM_RULES; i++) {
996 if (entry->lsm[i].rule) {
997 switch (i) {
998 case LSM_OBJ_USER:
999 seq_printf(m, pt(Opt_obj_user),
1000 (char *)entry->lsm[i].args_p);
1001 break;
1002 case LSM_OBJ_ROLE:
1003 seq_printf(m, pt(Opt_obj_role),
1004 (char *)entry->lsm[i].args_p);
1005 break;
1006 case LSM_OBJ_TYPE:
1007 seq_printf(m, pt(Opt_obj_type),
1008 (char *)entry->lsm[i].args_p);
1009 break;
1010 case LSM_SUBJ_USER:
1011 seq_printf(m, pt(Opt_subj_user),
1012 (char *)entry->lsm[i].args_p);
1013 break;
1014 case LSM_SUBJ_ROLE:
1015 seq_printf(m, pt(Opt_subj_role),
1016 (char *)entry->lsm[i].args_p);
1017 break;
1018 case LSM_SUBJ_TYPE:
1019 seq_printf(m, pt(Opt_subj_type),
1020 (char *)entry->lsm[i].args_p);
1021 break;
1022 }
1023 }
1024 }
1025 if (entry->flags & IMA_DIGSIG_REQUIRED)
1026 seq_puts(m, "appraise_type=imasig ");
1027 if (entry->flags & IMA_PERMIT_DIRECTIO)
1028 seq_puts(m, "permit_directio ");
1029 rcu_read_unlock();
1030 seq_puts(m, "\n");
1031 return 0;
1032}
1033#endif /* CONFIG_IMA_READ_POLICY */