Skip to content

Commit 3d54351

Browse files
committed
Merge tag 'lsm-pr-20240617' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm
Pull lsm fix from Paul Moore: "A single LSM/IMA patch to fix a problem caused by sleeping while in a RCU critical section" * tag 'lsm-pr-20240617' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm: ima: Avoid blocking in RCU read-side critical section
2 parents 14d7c92 + 9a95c5b commit 3d54351

File tree

11 files changed

+34
-22
lines changed

11 files changed

+34
-22
lines changed

include/linux/lsm_hook_defs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ LSM_HOOK(void, LSM_RET_VOID, key_post_create_or_update, struct key *keyring,
413413

414414
#ifdef CONFIG_AUDIT
415415
LSM_HOOK(int, 0, audit_rule_init, u32 field, u32 op, char *rulestr,
416-
void **lsmrule)
416+
void **lsmrule, gfp_t gfp)
417417
LSM_HOOK(int, 0, audit_rule_known, struct audit_krule *krule)
418418
LSM_HOOK(int, 0, audit_rule_match, u32 secid, u32 field, u32 op, void *lsmrule)
419419
LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule)

include/linux/security.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,15 +2048,16 @@ static inline void security_key_post_create_or_update(struct key *keyring,
20482048

20492049
#ifdef CONFIG_AUDIT
20502050
#ifdef CONFIG_SECURITY
2051-
int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule);
2051+
int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule,
2052+
gfp_t gfp);
20522053
int security_audit_rule_known(struct audit_krule *krule);
20532054
int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule);
20542055
void security_audit_rule_free(void *lsmrule);
20552056

20562057
#else
20572058

20582059
static inline int security_audit_rule_init(u32 field, u32 op, char *rulestr,
2059-
void **lsmrule)
2060+
void **lsmrule, gfp_t gfp)
20602061
{
20612062
return 0;
20622063
}

kernel/auditfilter.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
529529
entry->rule.buflen += f_val;
530530
f->lsm_str = str;
531531
err = security_audit_rule_init(f->type, f->op, str,
532-
(void **)&f->lsm_rule);
532+
(void **)&f->lsm_rule,
533+
GFP_KERNEL);
533534
/* Keep currently invalid fields around in case they
534535
* become valid after a policy reload. */
535536
if (err == -EINVAL) {
@@ -799,7 +800,7 @@ static inline int audit_dupe_lsm_field(struct audit_field *df,
799800

800801
/* our own (refreshed) copy of lsm_rule */
801802
ret = security_audit_rule_init(df->type, df->op, df->lsm_str,
802-
(void **)&df->lsm_rule);
803+
(void **)&df->lsm_rule, GFP_KERNEL);
803804
/* Keep currently invalid fields around in case they
804805
* become valid after a policy reload. */
805806
if (ret == -EINVAL) {

security/apparmor/audit.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ void aa_audit_rule_free(void *vrule)
217217
}
218218
}
219219

220-
int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
220+
int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, gfp_t gfp)
221221
{
222222
struct aa_audit_rule *rule;
223223

@@ -230,14 +230,14 @@ int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
230230
return -EINVAL;
231231
}
232232

233-
rule = kzalloc(sizeof(struct aa_audit_rule), GFP_KERNEL);
233+
rule = kzalloc(sizeof(struct aa_audit_rule), gfp);
234234

235235
if (!rule)
236236
return -ENOMEM;
237237

238238
/* Currently rules are treated as coming from the root ns */
239239
rule->label = aa_label_parse(&root_ns->unconfined->label, rulestr,
240-
GFP_KERNEL, true, false);
240+
gfp, true, false);
241241
if (IS_ERR(rule->label)) {
242242
int err = PTR_ERR(rule->label);
243243
aa_audit_rule_free(rule);

security/apparmor/include/audit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static inline int complain_error(int error)
200200
}
201201

202202
void aa_audit_rule_free(void *vrule);
203-
int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule);
203+
int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, gfp_t gfp);
204204
int aa_audit_rule_known(struct audit_krule *rule);
205205
int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule);
206206

security/integrity/ima/ima.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ static inline void ima_free_modsig(struct modsig *modsig)
546546
#else
547547

548548
static inline int ima_filter_rule_init(u32 field, u32 op, char *rulestr,
549-
void **lsmrule)
549+
void **lsmrule, gfp_t gfp)
550550
{
551551
return -EINVAL;
552552
}

security/integrity/ima/ima_policy.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,8 @@ static void ima_free_rule(struct ima_rule_entry *entry)
401401
kfree(entry);
402402
}
403403

404-
static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
404+
static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry,
405+
gfp_t gfp)
405406
{
406407
struct ima_rule_entry *nentry;
407408
int i;
@@ -410,7 +411,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
410411
* Immutable elements are copied over as pointers and data; only
411412
* lsm rules can change
412413
*/
413-
nentry = kmemdup(entry, sizeof(*nentry), GFP_KERNEL);
414+
nentry = kmemdup(entry, sizeof(*nentry), gfp);
414415
if (!nentry)
415416
return NULL;
416417

@@ -425,7 +426,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
425426

426427
ima_filter_rule_init(nentry->lsm[i].type, Audit_equal,
427428
nentry->lsm[i].args_p,
428-
&nentry->lsm[i].rule);
429+
&nentry->lsm[i].rule,
430+
gfp);
429431
if (!nentry->lsm[i].rule)
430432
pr_warn("rule for LSM \'%s\' is undefined\n",
431433
nentry->lsm[i].args_p);
@@ -438,7 +440,7 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry)
438440
int i;
439441
struct ima_rule_entry *nentry;
440442

441-
nentry = ima_lsm_copy_rule(entry);
443+
nentry = ima_lsm_copy_rule(entry, GFP_KERNEL);
442444
if (!nentry)
443445
return -ENOMEM;
444446

@@ -664,7 +666,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
664666
}
665667

666668
if (rc == -ESTALE && !rule_reinitialized) {
667-
lsm_rule = ima_lsm_copy_rule(rule);
669+
lsm_rule = ima_lsm_copy_rule(rule, GFP_ATOMIC);
668670
if (lsm_rule) {
669671
rule_reinitialized = true;
670672
goto retry;
@@ -1140,7 +1142,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
11401142
entry->lsm[lsm_rule].type = audit_type;
11411143
result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal,
11421144
entry->lsm[lsm_rule].args_p,
1143-
&entry->lsm[lsm_rule].rule);
1145+
&entry->lsm[lsm_rule].rule,
1146+
GFP_KERNEL);
11441147
if (!entry->lsm[lsm_rule].rule) {
11451148
pr_warn("rule for LSM \'%s\' is undefined\n",
11461149
entry->lsm[lsm_rule].args_p);

security/security.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5332,15 +5332,17 @@ void security_key_post_create_or_update(struct key *keyring, struct key *key,
53325332
* @op: rule operator
53335333
* @rulestr: rule context
53345334
* @lsmrule: receive buffer for audit rule struct
5335+
* @gfp: GFP flag used for kmalloc
53355336
*
53365337
* Allocate and initialize an LSM audit rule structure.
53375338
*
53385339
* Return: Return 0 if @lsmrule has been successfully set, -EINVAL in case of
53395340
* an invalid rule.
53405341
*/
5341-
int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule)
5342+
int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule,
5343+
gfp_t gfp)
53425344
{
5343-
return call_int_hook(audit_rule_init, field, op, rulestr, lsmrule);
5345+
return call_int_hook(audit_rule_init, field, op, rulestr, lsmrule, gfp);
53445346
}
53455347

53465348
/**

security/selinux/include/audit.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
* @op: the operator the rule uses
2222
* @rulestr: the text "target" of the rule
2323
* @rule: pointer to the new rule structure returned via this
24+
* @gfp: GFP flag used for kmalloc
2425
*
2526
* Returns 0 if successful, -errno if not. On success, the rule structure
2627
* will be allocated internally. The caller must free this structure with
2728
* selinux_audit_rule_free() after use.
2829
*/
29-
int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule);
30+
int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule,
31+
gfp_t gfp);
3032

3133
/**
3234
* selinux_audit_rule_free - free an selinux audit rule structure.

security/selinux/ss/services.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3507,7 +3507,8 @@ void selinux_audit_rule_free(void *vrule)
35073507
}
35083508
}
35093509

3510-
int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
3510+
int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
3511+
gfp_t gfp)
35113512
{
35123513
struct selinux_state *state = &selinux_state;
35133514
struct selinux_policy *policy;
@@ -3548,7 +3549,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
35483549
return -EINVAL;
35493550
}
35503551

3551-
tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL);
3552+
tmprule = kzalloc(sizeof(struct selinux_audit_rule), gfp);
35523553
if (!tmprule)
35533554
return -ENOMEM;
35543555
context_init(&tmprule->au_ctxt);

0 commit comments

Comments
 (0)