3636#define IMA_KEYRINGS 0x0400
3737#define IMA_LABEL 0x0800
3838#define IMA_VALIDATE_ALGOS 0x1000
39+ #define IMA_GID 0x2000
40+ #define IMA_EGID 0x4000
41+ #define IMA_FGROUP 0x8000
3942
4043#define UNKNOWN 0
4144#define MEASURE 0x0001 /* same as IMA_MEASURE */
@@ -78,9 +81,13 @@ struct ima_rule_entry {
7881 unsigned long fsmagic ;
7982 uuid_t fsuuid ;
8083 kuid_t uid ;
84+ kgid_t gid ;
8185 kuid_t fowner ;
86+ kgid_t fgroup ;
8287 bool (* uid_op )(kuid_t cred_uid , kuid_t rule_uid ); /* Handlers for operators */
88+ bool (* gid_op )(kgid_t cred_gid , kgid_t rule_gid );
8389 bool (* fowner_op )(kuid_t cred_uid , kuid_t rule_uid ); /* uid_eq(), uid_gt(), uid_lt() */
90+ bool (* fgroup_op )(kgid_t cred_gid , kgid_t rule_gid ); /* gid_eq(), gid_gt(), gid_lt() */
8491 int pcr ;
8592 unsigned int allowed_algos ; /* bitfield of allowed hash algorithms */
8693 struct {
@@ -104,7 +111,8 @@ static_assert(
104111
105112/*
106113 * Without LSM specific knowledge, the default policy can only be
107- * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner
114+ * written in terms of .action, .func, .mask, .fsmagic, .uid, .gid,
115+ * .fowner, and .fgroup
108116 */
109117
110118/*
@@ -582,10 +590,23 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
582590 } else if (!rule -> uid_op (cred -> euid , rule -> uid ))
583591 return false;
584592 }
585-
593+ if ((rule -> flags & IMA_GID ) && !rule -> gid_op (cred -> gid , rule -> gid ))
594+ return false;
595+ if (rule -> flags & IMA_EGID ) {
596+ if (has_capability_noaudit (current , CAP_SETGID )) {
597+ if (!rule -> gid_op (cred -> egid , rule -> gid )
598+ && !rule -> gid_op (cred -> sgid , rule -> gid )
599+ && !rule -> gid_op (cred -> gid , rule -> gid ))
600+ return false;
601+ } else if (!rule -> gid_op (cred -> egid , rule -> gid ))
602+ return false;
603+ }
586604 if ((rule -> flags & IMA_FOWNER ) &&
587605 !rule -> fowner_op (i_uid_into_mnt (mnt_userns , inode ), rule -> fowner ))
588606 return false;
607+ if ((rule -> flags & IMA_FGROUP ) &&
608+ !rule -> fgroup_op (i_gid_into_mnt (mnt_userns , inode ), rule -> fgroup ))
609+ return false;
589610 for (i = 0 ; i < MAX_LSM_RULES ; i ++ ) {
590611 int rc = 0 ;
591612 u32 osid ;
@@ -991,16 +1012,19 @@ void ima_update_policy(void)
9911012}
9921013
9931014/* Keep the enumeration in sync with the policy_tokens! */
994- enum {
1015+ enum policy_opt {
9951016 Opt_measure , Opt_dont_measure ,
9961017 Opt_appraise , Opt_dont_appraise ,
9971018 Opt_audit , Opt_hash , Opt_dont_hash ,
9981019 Opt_obj_user , Opt_obj_role , Opt_obj_type ,
9991020 Opt_subj_user , Opt_subj_role , Opt_subj_type ,
1000- Opt_func , Opt_mask , Opt_fsmagic , Opt_fsname ,
1001- Opt_fsuuid , Opt_uid_eq , Opt_euid_eq , Opt_fowner_eq ,
1002- Opt_uid_gt , Opt_euid_gt , Opt_fowner_gt ,
1003- Opt_uid_lt , Opt_euid_lt , Opt_fowner_lt ,
1021+ Opt_func , Opt_mask , Opt_fsmagic , Opt_fsname , Opt_fsuuid ,
1022+ Opt_uid_eq , Opt_euid_eq , Opt_gid_eq , Opt_egid_eq ,
1023+ Opt_fowner_eq , Opt_fgroup_eq ,
1024+ Opt_uid_gt , Opt_euid_gt , Opt_gid_gt , Opt_egid_gt ,
1025+ Opt_fowner_gt , Opt_fgroup_gt ,
1026+ Opt_uid_lt , Opt_euid_lt , Opt_gid_lt , Opt_egid_lt ,
1027+ Opt_fowner_lt , Opt_fgroup_lt ,
10041028 Opt_appraise_type , Opt_appraise_flag , Opt_appraise_algos ,
10051029 Opt_permit_directio , Opt_pcr , Opt_template , Opt_keyrings ,
10061030 Opt_label , Opt_err
@@ -1027,13 +1051,22 @@ static const match_table_t policy_tokens = {
10271051 {Opt_fsuuid , "fsuuid=%s" },
10281052 {Opt_uid_eq , "uid=%s" },
10291053 {Opt_euid_eq , "euid=%s" },
1054+ {Opt_gid_eq , "gid=%s" },
1055+ {Opt_egid_eq , "egid=%s" },
10301056 {Opt_fowner_eq , "fowner=%s" },
1057+ {Opt_fgroup_eq , "fgroup=%s" },
10311058 {Opt_uid_gt , "uid>%s" },
10321059 {Opt_euid_gt , "euid>%s" },
1060+ {Opt_gid_gt , "gid>%s" },
1061+ {Opt_egid_gt , "egid>%s" },
10331062 {Opt_fowner_gt , "fowner>%s" },
1063+ {Opt_fgroup_gt , "fgroup>%s" },
10341064 {Opt_uid_lt , "uid<%s" },
10351065 {Opt_euid_lt , "euid<%s" },
1066+ {Opt_gid_lt , "gid<%s" },
1067+ {Opt_egid_lt , "egid<%s" },
10361068 {Opt_fowner_lt , "fowner<%s" },
1069+ {Opt_fgroup_lt , "fgroup<%s" },
10371070 {Opt_appraise_type , "appraise_type=%s" },
10381071 {Opt_appraise_flag , "appraise_flag=%s" },
10391072 {Opt_appraise_algos , "appraise_algos=%s" },
@@ -1077,22 +1110,36 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
10771110}
10781111
10791112static void ima_log_string_op (struct audit_buffer * ab , char * key , char * value ,
1080- bool ( * rule_operator )( kuid_t , kuid_t ) )
1113+ enum policy_opt rule_operator )
10811114{
10821115 if (!ab )
10831116 return ;
10841117
1085- if (rule_operator == & uid_gt )
1118+ switch (rule_operator ) {
1119+ case Opt_uid_gt :
1120+ case Opt_euid_gt :
1121+ case Opt_gid_gt :
1122+ case Opt_egid_gt :
1123+ case Opt_fowner_gt :
1124+ case Opt_fgroup_gt :
10861125 audit_log_format (ab , "%s>" , key );
1087- else if (rule_operator == & uid_lt )
1126+ break ;
1127+ case Opt_uid_lt :
1128+ case Opt_euid_lt :
1129+ case Opt_gid_lt :
1130+ case Opt_egid_lt :
1131+ case Opt_fowner_lt :
1132+ case Opt_fgroup_lt :
10881133 audit_log_format (ab , "%s<" , key );
1089- else
1134+ break ;
1135+ default :
10901136 audit_log_format (ab , "%s=" , key );
1137+ }
10911138 audit_log_format (ab , "%s " , value );
10921139}
10931140static void ima_log_string (struct audit_buffer * ab , char * key , char * value )
10941141{
1095- ima_log_string_op (ab , key , value , NULL );
1142+ ima_log_string_op (ab , key , value , Opt_err );
10961143}
10971144
10981145/*
@@ -1167,7 +1214,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
11671214 if (entry -> flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
11681215 IMA_UID | IMA_FOWNER | IMA_FSUUID |
11691216 IMA_INMASK | IMA_EUID | IMA_PCR |
1170- IMA_FSNAME | IMA_DIGSIG_REQUIRED |
1217+ IMA_FSNAME | IMA_GID | IMA_EGID |
1218+ IMA_FGROUP | IMA_DIGSIG_REQUIRED |
11711219 IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS ))
11721220 return false;
11731221
@@ -1178,7 +1226,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
11781226 if (entry -> flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
11791227 IMA_UID | IMA_FOWNER | IMA_FSUUID |
11801228 IMA_INMASK | IMA_EUID | IMA_PCR |
1181- IMA_FSNAME | IMA_DIGSIG_REQUIRED |
1229+ IMA_FSNAME | IMA_GID | IMA_EGID |
1230+ IMA_FGROUP | IMA_DIGSIG_REQUIRED |
11821231 IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED |
11831232 IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS ))
11841233 return false;
@@ -1190,15 +1239,16 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
11901239
11911240 if (entry -> flags & ~(IMA_FUNC | IMA_FSMAGIC | IMA_UID |
11921241 IMA_FOWNER | IMA_FSUUID | IMA_EUID |
1193- IMA_PCR | IMA_FSNAME ))
1242+ IMA_PCR | IMA_FSNAME | IMA_GID | IMA_EGID |
1243+ IMA_FGROUP ))
11941244 return false;
11951245
11961246 break ;
11971247 case KEY_CHECK :
11981248 if (entry -> action & ~(MEASURE | DONT_MEASURE ))
11991249 return false;
12001250
1201- if (entry -> flags & ~(IMA_FUNC | IMA_UID | IMA_PCR |
1251+ if (entry -> flags & ~(IMA_FUNC | IMA_UID | IMA_GID | IMA_PCR |
12021252 IMA_KEYRINGS ))
12031253 return false;
12041254
@@ -1210,7 +1260,7 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
12101260 if (entry -> action & ~(MEASURE | DONT_MEASURE ))
12111261 return false;
12121262
1213- if (entry -> flags & ~(IMA_FUNC | IMA_UID | IMA_PCR |
1263+ if (entry -> flags & ~(IMA_FUNC | IMA_UID | IMA_GID | IMA_PCR |
12141264 IMA_LABEL ))
12151265 return false;
12161266
@@ -1280,17 +1330,21 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
12801330 struct audit_buffer * ab ;
12811331 char * from ;
12821332 char * p ;
1283- bool uid_token ;
1333+ bool eid_token ; /* either euid or egid */
12841334 struct ima_template_desc * template_desc ;
12851335 int result = 0 ;
12861336
12871337 ab = integrity_audit_log_start (audit_context (), GFP_KERNEL ,
12881338 AUDIT_INTEGRITY_POLICY_RULE );
12891339
12901340 entry -> uid = INVALID_UID ;
1341+ entry -> gid = INVALID_GID ;
12911342 entry -> fowner = INVALID_UID ;
1343+ entry -> fgroup = INVALID_GID ;
12921344 entry -> uid_op = & uid_eq ;
1345+ entry -> gid_op = & gid_eq ;
12931346 entry -> fowner_op = & uid_eq ;
1347+ entry -> fgroup_op = & gid_eq ;
12941348 entry -> action = UNKNOWN ;
12951349 while ((p = strsep (& rule , " \t" )) != NULL ) {
12961350 substring_t args [MAX_OPT_ARGS ];
@@ -1508,12 +1562,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
15081562 fallthrough ;
15091563 case Opt_uid_eq :
15101564 case Opt_euid_eq :
1511- uid_token = (token == Opt_uid_eq ) ||
1512- (token == Opt_uid_gt ) ||
1513- (token == Opt_uid_lt );
1565+ eid_token = (token == Opt_euid_eq ) ||
1566+ (token == Opt_euid_gt ) ||
1567+ (token == Opt_euid_lt );
15141568
1515- ima_log_string_op (ab , uid_token ? "uid " : "euid " ,
1516- args [0 ].from , entry -> uid_op );
1569+ ima_log_string_op (ab , eid_token ? "euid " : "uid " ,
1570+ args [0 ].from , token );
15171571
15181572 if (uid_valid (entry -> uid )) {
15191573 result = - EINVAL ;
@@ -1528,8 +1582,43 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
15281582 (uid_t )lnum != lnum )
15291583 result = - EINVAL ;
15301584 else
1531- entry -> flags |= uid_token
1532- ? IMA_UID : IMA_EUID ;
1585+ entry -> flags |= eid_token
1586+ ? IMA_EUID : IMA_UID ;
1587+ }
1588+ break ;
1589+ case Opt_gid_gt :
1590+ case Opt_egid_gt :
1591+ entry -> gid_op = & gid_gt ;
1592+ fallthrough ;
1593+ case Opt_gid_lt :
1594+ case Opt_egid_lt :
1595+ if ((token == Opt_gid_lt ) || (token == Opt_egid_lt ))
1596+ entry -> gid_op = & gid_lt ;
1597+ fallthrough ;
1598+ case Opt_gid_eq :
1599+ case Opt_egid_eq :
1600+ eid_token = (token == Opt_egid_eq ) ||
1601+ (token == Opt_egid_gt ) ||
1602+ (token == Opt_egid_lt );
1603+
1604+ ima_log_string_op (ab , eid_token ? "egid" : "gid" ,
1605+ args [0 ].from , token );
1606+
1607+ if (gid_valid (entry -> gid )) {
1608+ result = - EINVAL ;
1609+ break ;
1610+ }
1611+
1612+ result = kstrtoul (args [0 ].from , 10 , & lnum );
1613+ if (!result ) {
1614+ entry -> gid = make_kgid (current_user_ns (),
1615+ (gid_t )lnum );
1616+ if (!gid_valid (entry -> gid ) ||
1617+ (((gid_t )lnum ) != lnum ))
1618+ result = - EINVAL ;
1619+ else
1620+ entry -> flags |= eid_token
1621+ ? IMA_EGID : IMA_GID ;
15331622 }
15341623 break ;
15351624 case Opt_fowner_gt :
@@ -1540,8 +1629,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
15401629 entry -> fowner_op = & uid_lt ;
15411630 fallthrough ;
15421631 case Opt_fowner_eq :
1543- ima_log_string_op (ab , "fowner" , args [0 ].from ,
1544- entry -> fowner_op );
1632+ ima_log_string_op (ab , "fowner" , args [0 ].from , token );
15451633
15461634 if (uid_valid (entry -> fowner )) {
15471635 result = - EINVAL ;
@@ -1559,6 +1647,32 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
15591647 entry -> flags |= IMA_FOWNER ;
15601648 }
15611649 break ;
1650+ case Opt_fgroup_gt :
1651+ entry -> fgroup_op = & gid_gt ;
1652+ fallthrough ;
1653+ case Opt_fgroup_lt :
1654+ if (token == Opt_fgroup_lt )
1655+ entry -> fgroup_op = & gid_lt ;
1656+ fallthrough ;
1657+ case Opt_fgroup_eq :
1658+ ima_log_string_op (ab , "fgroup" , args [0 ].from , token );
1659+
1660+ if (gid_valid (entry -> fgroup )) {
1661+ result = - EINVAL ;
1662+ break ;
1663+ }
1664+
1665+ result = kstrtoul (args [0 ].from , 10 , & lnum );
1666+ if (!result ) {
1667+ entry -> fgroup = make_kgid (current_user_ns (),
1668+ (gid_t )lnum );
1669+ if (!gid_valid (entry -> fgroup ) ||
1670+ (((gid_t )lnum ) != lnum ))
1671+ result = - EINVAL ;
1672+ else
1673+ entry -> flags |= IMA_FGROUP ;
1674+ }
1675+ break ;
15621676 case Opt_obj_user :
15631677 ima_log_string (ab , "obj_user" , args [0 ].from );
15641678 result = ima_lsm_rule_init (entry , args ,
@@ -1945,6 +2059,28 @@ int ima_policy_show(struct seq_file *m, void *v)
19452059 seq_puts (m , " " );
19462060 }
19472061
2062+ if (entry -> flags & IMA_GID ) {
2063+ snprintf (tbuf , sizeof (tbuf ), "%d" , __kgid_val (entry -> gid ));
2064+ if (entry -> gid_op == & gid_gt )
2065+ seq_printf (m , pt (Opt_gid_gt ), tbuf );
2066+ else if (entry -> gid_op == & gid_lt )
2067+ seq_printf (m , pt (Opt_gid_lt ), tbuf );
2068+ else
2069+ seq_printf (m , pt (Opt_gid_eq ), tbuf );
2070+ seq_puts (m , " " );
2071+ }
2072+
2073+ if (entry -> flags & IMA_EGID ) {
2074+ snprintf (tbuf , sizeof (tbuf ), "%d" , __kgid_val (entry -> gid ));
2075+ if (entry -> gid_op == & gid_gt )
2076+ seq_printf (m , pt (Opt_egid_gt ), tbuf );
2077+ else if (entry -> gid_op == & gid_lt )
2078+ seq_printf (m , pt (Opt_egid_lt ), tbuf );
2079+ else
2080+ seq_printf (m , pt (Opt_egid_eq ), tbuf );
2081+ seq_puts (m , " " );
2082+ }
2083+
19482084 if (entry -> flags & IMA_FOWNER ) {
19492085 snprintf (tbuf , sizeof (tbuf ), "%d" , __kuid_val (entry -> fowner ));
19502086 if (entry -> fowner_op == & uid_gt )
@@ -1956,6 +2092,17 @@ int ima_policy_show(struct seq_file *m, void *v)
19562092 seq_puts (m , " " );
19572093 }
19582094
2095+ if (entry -> flags & IMA_FGROUP ) {
2096+ snprintf (tbuf , sizeof (tbuf ), "%d" , __kgid_val (entry -> fgroup ));
2097+ if (entry -> fgroup_op == & gid_gt )
2098+ seq_printf (m , pt (Opt_fgroup_gt ), tbuf );
2099+ else if (entry -> fgroup_op == & gid_lt )
2100+ seq_printf (m , pt (Opt_fgroup_lt ), tbuf );
2101+ else
2102+ seq_printf (m , pt (Opt_fgroup_eq ), tbuf );
2103+ seq_puts (m , " " );
2104+ }
2105+
19592106 if (entry -> flags & IMA_VALIDATE_ALGOS ) {
19602107 seq_puts (m , "appraise_algos=" );
19612108 ima_policy_show_appraise_algos (m , entry -> allowed_algos );
0 commit comments