Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ima: define a new policy condition based on the filesystem name

If/when file data signatures are distributed with the file data, this
patch will not be needed. In the current environment where only some
files are signed, the ability to differentiate between file systems is
needed. Some file systems consider the file system magic number
internal to the file system.

This patch defines a new IMA policy condition named "fsname", based on
the superblock's file_system_type (sb->s_type) name. This allows policy
rules to be expressed in terms of the filesystem name.

The following sample rules require file signatures on rootfs files
executed or mmap'ed.

appraise func=BPRM_CHECK fsname=rootfs appraise_type=imasig
appraise func=FILE_MMAP fsname=rootfs appraise_type=imasig

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Theodore Ts'o <tytso@mit.edu>

+25 -2
+1 -1
Documentation/ABI/testing/ima_policy
··· 21 21 audit | hash | dont_hash 22 22 condition:= base | lsm [option] 23 23 base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=] 24 - [euid=] [fowner=]] 24 + [euid=] [fowner=] [fsname=]] 25 25 lsm: [[subj_user=] [subj_role=] [subj_type=] 26 26 [obj_user=] [obj_role=] [obj_type=]] 27 27 option: [[appraise_type=]] [permit_directio]
+24 -1
security/integrity/ima/ima_policy.c
··· 33 33 #define IMA_INMASK 0x0040 34 34 #define IMA_EUID 0x0080 35 35 #define IMA_PCR 0x0100 36 + #define IMA_FSNAME 0x0200 36 37 37 38 #define UNKNOWN 0 38 39 #define MEASURE 0x0001 /* same as IMA_MEASURE */ ··· 75 74 void *args_p; /* audit value */ 76 75 int type; /* audit type */ 77 76 } lsm[MAX_LSM_RULES]; 77 + char *fsname; 78 78 }; 79 79 80 80 /* ··· 274 272 return false; 275 273 if ((rule->flags & IMA_FSMAGIC) 276 274 && rule->fsmagic != inode->i_sb->s_magic) 275 + return false; 276 + if ((rule->flags & IMA_FSNAME) 277 + && strcmp(rule->fsname, inode->i_sb->s_type->name)) 277 278 return false; 278 279 if ((rule->flags & IMA_FSUUID) && 279 280 !uuid_equal(&rule->fsuuid, &inode->i_sb->s_uuid)) ··· 545 540 Opt_audit, Opt_hash, Opt_dont_hash, 546 541 Opt_obj_user, Opt_obj_role, Opt_obj_type, 547 542 Opt_subj_user, Opt_subj_role, Opt_subj_type, 548 - Opt_func, Opt_mask, Opt_fsmagic, 543 + Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, 549 544 Opt_fsuuid, Opt_uid_eq, Opt_euid_eq, Opt_fowner_eq, 550 545 Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt, 551 546 Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt, ··· 570 565 {Opt_func, "func=%s"}, 571 566 {Opt_mask, "mask=%s"}, 572 567 {Opt_fsmagic, "fsmagic=%s"}, 568 + {Opt_fsname, "fsname=%s"}, 573 569 {Opt_fsuuid, "fsuuid=%s"}, 574 570 {Opt_uid_eq, "uid=%s"}, 575 571 {Opt_euid_eq, "euid=%s"}, ··· 781 775 result = kstrtoul(args[0].from, 16, &entry->fsmagic); 782 776 if (!result) 783 777 entry->flags |= IMA_FSMAGIC; 778 + break; 779 + case Opt_fsname: 780 + ima_log_string(ab, "fsname", args[0].from); 781 + 782 + entry->fsname = kstrdup(args[0].from, GFP_KERNEL); 783 + if (!entry->fsname) { 784 + result = -ENOMEM; 785 + break; 786 + } 787 + result = 0; 788 + entry->flags |= IMA_FSNAME; 784 789 break; 785 790 case Opt_fsuuid: 786 791 ima_log_string(ab, "fsuuid", args[0].from); ··· 1118 1101 if (entry->flags & IMA_FSMAGIC) { 1119 1102 snprintf(tbuf, sizeof(tbuf), "0x%lx", entry->fsmagic); 1120 1103 seq_printf(m, pt(Opt_fsmagic), tbuf); 1104 + seq_puts(m, " "); 1105 + } 1106 + 1107 + if (entry->flags & IMA_FSNAME) { 1108 + snprintf(tbuf, sizeof(tbuf), "%s", entry->fsname); 1109 + seq_printf(m, pt(Opt_fsname), tbuf); 1121 1110 seq_puts(m, " "); 1122 1111 } 1123 1112