Skip to content

Commit 4336927

Browse files
thejhmimizohar
authored andcommitted
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>
1 parent 345123d commit 4336927

2 files changed

Lines changed: 40 additions & 4 deletions

File tree

Documentation/ABI/testing/ima_policy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Description:
2323
audit | dont_audit | hash | dont_hash
2424
condition:= base | lsm [option]
2525
base: [[func=] [mask=] [fsmagic=] [fsuuid=] [fsname=]
26+
[fs_subtype=]
2627
[uid=] [euid=] [gid=] [egid=]
2728
[fowner=] [fgroup=]]
2829
lsm: [[subj_user=] [subj_role=] [subj_type=]

security/integrity/ima/ima_policy.c

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#define IMA_GID 0x2000
3939
#define IMA_EGID 0x4000
4040
#define IMA_FGROUP 0x8000
41+
#define IMA_FS_SUBTYPE 0x10000
4142

4243
#define UNKNOWN 0
4344
#define MEASURE 0x0001 /* same as IMA_MEASURE */
@@ -120,6 +121,7 @@ struct ima_rule_entry {
120121
int type; /* audit type */
121122
} lsm[MAX_LSM_RULES];
122123
char *fsname;
124+
char *fs_subtype;
123125
struct ima_rule_opt_list *keyrings; /* Measure keys added to these keyrings */
124126
struct ima_rule_opt_list *label; /* Measure data grouped under this label */
125127
struct ima_template_desc *template;
@@ -398,6 +400,7 @@ static void ima_free_rule(struct ima_rule_entry *entry)
398400
* the defined_templates list and cannot be freed here
399401
*/
400402
kfree(entry->fsname);
403+
kfree(entry->fs_subtype);
401404
ima_free_rule_opt_list(entry->keyrings);
402405
ima_lsm_free_rule(entry);
403406
kfree(entry);
@@ -602,6 +605,12 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
602605
if ((rule->flags & IMA_FSNAME)
603606
&& strcmp(rule->fsname, inode->i_sb->s_type->name))
604607
return false;
608+
if (rule->flags & IMA_FS_SUBTYPE) {
609+
if (!inode->i_sb->s_subtype)
610+
return false;
611+
if (strcmp(rule->fs_subtype, inode->i_sb->s_subtype))
612+
return false;
613+
}
605614
if ((rule->flags & IMA_FSUUID) &&
606615
!uuid_equal(&rule->fsuuid, &inode->i_sb->s_uuid))
607616
return false;
@@ -1068,7 +1077,7 @@ enum policy_opt {
10681077
Opt_audit, Opt_dont_audit, Opt_hash, Opt_dont_hash,
10691078
Opt_obj_user, Opt_obj_role, Opt_obj_type,
10701079
Opt_subj_user, Opt_subj_role, Opt_subj_type,
1071-
Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, Opt_fsuuid,
1080+
Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, Opt_fs_subtype, Opt_fsuuid,
10721081
Opt_uid_eq, Opt_euid_eq, Opt_gid_eq, Opt_egid_eq,
10731082
Opt_fowner_eq, Opt_fgroup_eq,
10741083
Opt_uid_gt, Opt_euid_gt, Opt_gid_gt, Opt_egid_gt,
@@ -1100,6 +1109,7 @@ static const match_table_t policy_tokens = {
11001109
{Opt_mask, "mask=%s"},
11011110
{Opt_fsmagic, "fsmagic=%s"},
11021111
{Opt_fsname, "fsname=%s"},
1112+
{Opt_fs_subtype, "fs_subtype=%s"},
11031113
{Opt_fsuuid, "fsuuid=%s"},
11041114
{Opt_uid_eq, "uid=%s"},
11051115
{Opt_euid_eq, "euid=%s"},
@@ -1284,7 +1294,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
12841294
if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
12851295
IMA_UID | IMA_FOWNER | IMA_FSUUID |
12861296
IMA_INMASK | IMA_EUID | IMA_PCR |
1287-
IMA_FSNAME | IMA_GID | IMA_EGID |
1297+
IMA_FSNAME | IMA_FS_SUBTYPE |
1298+
IMA_GID | IMA_EGID |
12881299
IMA_FGROUP | IMA_DIGSIG_REQUIRED |
12891300
IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS |
12901301
IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED))
@@ -1297,7 +1308,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
12971308
if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
12981309
IMA_UID | IMA_FOWNER | IMA_FSUUID |
12991310
IMA_INMASK | IMA_EUID | IMA_PCR |
1300-
IMA_FSNAME | IMA_GID | IMA_EGID |
1311+
IMA_FSNAME | IMA_FS_SUBTYPE |
1312+
IMA_GID | IMA_EGID |
13011313
IMA_FGROUP | IMA_DIGSIG_REQUIRED |
13021314
IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED |
13031315
IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS))
@@ -1310,7 +1322,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
13101322

13111323
if (entry->flags & ~(IMA_FUNC | IMA_FSMAGIC | IMA_UID |
13121324
IMA_FOWNER | IMA_FSUUID | IMA_EUID |
1313-
IMA_PCR | IMA_FSNAME | IMA_GID | IMA_EGID |
1325+
IMA_PCR | IMA_FSNAME | IMA_FS_SUBTYPE |
1326+
IMA_GID | IMA_EGID |
13141327
IMA_FGROUP))
13151328
return false;
13161329

@@ -1597,6 +1610,22 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
15971610
result = 0;
15981611
entry->flags |= IMA_FSNAME;
15991612
break;
1613+
case Opt_fs_subtype:
1614+
ima_log_string(ab, "fs_subtype", args[0].from);
1615+
1616+
if (entry->fs_subtype) {
1617+
result = -EINVAL;
1618+
break;
1619+
}
1620+
1621+
entry->fs_subtype = kstrdup(args[0].from, GFP_KERNEL);
1622+
if (!entry->fs_subtype) {
1623+
result = -ENOMEM;
1624+
break;
1625+
}
1626+
result = 0;
1627+
entry->flags |= IMA_FS_SUBTYPE;
1628+
break;
16001629
case Opt_keyrings:
16011630
ima_log_string(ab, "keyrings", args[0].from);
16021631

@@ -2145,6 +2174,12 @@ int ima_policy_show(struct seq_file *m, void *v)
21452174
seq_puts(m, " ");
21462175
}
21472176

2177+
if (entry->flags & IMA_FS_SUBTYPE) {
2178+
snprintf(tbuf, sizeof(tbuf), "%s", entry->fs_subtype);
2179+
seq_printf(m, pt(Opt_fs_subtype), tbuf);
2180+
seq_puts(m, " ");
2181+
}
2182+
21482183
if (entry->flags & IMA_KEYRINGS) {
21492184
seq_puts(m, "keyrings=");
21502185
ima_show_rule_opt_list(m, entry->keyrings);

0 commit comments

Comments
 (0)