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

ima: add fs_subtype condition for distinguishing FUSE instances

Linux systems often use FUSE for several different purposes, where the
contents of some FUSE instances can be of more interest for auditing
than others.

Allow distinguishing between them based on the filesystem subtype
(s_subtype) using the new condition "fs_subtype".

The subtype string is supplied by userspace FUSE daemons
when a FUSE connection is initialized, so policy authors who want to
filter based on subtype need to ensure that FUSE mount operations are
sufficiently audited or restricted.

Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>

authored by

Jann Horn and committed by
Mimi Zohar
43369273 345123d6

+40 -4
+1
Documentation/ABI/testing/ima_policy
··· 23 23 audit | dont_audit | hash | dont_hash 24 24 condition:= base | lsm [option] 25 25 base: [[func=] [mask=] [fsmagic=] [fsuuid=] [fsname=] 26 + [fs_subtype=] 26 27 [uid=] [euid=] [gid=] [egid=] 27 28 [fowner=] [fgroup=]] 28 29 lsm: [[subj_user=] [subj_role=] [subj_type=]
+39 -4
security/integrity/ima/ima_policy.c
··· 38 38 #define IMA_GID 0x2000 39 39 #define IMA_EGID 0x4000 40 40 #define IMA_FGROUP 0x8000 41 + #define IMA_FS_SUBTYPE 0x10000 41 42 42 43 #define UNKNOWN 0 43 44 #define MEASURE 0x0001 /* same as IMA_MEASURE */ ··· 121 120 int type; /* audit type */ 122 121 } lsm[MAX_LSM_RULES]; 123 122 char *fsname; 123 + char *fs_subtype; 124 124 struct ima_rule_opt_list *keyrings; /* Measure keys added to these keyrings */ 125 125 struct ima_rule_opt_list *label; /* Measure data grouped under this label */ 126 126 struct ima_template_desc *template; ··· 400 398 * the defined_templates list and cannot be freed here 401 399 */ 402 400 kfree(entry->fsname); 401 + kfree(entry->fs_subtype); 403 402 ima_free_rule_opt_list(entry->keyrings); 404 403 ima_lsm_free_rule(entry); 405 404 kfree(entry); ··· 605 602 if ((rule->flags & IMA_FSNAME) 606 603 && strcmp(rule->fsname, inode->i_sb->s_type->name)) 607 604 return false; 605 + if (rule->flags & IMA_FS_SUBTYPE) { 606 + if (!inode->i_sb->s_subtype) 607 + return false; 608 + if (strcmp(rule->fs_subtype, inode->i_sb->s_subtype)) 609 + return false; 610 + } 608 611 if ((rule->flags & IMA_FSUUID) && 609 612 !uuid_equal(&rule->fsuuid, &inode->i_sb->s_uuid)) 610 613 return false; ··· 1077 1068 Opt_audit, Opt_dont_audit, Opt_hash, Opt_dont_hash, 1078 1069 Opt_obj_user, Opt_obj_role, Opt_obj_type, 1079 1070 Opt_subj_user, Opt_subj_role, Opt_subj_type, 1080 - Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, Opt_fsuuid, 1071 + Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, Opt_fs_subtype, Opt_fsuuid, 1081 1072 Opt_uid_eq, Opt_euid_eq, Opt_gid_eq, Opt_egid_eq, 1082 1073 Opt_fowner_eq, Opt_fgroup_eq, 1083 1074 Opt_uid_gt, Opt_euid_gt, Opt_gid_gt, Opt_egid_gt, ··· 1109 1100 {Opt_mask, "mask=%s"}, 1110 1101 {Opt_fsmagic, "fsmagic=%s"}, 1111 1102 {Opt_fsname, "fsname=%s"}, 1103 + {Opt_fs_subtype, "fs_subtype=%s"}, 1112 1104 {Opt_fsuuid, "fsuuid=%s"}, 1113 1105 {Opt_uid_eq, "uid=%s"}, 1114 1106 {Opt_euid_eq, "euid=%s"}, ··· 1294 1284 if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC | 1295 1285 IMA_UID | IMA_FOWNER | IMA_FSUUID | 1296 1286 IMA_INMASK | IMA_EUID | IMA_PCR | 1297 - IMA_FSNAME | IMA_GID | IMA_EGID | 1287 + IMA_FSNAME | IMA_FS_SUBTYPE | 1288 + IMA_GID | IMA_EGID | 1298 1289 IMA_FGROUP | IMA_DIGSIG_REQUIRED | 1299 1290 IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS | 1300 1291 IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED)) ··· 1308 1297 if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC | 1309 1298 IMA_UID | IMA_FOWNER | IMA_FSUUID | 1310 1299 IMA_INMASK | IMA_EUID | IMA_PCR | 1311 - IMA_FSNAME | IMA_GID | IMA_EGID | 1300 + IMA_FSNAME | IMA_FS_SUBTYPE | 1301 + IMA_GID | IMA_EGID | 1312 1302 IMA_FGROUP | IMA_DIGSIG_REQUIRED | 1313 1303 IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED | 1314 1304 IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS)) ··· 1322 1310 1323 1311 if (entry->flags & ~(IMA_FUNC | IMA_FSMAGIC | IMA_UID | 1324 1312 IMA_FOWNER | IMA_FSUUID | IMA_EUID | 1325 - IMA_PCR | IMA_FSNAME | IMA_GID | IMA_EGID | 1313 + IMA_PCR | IMA_FSNAME | IMA_FS_SUBTYPE | 1314 + IMA_GID | IMA_EGID | 1326 1315 IMA_FGROUP)) 1327 1316 return false; 1328 1317 ··· 1609 1596 } 1610 1597 result = 0; 1611 1598 entry->flags |= IMA_FSNAME; 1599 + break; 1600 + case Opt_fs_subtype: 1601 + ima_log_string(ab, "fs_subtype", args[0].from); 1602 + 1603 + if (entry->fs_subtype) { 1604 + result = -EINVAL; 1605 + break; 1606 + } 1607 + 1608 + entry->fs_subtype = kstrdup(args[0].from, GFP_KERNEL); 1609 + if (!entry->fs_subtype) { 1610 + result = -ENOMEM; 1611 + break; 1612 + } 1613 + result = 0; 1614 + entry->flags |= IMA_FS_SUBTYPE; 1612 1615 break; 1613 1616 case Opt_keyrings: 1614 1617 ima_log_string(ab, "keyrings", args[0].from); ··· 2171 2142 if (entry->flags & IMA_FSNAME) { 2172 2143 snprintf(tbuf, sizeof(tbuf), "%s", entry->fsname); 2173 2144 seq_printf(m, pt(Opt_fsname), tbuf); 2145 + seq_puts(m, " "); 2146 + } 2147 + 2148 + if (entry->flags & IMA_FS_SUBTYPE) { 2149 + snprintf(tbuf, sizeof(tbuf), "%s", entry->fs_subtype); 2150 + seq_printf(m, pt(Opt_fs_subtype), tbuf); 2174 2151 seq_puts(m, " "); 2175 2152 } 2176 2153