From: Casey Schaufler <casey@xxxxxxxxxxxxxxxx> Add Smack privilege checks for io_uring. Use CAP_MAC_OVERRIDE for the override_creds case and CAP_MAC_ADMIN for creating a polling thread. These choices are based on conjecture regarding the intent of the surrounding code. Signed-off-by: Casey Schaufler <casey@xxxxxxxxxxxxxxxx> [PM: make the smack_uring_* funcs static] Signed-off-by: Paul Moore <paul@xxxxxxxxxxxxxx> --- v2: - made the smack_uring_* funcs static v1: - initial draft --- security/smack/smack_lsm.c | 64 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 223a6da0e6dc..7fb094098f38 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4691,6 +4691,66 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, return 0; } +#ifdef CONFIG_IO_URING +/** + * smack_uring_override_creds - Is io_uring cred override allowed? + * @new: the target creds + * + * Check to see if the current task is allowed to override it's credentials + * to service an io_uring operation. + */ +static int smack_uring_override_creds(const struct cred *new) +{ + struct task_smack *tsp = smack_cred(current_cred()); + struct task_smack *nsp = smack_cred(new); + +#if 1 + if (tsp->smk_task == nsp->smk_task) + pr_info("%s: Smack matches %s\n", __func__, + tsp->smk_task->smk_known); + else + pr_info("%s: Smack override check %s to %s\n", __func__, + tsp->smk_task->smk_known, nsp->smk_task->smk_known); +#endif + /* + * Allow the degenerate case where the new Smack value is + * the same as the current Smack value. + */ + if (tsp->smk_task == nsp->smk_task) + return 0; + +#if 1 + pr_info("%s: Smack sqpoll %s\n", __func__, + smack_privileged_cred(CAP_MAC_OVERRIDE, current_cred()) ? + "ok by Smack" : "disallowed (No CAP_MAC_OVERRIDE)"); +#endif + if (smack_privileged_cred(CAP_MAC_OVERRIDE, current_cred())) + return 0; + + return -EPERM; +} + +/** + * smack_uring_sqpoll - check if a io_uring polling thread can be created + * + * Check to see if the current task is allowed to create a new io_uring + * kernel polling thread. + */ +static int smack_uring_sqpoll(void) +{ +#if 1 + pr_info("%s: Smack new ring %s\n", __func__, + smack_privileged_cred(CAP_MAC_ADMIN, current_cred()) ? + "ok by Smack" : "disallowed (No CAP_MAC_ADMIN)"); +#endif + if (smack_privileged_cred(CAP_MAC_ADMIN, current_cred())) + return 0; + + return -EPERM; +} + +#endif /* CONFIG_IO_URING */ + struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_cred = sizeof(struct task_smack), .lbs_file = sizeof(struct smack_known *), @@ -4843,6 +4903,10 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(inode_copy_up, smack_inode_copy_up), LSM_HOOK_INIT(inode_copy_up_xattr, smack_inode_copy_up_xattr), LSM_HOOK_INIT(dentry_create_files_as, smack_dentry_create_files_as), +#ifdef CONFIG_IO_URING + LSM_HOOK_INIT(uring_override_creds, smack_uring_override_creds), + LSM_HOOK_INIT(uring_sqpoll, smack_uring_sqpoll), +#endif };