integrity-v5.16
-----BEGIN PGP SIGNATURE----- iIoEABYIADIWIQQdXVVFGN5XqKr1Hj7LwZzRsCrn5QUCYYELkRQcem9oYXJAbGlu dXguaWJtLmNvbQAKCRDLwZzRsCrn5egFAP99TYmvDcP7sdcOpDzNCTviirj3PCF9 jiYcVJDvkRousQD9GclOwWTUoGg382zRSopR9IT/wNhLFz/JIGwGhZrHwwA= =a74o -----END PGP SIGNATURE----- Merge tag 'integrity-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity Pull integrity subsystem updates from Mimi Zohar: "Other than the new gid IMA policy rule support and the RCU locking fix, the couple of remaining changes are minor/trivial (e.g. __ro_after_init, replacing strscpy)" * tag 'integrity-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity: evm: mark evm_fixmode as __ro_after_init ima: Use strscpy instead of strlcpy ima_policy: Remove duplicate 'the' in docs comment ima: add gid support ima: fix uid code style problems ima: fix deadlock when traversing "ima_default_rules".
This commit is contained in:
commit
c150d66bd5
@ -22,8 +22,9 @@ Description:
|
||||
action: measure | dont_measure | appraise | dont_appraise |
|
||||
audit | hash | dont_hash
|
||||
condition:= base | lsm [option]
|
||||
base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=]
|
||||
[euid=] [fowner=] [fsname=]]
|
||||
base: [[func=] [mask=] [fsmagic=] [fsuuid=] [fsname=]
|
||||
[uid=] [euid=] [gid=] [egid=]
|
||||
[fowner=] [fgroup=]]
|
||||
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
||||
[obj_user=] [obj_role=] [obj_type=]]
|
||||
option: [[appraise_type=]] [template=] [permit_directio]
|
||||
@ -40,7 +41,10 @@ Description:
|
||||
fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6)
|
||||
uid:= decimal value
|
||||
euid:= decimal value
|
||||
gid:= decimal value
|
||||
egid:= decimal value
|
||||
fowner:= decimal value
|
||||
fgroup:= decimal value
|
||||
lsm: are LSM specific
|
||||
option:
|
||||
appraise_type:= [imasig] [imasig|modsig]
|
||||
|
@ -78,7 +78,7 @@ static struct xattr_list evm_config_default_xattrnames[] = {
|
||||
|
||||
LIST_HEAD(evm_config_xattrnames);
|
||||
|
||||
static int evm_fixmode;
|
||||
static int evm_fixmode __ro_after_init;
|
||||
static int __init evm_set_fixmode(char *str)
|
||||
{
|
||||
if (strncmp(str, "fix", 3) == 0)
|
||||
|
@ -403,7 +403,7 @@ const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
|
||||
}
|
||||
|
||||
if (!pathname) {
|
||||
strlcpy(namebuf, path->dentry->d_name.name, NAME_MAX);
|
||||
strscpy(namebuf, path->dentry->d_name.name, NAME_MAX);
|
||||
pathname = namebuf;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,9 @@
|
||||
#define IMA_KEYRINGS 0x0400
|
||||
#define IMA_LABEL 0x0800
|
||||
#define IMA_VALIDATE_ALGOS 0x1000
|
||||
#define IMA_GID 0x2000
|
||||
#define IMA_EGID 0x4000
|
||||
#define IMA_FGROUP 0x8000
|
||||
|
||||
#define UNKNOWN 0
|
||||
#define MEASURE 0x0001 /* same as IMA_MEASURE */
|
||||
@ -78,9 +81,13 @@ struct ima_rule_entry {
|
||||
unsigned long fsmagic;
|
||||
uuid_t fsuuid;
|
||||
kuid_t uid;
|
||||
kgid_t gid;
|
||||
kuid_t fowner;
|
||||
bool (*uid_op)(kuid_t, kuid_t); /* Handlers for operators */
|
||||
bool (*fowner_op)(kuid_t, kuid_t); /* uid_eq(), uid_gt(), uid_lt() */
|
||||
kgid_t fgroup;
|
||||
bool (*uid_op)(kuid_t cred_uid, kuid_t rule_uid); /* Handlers for operators */
|
||||
bool (*gid_op)(kgid_t cred_gid, kgid_t rule_gid);
|
||||
bool (*fowner_op)(kuid_t cred_uid, kuid_t rule_uid); /* uid_eq(), uid_gt(), uid_lt() */
|
||||
bool (*fgroup_op)(kgid_t cred_gid, kgid_t rule_gid); /* gid_eq(), gid_gt(), gid_lt() */
|
||||
int pcr;
|
||||
unsigned int allowed_algos; /* bitfield of allowed hash algorithms */
|
||||
struct {
|
||||
@ -104,7 +111,8 @@ static_assert(
|
||||
|
||||
/*
|
||||
* Without LSM specific knowledge, the default policy can only be
|
||||
* written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner
|
||||
* written in terms of .action, .func, .mask, .fsmagic, .uid, .gid,
|
||||
* .fowner, and .fgroup
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -228,7 +236,7 @@ static struct ima_rule_entry *arch_policy_entry __ro_after_init;
|
||||
static LIST_HEAD(ima_default_rules);
|
||||
static LIST_HEAD(ima_policy_rules);
|
||||
static LIST_HEAD(ima_temp_rules);
|
||||
static struct list_head *ima_rules = &ima_default_rules;
|
||||
static struct list_head __rcu *ima_rules = (struct list_head __rcu *)(&ima_default_rules);
|
||||
|
||||
static int ima_policy __initdata;
|
||||
|
||||
@ -582,10 +590,23 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
|
||||
} else if (!rule->uid_op(cred->euid, rule->uid))
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((rule->flags & IMA_GID) && !rule->gid_op(cred->gid, rule->gid))
|
||||
return false;
|
||||
if (rule->flags & IMA_EGID) {
|
||||
if (has_capability_noaudit(current, CAP_SETGID)) {
|
||||
if (!rule->gid_op(cred->egid, rule->gid)
|
||||
&& !rule->gid_op(cred->sgid, rule->gid)
|
||||
&& !rule->gid_op(cred->gid, rule->gid))
|
||||
return false;
|
||||
} else if (!rule->gid_op(cred->egid, rule->gid))
|
||||
return false;
|
||||
}
|
||||
if ((rule->flags & IMA_FOWNER) &&
|
||||
!rule->fowner_op(i_uid_into_mnt(mnt_userns, inode), rule->fowner))
|
||||
return false;
|
||||
if ((rule->flags & IMA_FGROUP) &&
|
||||
!rule->fgroup_op(i_gid_into_mnt(mnt_userns, inode), rule->fgroup))
|
||||
return false;
|
||||
for (i = 0; i < MAX_LSM_RULES; i++) {
|
||||
int rc = 0;
|
||||
u32 osid;
|
||||
@ -675,12 +696,14 @@ int ima_match_policy(struct user_namespace *mnt_userns, struct inode *inode,
|
||||
{
|
||||
struct ima_rule_entry *entry;
|
||||
int action = 0, actmask = flags | (flags << 1);
|
||||
struct list_head *ima_rules_tmp;
|
||||
|
||||
if (template_desc && !*template_desc)
|
||||
*template_desc = ima_template_desc_current();
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(entry, ima_rules, list) {
|
||||
ima_rules_tmp = rcu_dereference(ima_rules);
|
||||
list_for_each_entry_rcu(entry, ima_rules_tmp, list) {
|
||||
|
||||
if (!(entry->action & actmask))
|
||||
continue;
|
||||
@ -741,9 +764,11 @@ void ima_update_policy_flags(void)
|
||||
{
|
||||
struct ima_rule_entry *entry;
|
||||
int new_policy_flag = 0;
|
||||
struct list_head *ima_rules_tmp;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry(entry, ima_rules, list) {
|
||||
ima_rules_tmp = rcu_dereference(ima_rules);
|
||||
list_for_each_entry_rcu(entry, ima_rules_tmp, list) {
|
||||
/*
|
||||
* SETXATTR_CHECK rules do not implement a full policy check
|
||||
* because rule checking would probably have an important
|
||||
@ -845,7 +870,7 @@ static int __init ima_init_arch_policy(void)
|
||||
char rule[255];
|
||||
int result;
|
||||
|
||||
result = strlcpy(rule, *rules, sizeof(rule));
|
||||
result = strscpy(rule, *rules, sizeof(rule));
|
||||
|
||||
INIT_LIST_HEAD(&arch_policy_entry[i].list);
|
||||
result = ima_parse_rule(rule, &arch_policy_entry[i]);
|
||||
@ -864,8 +889,7 @@ static int __init ima_init_arch_policy(void)
|
||||
/**
|
||||
* ima_init_policy - initialize the default measure rules.
|
||||
*
|
||||
* ima_rules points to either the ima_default_rules or the
|
||||
* the new ima_policy_rules.
|
||||
* ima_rules points to either the ima_default_rules or the new ima_policy_rules.
|
||||
*/
|
||||
void __init ima_init_policy(void)
|
||||
{
|
||||
@ -968,10 +992,10 @@ void ima_update_policy(void)
|
||||
|
||||
list_splice_tail_init_rcu(&ima_temp_rules, policy, synchronize_rcu);
|
||||
|
||||
if (ima_rules != policy) {
|
||||
if (ima_rules != (struct list_head __rcu *)policy) {
|
||||
ima_policy_flag = 0;
|
||||
ima_rules = policy;
|
||||
|
||||
rcu_assign_pointer(ima_rules, policy);
|
||||
/*
|
||||
* IMA architecture specific policy rules are specified
|
||||
* as strings and converted to an array of ima_entry_rules
|
||||
@ -987,16 +1011,19 @@ void ima_update_policy(void)
|
||||
}
|
||||
|
||||
/* Keep the enumeration in sync with the policy_tokens! */
|
||||
enum {
|
||||
enum policy_opt {
|
||||
Opt_measure, Opt_dont_measure,
|
||||
Opt_appraise, Opt_dont_appraise,
|
||||
Opt_audit, Opt_hash, Opt_dont_hash,
|
||||
Opt_obj_user, Opt_obj_role, Opt_obj_type,
|
||||
Opt_subj_user, Opt_subj_role, Opt_subj_type,
|
||||
Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname,
|
||||
Opt_fsuuid, Opt_uid_eq, Opt_euid_eq, Opt_fowner_eq,
|
||||
Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
|
||||
Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
|
||||
Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, Opt_fsuuid,
|
||||
Opt_uid_eq, Opt_euid_eq, Opt_gid_eq, Opt_egid_eq,
|
||||
Opt_fowner_eq, Opt_fgroup_eq,
|
||||
Opt_uid_gt, Opt_euid_gt, Opt_gid_gt, Opt_egid_gt,
|
||||
Opt_fowner_gt, Opt_fgroup_gt,
|
||||
Opt_uid_lt, Opt_euid_lt, Opt_gid_lt, Opt_egid_lt,
|
||||
Opt_fowner_lt, Opt_fgroup_lt,
|
||||
Opt_appraise_type, Opt_appraise_flag, Opt_appraise_algos,
|
||||
Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings,
|
||||
Opt_label, Opt_err
|
||||
@ -1023,13 +1050,22 @@ static const match_table_t policy_tokens = {
|
||||
{Opt_fsuuid, "fsuuid=%s"},
|
||||
{Opt_uid_eq, "uid=%s"},
|
||||
{Opt_euid_eq, "euid=%s"},
|
||||
{Opt_gid_eq, "gid=%s"},
|
||||
{Opt_egid_eq, "egid=%s"},
|
||||
{Opt_fowner_eq, "fowner=%s"},
|
||||
{Opt_fgroup_eq, "fgroup=%s"},
|
||||
{Opt_uid_gt, "uid>%s"},
|
||||
{Opt_euid_gt, "euid>%s"},
|
||||
{Opt_gid_gt, "gid>%s"},
|
||||
{Opt_egid_gt, "egid>%s"},
|
||||
{Opt_fowner_gt, "fowner>%s"},
|
||||
{Opt_fgroup_gt, "fgroup>%s"},
|
||||
{Opt_uid_lt, "uid<%s"},
|
||||
{Opt_euid_lt, "euid<%s"},
|
||||
{Opt_gid_lt, "gid<%s"},
|
||||
{Opt_egid_lt, "egid<%s"},
|
||||
{Opt_fowner_lt, "fowner<%s"},
|
||||
{Opt_fgroup_lt, "fgroup<%s"},
|
||||
{Opt_appraise_type, "appraise_type=%s"},
|
||||
{Opt_appraise_flag, "appraise_flag=%s"},
|
||||
{Opt_appraise_algos, "appraise_algos=%s"},
|
||||
@ -1061,7 +1097,7 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
|
||||
pr_warn("rule for LSM \'%s\' is undefined\n",
|
||||
entry->lsm[lsm_rule].args_p);
|
||||
|
||||
if (ima_rules == &ima_default_rules) {
|
||||
if (ima_rules == (struct list_head __rcu *)(&ima_default_rules)) {
|
||||
kfree(entry->lsm[lsm_rule].args_p);
|
||||
entry->lsm[lsm_rule].args_p = NULL;
|
||||
result = -EINVAL;
|
||||
@ -1073,22 +1109,36 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
|
||||
}
|
||||
|
||||
static void ima_log_string_op(struct audit_buffer *ab, char *key, char *value,
|
||||
bool (*rule_operator)(kuid_t, kuid_t))
|
||||
enum policy_opt rule_operator)
|
||||
{
|
||||
if (!ab)
|
||||
return;
|
||||
|
||||
if (rule_operator == &uid_gt)
|
||||
switch (rule_operator) {
|
||||
case Opt_uid_gt:
|
||||
case Opt_euid_gt:
|
||||
case Opt_gid_gt:
|
||||
case Opt_egid_gt:
|
||||
case Opt_fowner_gt:
|
||||
case Opt_fgroup_gt:
|
||||
audit_log_format(ab, "%s>", key);
|
||||
else if (rule_operator == &uid_lt)
|
||||
break;
|
||||
case Opt_uid_lt:
|
||||
case Opt_euid_lt:
|
||||
case Opt_gid_lt:
|
||||
case Opt_egid_lt:
|
||||
case Opt_fowner_lt:
|
||||
case Opt_fgroup_lt:
|
||||
audit_log_format(ab, "%s<", key);
|
||||
else
|
||||
break;
|
||||
default:
|
||||
audit_log_format(ab, "%s=", key);
|
||||
}
|
||||
audit_log_format(ab, "%s ", value);
|
||||
}
|
||||
static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
|
||||
{
|
||||
ima_log_string_op(ab, key, value, NULL);
|
||||
ima_log_string_op(ab, key, value, Opt_err);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1163,7 +1213,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
|
||||
if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
|
||||
IMA_UID | IMA_FOWNER | IMA_FSUUID |
|
||||
IMA_INMASK | IMA_EUID | IMA_PCR |
|
||||
IMA_FSNAME | IMA_DIGSIG_REQUIRED |
|
||||
IMA_FSNAME | IMA_GID | IMA_EGID |
|
||||
IMA_FGROUP | IMA_DIGSIG_REQUIRED |
|
||||
IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS))
|
||||
return false;
|
||||
|
||||
@ -1174,7 +1225,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
|
||||
if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
|
||||
IMA_UID | IMA_FOWNER | IMA_FSUUID |
|
||||
IMA_INMASK | IMA_EUID | IMA_PCR |
|
||||
IMA_FSNAME | IMA_DIGSIG_REQUIRED |
|
||||
IMA_FSNAME | IMA_GID | IMA_EGID |
|
||||
IMA_FGROUP | IMA_DIGSIG_REQUIRED |
|
||||
IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED |
|
||||
IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS))
|
||||
return false;
|
||||
@ -1186,7 +1238,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
|
||||
|
||||
if (entry->flags & ~(IMA_FUNC | IMA_FSMAGIC | IMA_UID |
|
||||
IMA_FOWNER | IMA_FSUUID | IMA_EUID |
|
||||
IMA_PCR | IMA_FSNAME))
|
||||
IMA_PCR | IMA_FSNAME | IMA_GID | IMA_EGID |
|
||||
IMA_FGROUP))
|
||||
return false;
|
||||
|
||||
break;
|
||||
@ -1194,7 +1247,7 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
|
||||
if (entry->action & ~(MEASURE | DONT_MEASURE))
|
||||
return false;
|
||||
|
||||
if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_PCR |
|
||||
if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_GID | IMA_PCR |
|
||||
IMA_KEYRINGS))
|
||||
return false;
|
||||
|
||||
@ -1206,7 +1259,7 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
|
||||
if (entry->action & ~(MEASURE | DONT_MEASURE))
|
||||
return false;
|
||||
|
||||
if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_PCR |
|
||||
if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_GID | IMA_PCR |
|
||||
IMA_LABEL))
|
||||
return false;
|
||||
|
||||
@ -1276,7 +1329,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||
struct audit_buffer *ab;
|
||||
char *from;
|
||||
char *p;
|
||||
bool uid_token;
|
||||
bool eid_token; /* either euid or egid */
|
||||
struct ima_template_desc *template_desc;
|
||||
int result = 0;
|
||||
|
||||
@ -1284,9 +1337,13 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||
AUDIT_INTEGRITY_POLICY_RULE);
|
||||
|
||||
entry->uid = INVALID_UID;
|
||||
entry->gid = INVALID_GID;
|
||||
entry->fowner = INVALID_UID;
|
||||
entry->fgroup = INVALID_GID;
|
||||
entry->uid_op = &uid_eq;
|
||||
entry->gid_op = &gid_eq;
|
||||
entry->fowner_op = &uid_eq;
|
||||
entry->fgroup_op = &gid_eq;
|
||||
entry->action = UNKNOWN;
|
||||
while ((p = strsep(&rule, " \t")) != NULL) {
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
@ -1504,12 +1561,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||
fallthrough;
|
||||
case Opt_uid_eq:
|
||||
case Opt_euid_eq:
|
||||
uid_token = (token == Opt_uid_eq) ||
|
||||
(token == Opt_uid_gt) ||
|
||||
(token == Opt_uid_lt);
|
||||
eid_token = (token == Opt_euid_eq) ||
|
||||
(token == Opt_euid_gt) ||
|
||||
(token == Opt_euid_lt);
|
||||
|
||||
ima_log_string_op(ab, uid_token ? "uid" : "euid",
|
||||
args[0].from, entry->uid_op);
|
||||
ima_log_string_op(ab, eid_token ? "euid" : "uid",
|
||||
args[0].from, token);
|
||||
|
||||
if (uid_valid(entry->uid)) {
|
||||
result = -EINVAL;
|
||||
@ -1524,8 +1581,43 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||
(uid_t)lnum != lnum)
|
||||
result = -EINVAL;
|
||||
else
|
||||
entry->flags |= uid_token
|
||||
? IMA_UID : IMA_EUID;
|
||||
entry->flags |= eid_token
|
||||
? IMA_EUID : IMA_UID;
|
||||
}
|
||||
break;
|
||||
case Opt_gid_gt:
|
||||
case Opt_egid_gt:
|
||||
entry->gid_op = &gid_gt;
|
||||
fallthrough;
|
||||
case Opt_gid_lt:
|
||||
case Opt_egid_lt:
|
||||
if ((token == Opt_gid_lt) || (token == Opt_egid_lt))
|
||||
entry->gid_op = &gid_lt;
|
||||
fallthrough;
|
||||
case Opt_gid_eq:
|
||||
case Opt_egid_eq:
|
||||
eid_token = (token == Opt_egid_eq) ||
|
||||
(token == Opt_egid_gt) ||
|
||||
(token == Opt_egid_lt);
|
||||
|
||||
ima_log_string_op(ab, eid_token ? "egid" : "gid",
|
||||
args[0].from, token);
|
||||
|
||||
if (gid_valid(entry->gid)) {
|
||||
result = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
result = kstrtoul(args[0].from, 10, &lnum);
|
||||
if (!result) {
|
||||
entry->gid = make_kgid(current_user_ns(),
|
||||
(gid_t)lnum);
|
||||
if (!gid_valid(entry->gid) ||
|
||||
(((gid_t)lnum) != lnum))
|
||||
result = -EINVAL;
|
||||
else
|
||||
entry->flags |= eid_token
|
||||
? IMA_EGID : IMA_GID;
|
||||
}
|
||||
break;
|
||||
case Opt_fowner_gt:
|
||||
@ -1536,8 +1628,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||
entry->fowner_op = &uid_lt;
|
||||
fallthrough;
|
||||
case Opt_fowner_eq:
|
||||
ima_log_string_op(ab, "fowner", args[0].from,
|
||||
entry->fowner_op);
|
||||
ima_log_string_op(ab, "fowner", args[0].from, token);
|
||||
|
||||
if (uid_valid(entry->fowner)) {
|
||||
result = -EINVAL;
|
||||
@ -1546,13 +1637,41 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||
|
||||
result = kstrtoul(args[0].from, 10, &lnum);
|
||||
if (!result) {
|
||||
entry->fowner = make_kuid(current_user_ns(), (uid_t)lnum);
|
||||
if (!uid_valid(entry->fowner) || (((uid_t)lnum) != lnum))
|
||||
entry->fowner = make_kuid(current_user_ns(),
|
||||
(uid_t)lnum);
|
||||
if (!uid_valid(entry->fowner) ||
|
||||
(((uid_t)lnum) != lnum))
|
||||
result = -EINVAL;
|
||||
else
|
||||
entry->flags |= IMA_FOWNER;
|
||||
}
|
||||
break;
|
||||
case Opt_fgroup_gt:
|
||||
entry->fgroup_op = &gid_gt;
|
||||
fallthrough;
|
||||
case Opt_fgroup_lt:
|
||||
if (token == Opt_fgroup_lt)
|
||||
entry->fgroup_op = &gid_lt;
|
||||
fallthrough;
|
||||
case Opt_fgroup_eq:
|
||||
ima_log_string_op(ab, "fgroup", args[0].from, token);
|
||||
|
||||
if (gid_valid(entry->fgroup)) {
|
||||
result = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
result = kstrtoul(args[0].from, 10, &lnum);
|
||||
if (!result) {
|
||||
entry->fgroup = make_kgid(current_user_ns(),
|
||||
(gid_t)lnum);
|
||||
if (!gid_valid(entry->fgroup) ||
|
||||
(((gid_t)lnum) != lnum))
|
||||
result = -EINVAL;
|
||||
else
|
||||
entry->flags |= IMA_FGROUP;
|
||||
}
|
||||
break;
|
||||
case Opt_obj_user:
|
||||
ima_log_string(ab, "obj_user", args[0].from);
|
||||
result = ima_lsm_rule_init(entry, args,
|
||||
@ -1768,9 +1887,11 @@ void *ima_policy_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
loff_t l = *pos;
|
||||
struct ima_rule_entry *entry;
|
||||
struct list_head *ima_rules_tmp;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(entry, ima_rules, list) {
|
||||
ima_rules_tmp = rcu_dereference(ima_rules);
|
||||
list_for_each_entry_rcu(entry, ima_rules_tmp, list) {
|
||||
if (!l--) {
|
||||
rcu_read_unlock();
|
||||
return entry;
|
||||
@ -1789,7 +1910,8 @@ void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
rcu_read_unlock();
|
||||
(*pos)++;
|
||||
|
||||
return (&entry->list == ima_rules) ? NULL : entry;
|
||||
return (&entry->list == &ima_default_rules ||
|
||||
&entry->list == &ima_policy_rules) ? NULL : entry;
|
||||
}
|
||||
|
||||
void ima_policy_stop(struct seq_file *m, void *v)
|
||||
@ -1936,6 +2058,28 @@ int ima_policy_show(struct seq_file *m, void *v)
|
||||
seq_puts(m, " ");
|
||||
}
|
||||
|
||||
if (entry->flags & IMA_GID) {
|
||||
snprintf(tbuf, sizeof(tbuf), "%d", __kgid_val(entry->gid));
|
||||
if (entry->gid_op == &gid_gt)
|
||||
seq_printf(m, pt(Opt_gid_gt), tbuf);
|
||||
else if (entry->gid_op == &gid_lt)
|
||||
seq_printf(m, pt(Opt_gid_lt), tbuf);
|
||||
else
|
||||
seq_printf(m, pt(Opt_gid_eq), tbuf);
|
||||
seq_puts(m, " ");
|
||||
}
|
||||
|
||||
if (entry->flags & IMA_EGID) {
|
||||
snprintf(tbuf, sizeof(tbuf), "%d", __kgid_val(entry->gid));
|
||||
if (entry->gid_op == &gid_gt)
|
||||
seq_printf(m, pt(Opt_egid_gt), tbuf);
|
||||
else if (entry->gid_op == &gid_lt)
|
||||
seq_printf(m, pt(Opt_egid_lt), tbuf);
|
||||
else
|
||||
seq_printf(m, pt(Opt_egid_eq), tbuf);
|
||||
seq_puts(m, " ");
|
||||
}
|
||||
|
||||
if (entry->flags & IMA_FOWNER) {
|
||||
snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->fowner));
|
||||
if (entry->fowner_op == &uid_gt)
|
||||
@ -1947,6 +2091,17 @@ int ima_policy_show(struct seq_file *m, void *v)
|
||||
seq_puts(m, " ");
|
||||
}
|
||||
|
||||
if (entry->flags & IMA_FGROUP) {
|
||||
snprintf(tbuf, sizeof(tbuf), "%d", __kgid_val(entry->fgroup));
|
||||
if (entry->fgroup_op == &gid_gt)
|
||||
seq_printf(m, pt(Opt_fgroup_gt), tbuf);
|
||||
else if (entry->fgroup_op == &gid_lt)
|
||||
seq_printf(m, pt(Opt_fgroup_lt), tbuf);
|
||||
else
|
||||
seq_printf(m, pt(Opt_fgroup_eq), tbuf);
|
||||
seq_puts(m, " ");
|
||||
}
|
||||
|
||||
if (entry->flags & IMA_VALIDATE_ALGOS) {
|
||||
seq_puts(m, "appraise_algos=");
|
||||
ima_policy_show_appraise_algos(m, entry->allowed_algos);
|
||||
@ -2014,6 +2169,7 @@ bool ima_appraise_signature(enum kernel_read_file_id id)
|
||||
struct ima_rule_entry *entry;
|
||||
bool found = false;
|
||||
enum ima_hooks func;
|
||||
struct list_head *ima_rules_tmp;
|
||||
|
||||
if (id >= READING_MAX_ID)
|
||||
return false;
|
||||
@ -2021,7 +2177,8 @@ bool ima_appraise_signature(enum kernel_read_file_id id)
|
||||
func = read_idmap[id] ?: FILE_CHECK;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(entry, ima_rules, list) {
|
||||
ima_rules_tmp = rcu_dereference(ima_rules);
|
||||
list_for_each_entry_rcu(entry, ima_rules_tmp, list) {
|
||||
if (entry->action != APPRAISE)
|
||||
continue;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user