Re: [RFC][PATCH] selinux: avoid silent denials in permissive mode under RCU walk

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Dec 4, 2018 at 3:39 PM Stephen Smalley <sds@xxxxxxxxxxxxx> wrote:
> commit 0dc1ba24f7fff6 ("SELINUX: Make selinux cache VFS RCU walks safe")
> results in no audit messages at all if in permissive mode because the
> cache is updated during the rcu walk and thus no denial occurs on
> the subsequent ref walk.  Fix this by not updating the cache when
> performing a non-blocking permission check.  This only affects search
> and symlink read checks during rcu walk.
>
> Fixes: 0dc1ba24f7fff6 ("SELINUX: Make selinux cache VFS RCU walks safe")
> Reported-by: BMK <bmktuwien@xxxxxxxxx>
> Signed-off-by: Stephen Smalley <sds@xxxxxxxxxxxxx>
> ---
>  security/selinux/avc.c         | 9 ++++++---
>  security/selinux/hooks.c       | 4 +++-
>  security/selinux/include/avc.h | 1 +
>  3 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/security/selinux/avc.c b/security/selinux/avc.c
> index 635e5c1e3e48..f0e7bc0dc442 100644
> --- a/security/selinux/avc.c
> +++ b/security/selinux/avc.c
> @@ -1021,8 +1021,10 @@ static noinline int avc_denied(struct selinux_state *state,
>             !(avd->flags & AVD_FLAGS_PERMISSIVE))
>                 return -EACCES;
>
> -       avc_update_node(state->avc, AVC_CALLBACK_GRANT, requested, driver,
> -                       xperm, ssid, tsid, tclass, avd->seqno, NULL, flags);
> +       if (!(flags & AVC_NONBLOCKING))
> +               avc_update_node(state->avc, AVC_CALLBACK_GRANT, requested,
> +                               driver, xperm, ssid, tsid, tclass, avd->seqno,
> +                               NULL, flags);

I realize the issue here is specific to the VFS code paths, but if we
are going to introduce a general AVC flag to tell the AVC code not to
block, it seems like we should honor it everywhere.  I would suggest
moving the check into avc_update_node() itself (it's static, so
hopefully any perf impact will be negligible).

>         return 0;
>  }
>
> @@ -1199,7 +1201,8 @@ int avc_has_perm_flags(struct selinux_state *state,
>         struct av_decision avd;
>         int rc, rc2;
>
> -       rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0,
> +       rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested,
> +                                 (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0,
>                                   &avd);
>
>         rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc,
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 7ce012d9ec51..9b05f84808d9 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -3196,7 +3196,9 @@ static int selinux_inode_permission(struct inode *inode, int mask)
>                 return PTR_ERR(isec);
>
>         rc = avc_has_perm_noaudit(&selinux_state,
> -                                 sid, isec->sid, isec->sclass, perms, 0, &avd);
> +                                 sid, isec->sid, isec->sclass, perms,
> +                                 (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0,
> +                                 &avd);
>         audited = avc_audit_required(perms, &avd, rc,
>                                      from_access ? FILE__AUDIT_ACCESS : 0,
>                                      &denied);
> diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
> index ef899bcfd2cb..74ea50977c20 100644
> --- a/security/selinux/include/avc.h
> +++ b/security/selinux/include/avc.h
> @@ -142,6 +142,7 @@ static inline int avc_audit(struct selinux_state *state,
>
>  #define AVC_STRICT 1 /* Ignore permissive mode. */
>  #define AVC_EXTENDED_PERMS 2   /* update extended permissions */
> +#define AVC_NONBLOCKING    4   /* non blocking */
>  int avc_has_perm_noaudit(struct selinux_state *state,
>                          u32 ssid, u32 tsid,
>                          u16 tclass, u32 requested,
> --
> 2.19.2
>

-- 
paul moore
www.paul-moore.com



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux