Commit f1f05ef3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'selinux-pr-20211217' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux fix from Paul Moore:
 "Another small SELinux fix for v5.16 to ensure that we don't block on
  memory allocations while holding a spinlock.

  This passes all our tests without problem"

* tag 'selinux-pr-20211217' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: fix sleeping function called from invalid context
parents 0bb43aec cc274ae7
...@@ -611,10 +611,11 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag, ...@@ -611,10 +611,11 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
return 0; return 0;
} }
static int parse_sid(struct super_block *sb, const char *s, u32 *sid) static int parse_sid(struct super_block *sb, const char *s, u32 *sid,
gfp_t gfp)
{ {
int rc = security_context_str_to_sid(&selinux_state, s, int rc = security_context_str_to_sid(&selinux_state, s,
sid, GFP_KERNEL); sid, gfp);
if (rc) if (rc)
pr_warn("SELinux: security_context_str_to_sid" pr_warn("SELinux: security_context_str_to_sid"
"(%s) failed for (dev %s, type %s) errno=%d\n", "(%s) failed for (dev %s, type %s) errno=%d\n",
...@@ -685,7 +686,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, ...@@ -685,7 +686,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
*/ */
if (opts) { if (opts) {
if (opts->fscontext) { if (opts->fscontext) {
rc = parse_sid(sb, opts->fscontext, &fscontext_sid); rc = parse_sid(sb, opts->fscontext, &fscontext_sid,
GFP_KERNEL);
if (rc) if (rc)
goto out; goto out;
if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
...@@ -694,7 +696,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, ...@@ -694,7 +696,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
sbsec->flags |= FSCONTEXT_MNT; sbsec->flags |= FSCONTEXT_MNT;
} }
if (opts->context) { if (opts->context) {
rc = parse_sid(sb, opts->context, &context_sid); rc = parse_sid(sb, opts->context, &context_sid,
GFP_KERNEL);
if (rc) if (rc)
goto out; goto out;
if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
...@@ -703,7 +706,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, ...@@ -703,7 +706,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
sbsec->flags |= CONTEXT_MNT; sbsec->flags |= CONTEXT_MNT;
} }
if (opts->rootcontext) { if (opts->rootcontext) {
rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid); rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid,
GFP_KERNEL);
if (rc) if (rc)
goto out; goto out;
if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
...@@ -712,7 +716,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, ...@@ -712,7 +716,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
sbsec->flags |= ROOTCONTEXT_MNT; sbsec->flags |= ROOTCONTEXT_MNT;
} }
if (opts->defcontext) { if (opts->defcontext) {
rc = parse_sid(sb, opts->defcontext, &defcontext_sid); rc = parse_sid(sb, opts->defcontext, &defcontext_sid,
GFP_KERNEL);
if (rc) if (rc)
goto out; goto out;
if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
...@@ -2702,14 +2707,14 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts) ...@@ -2702,14 +2707,14 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
return (sbsec->flags & SE_MNTMASK) ? 1 : 0; return (sbsec->flags & SE_MNTMASK) ? 1 : 0;
if (opts->fscontext) { if (opts->fscontext) {
rc = parse_sid(sb, opts->fscontext, &sid); rc = parse_sid(sb, opts->fscontext, &sid, GFP_NOWAIT);
if (rc) if (rc)
return 1; return 1;
if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
return 1; return 1;
} }
if (opts->context) { if (opts->context) {
rc = parse_sid(sb, opts->context, &sid); rc = parse_sid(sb, opts->context, &sid, GFP_NOWAIT);
if (rc) if (rc)
return 1; return 1;
if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
...@@ -2719,14 +2724,14 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts) ...@@ -2719,14 +2724,14 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
struct inode_security_struct *root_isec; struct inode_security_struct *root_isec;
root_isec = backing_inode_security(sb->s_root); root_isec = backing_inode_security(sb->s_root);
rc = parse_sid(sb, opts->rootcontext, &sid); rc = parse_sid(sb, opts->rootcontext, &sid, GFP_NOWAIT);
if (rc) if (rc)
return 1; return 1;
if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
return 1; return 1;
} }
if (opts->defcontext) { if (opts->defcontext) {
rc = parse_sid(sb, opts->defcontext, &sid); rc = parse_sid(sb, opts->defcontext, &sid, GFP_NOWAIT);
if (rc) if (rc)
return 1; return 1;
if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
...@@ -2749,14 +2754,14 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts) ...@@ -2749,14 +2754,14 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
return 0; return 0;
if (opts->fscontext) { if (opts->fscontext) {
rc = parse_sid(sb, opts->fscontext, &sid); rc = parse_sid(sb, opts->fscontext, &sid, GFP_KERNEL);
if (rc) if (rc)
return rc; return rc;
if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
goto out_bad_option; goto out_bad_option;
} }
if (opts->context) { if (opts->context) {
rc = parse_sid(sb, opts->context, &sid); rc = parse_sid(sb, opts->context, &sid, GFP_KERNEL);
if (rc) if (rc)
return rc; return rc;
if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
...@@ -2765,14 +2770,14 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts) ...@@ -2765,14 +2770,14 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
if (opts->rootcontext) { if (opts->rootcontext) {
struct inode_security_struct *root_isec; struct inode_security_struct *root_isec;
root_isec = backing_inode_security(sb->s_root); root_isec = backing_inode_security(sb->s_root);
rc = parse_sid(sb, opts->rootcontext, &sid); rc = parse_sid(sb, opts->rootcontext, &sid, GFP_KERNEL);
if (rc) if (rc)
return rc; return rc;
if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
goto out_bad_option; goto out_bad_option;
} }
if (opts->defcontext) { if (opts->defcontext) {
rc = parse_sid(sb, opts->defcontext, &sid); rc = parse_sid(sb, opts->defcontext, &sid, GFP_KERNEL);
if (rc) if (rc)
return rc; return rc;
if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment