Skip to content

Commit c4371d9

Browse files
gegarciajrjohansen
authored andcommitted
apparmor: add io_uring mediation
For now, the io_uring mediation is limited to sqpoll and override_creds. Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
1 parent fa9b63a commit c4371d9

File tree

6 files changed

+131
-2
lines changed

6 files changed

+131
-2
lines changed

security/apparmor/apparmorfs.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,12 @@ static struct aa_sfs_entry aa_sfs_entry_query[] = {
23902390
AA_SFS_DIR("label", aa_sfs_entry_query_label),
23912391
{ }
23922392
};
2393+
2394+
static struct aa_sfs_entry aa_sfs_entry_io_uring[] = {
2395+
AA_SFS_FILE_STRING("mask", "sqpoll override_creds"),
2396+
{ }
2397+
};
2398+
23932399
static struct aa_sfs_entry aa_sfs_entry_features[] = {
23942400
AA_SFS_DIR("policy", aa_sfs_entry_policy),
23952401
AA_SFS_DIR("domain", aa_sfs_entry_domain),
@@ -2403,6 +2409,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
24032409
AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
24042410
AA_SFS_DIR("signal", aa_sfs_entry_signal),
24052411
AA_SFS_DIR("query", aa_sfs_entry_query),
2412+
AA_SFS_DIR("io_uring", aa_sfs_entry_io_uring),
24062413
{ }
24072414
};
24082415

security/apparmor/audit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static const char *const aa_class_names[] = {
5959
"module",
6060
"lsm",
6161
"namespace",
62-
"unknown",
62+
"io_uring",
6363
"unknown",
6464
"unknown",
6565
"unknown",

security/apparmor/include/apparmor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030
#define AA_CLASS_NET 14
3131
#define AA_CLASS_LABEL 16
3232
#define AA_CLASS_POSIX_MQUEUE 17
33-
#define AA_CLASS_IO_URING 18
3433
#define AA_CLASS_MODULE 19
3534
#define AA_CLASS_DISPLAY_LSM 20
3635
#define AA_CLASS_NS 21
36+
#define AA_CLASS_IO_URING 22
3737

3838
#define AA_CLASS_X 31
3939
#define AA_CLASS_DBUS 32

security/apparmor/include/audit.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ enum audit_type {
105105

106106
#define OP_USERNS_CREATE "userns_create"
107107

108+
#define OP_URING_OVERRIDE "uring_override"
109+
#define OP_URING_SQPOLL "uring_sqpoll"
110+
108111
struct apparmor_audit_data {
109112
int error;
110113
int type;
@@ -153,6 +156,9 @@ struct apparmor_audit_data {
153156
const char *data;
154157
unsigned long flags;
155158
} mnt;
159+
struct {
160+
struct aa_label *target;
161+
} uring;
156162
};
157163

158164
struct common_audit_data common;

security/apparmor/include/perms.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848

4949
#define AA_LINK_SUBSET AA_MAY_LOCK /* overlaid */
5050

51+
#define AA_MAY_CREATE_SQPOLL AA_MAY_CREATE
52+
#define AA_MAY_OVERRIDE_CRED AA_MAY_APPEND
53+
#define AA_URING_PERM_MASK (AA_MAY_OVERRIDE_CRED | AA_MAY_CREATE_SQPOLL)
5154

5255
#define PERMS_CHRS_MASK (MAY_READ | MAY_WRITE | AA_MAY_CREATE | \
5356
AA_MAY_DELETE | AA_MAY_LINK | AA_MAY_LOCK | \

security/apparmor/lsm.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,114 @@ static int apparmor_file_mprotect(struct vm_area_struct *vma,
582582
false);
583583
}
584584

585+
#ifdef CONFIG_IO_URING
586+
static const char *audit_uring_mask(u32 mask)
587+
{
588+
if (mask & AA_MAY_CREATE_SQPOLL)
589+
return "sqpoll";
590+
if (mask & AA_MAY_OVERRIDE_CRED)
591+
return "override_creds";
592+
return "";
593+
}
594+
595+
static void audit_uring_cb(struct audit_buffer *ab, void *va)
596+
{
597+
struct apparmor_audit_data *ad = aad_of_va(va);
598+
599+
if (ad->request & AA_URING_PERM_MASK) {
600+
audit_log_format(ab, " requested=\"%s\"",
601+
audit_uring_mask(ad->request));
602+
if (ad->denied & AA_URING_PERM_MASK) {
603+
audit_log_format(ab, " denied=\"%s\"",
604+
audit_uring_mask(ad->denied));
605+
}
606+
}
607+
if (ad->uring.target) {
608+
audit_log_format(ab, " tcontext=");
609+
aa_label_xaudit(ab, labels_ns(ad->subj_label),
610+
ad->uring.target,
611+
FLAGS_NONE, GFP_ATOMIC);
612+
}
613+
}
614+
615+
static int profile_uring(struct aa_profile *profile, u32 request,
616+
struct aa_label *new, int cap,
617+
struct apparmor_audit_data *ad)
618+
{
619+
unsigned int state;
620+
struct aa_ruleset *rules;
621+
int error = 0;
622+
623+
AA_BUG(!profile);
624+
625+
rules = list_first_entry(&profile->rules, typeof(*rules), list);
626+
state = RULE_MEDIATES(rules, AA_CLASS_IO_URING);
627+
if (state) {
628+
struct aa_perms perms = { };
629+
630+
if (new) {
631+
aa_label_match(profile, rules, new, state,
632+
false, request, &perms);
633+
} else {
634+
perms = *aa_lookup_perms(rules->policy, state);
635+
}
636+
aa_apply_modes_to_perms(profile, &perms);
637+
error = aa_check_perms(profile, &perms, request, ad,
638+
audit_uring_cb);
639+
}
640+
641+
return error;
642+
}
643+
644+
/**
645+
* apparmor_uring_override_creds - check the requested cred override
646+
* @new: the target creds
647+
*
648+
* Check to see if the current task is allowed to override it's credentials
649+
* to service an io_uring operation.
650+
*/
651+
int apparmor_uring_override_creds(const struct cred *new)
652+
{
653+
struct aa_profile *profile;
654+
struct aa_label *label;
655+
int error;
656+
DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_IO_URING,
657+
OP_URING_OVERRIDE);
658+
659+
ad.uring.target = cred_label(new);
660+
label = __begin_current_label_crit_section();
661+
error = fn_for_each(label, profile,
662+
profile_uring(profile, AA_MAY_OVERRIDE_CRED,
663+
cred_label(new), CAP_SYS_ADMIN, &ad));
664+
__end_current_label_crit_section(label);
665+
666+
return error;
667+
}
668+
669+
/**
670+
* apparmor_uring_sqpoll - check if a io_uring polling thread can be created
671+
*
672+
* Check to see if the current task is allowed to create a new io_uring
673+
* kernel polling thread.
674+
*/
675+
int apparmor_uring_sqpoll(void)
676+
{
677+
struct aa_profile *profile;
678+
struct aa_label *label;
679+
int error;
680+
DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_IO_URING,
681+
OP_URING_SQPOLL);
682+
683+
label = __begin_current_label_crit_section();
684+
error = fn_for_each(label, profile,
685+
profile_uring(profile, AA_MAY_CREATE_SQPOLL,
686+
NULL, CAP_SYS_ADMIN, &ad));
687+
__end_current_label_crit_section(label);
688+
689+
return error;
690+
}
691+
#endif /* CONFIG_IO_URING */
692+
585693
static int apparmor_sb_mount(const char *dev_name, const struct path *path,
586694
const char *type, unsigned long flags, void *data)
587695
{
@@ -1346,6 +1454,11 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
13461454
LSM_HOOK_INIT(secid_to_secctx, apparmor_secid_to_secctx),
13471455
LSM_HOOK_INIT(secctx_to_secid, apparmor_secctx_to_secid),
13481456
LSM_HOOK_INIT(release_secctx, apparmor_release_secctx),
1457+
1458+
#ifdef CONFIG_IO_URING
1459+
LSM_HOOK_INIT(uring_override_creds, apparmor_uring_override_creds),
1460+
LSM_HOOK_INIT(uring_sqpoll, apparmor_uring_sqpoll),
1461+
#endif
13491462
};
13501463

13511464
/*

0 commit comments

Comments
 (0)