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