Re: [RFC PATCH] selinux: Use call_rcu for policydb and booleans

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

 



On Wed, Aug 19, 2020 at 10:32 AM peter enderborg
<peter.enderborg@xxxxxxxx> wrote:
> From 8184ea3648b18718fdb460a30dfc7f848b7bc6a2 Mon Sep 17 00:00:00 2001
> From: Peter Enderborg <peter.enderborg@xxxxxxxx>
> Date: Wed, 19 Aug 2020 10:20:28 +0200
> Subject: [RFC PATCH] selinux: Use call_rcu for policydb and booleans
>
> This patch adds call_rcu that moves sycronize out
> out call path. In the callback we can no call
> cond_resched so they have to be remvoed.

Did you notice Stephen's comment about vfree() in the v1 patch [1]?
That probably also needs addressing, and after that you'll likely end
up with something very similar to the v1 patch anyway.

[1] https://lore.kernel.org/selinux/20200818194311.30018-1-stephen.smalley.work@xxxxxxxxx/

>
> Signed-off-by: Peter Enderborg <peter.enderborg@xxxxxxxx>
> ---
>  security/selinux/ss/policydb.c |  6 -----
>  security/selinux/ss/services.c | 43 ++++++++++++++++++++++++++++++----
>  2 files changed, 39 insertions(+), 10 deletions(-)
>
[...]
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index ba9347517e5b..11eff3a98ef8 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -2184,11 +2184,29 @@ static void selinux_notify_policy_change(struct selinux_state *state,
>         selinux_xfrm_notify_policyload();
>  }
>
> +struct deprecated_policy {
> +       struct selinux_policy *policy;
> +       int partial;
> +       struct rcu_head rcu;

Why not just add these fields to struct selinux_policy directly? Then
you can avoid the speculative allocation of struct deprecated_policy.

> +};
> +
> +void policy_reclaim(struct rcu_head *rp)
> +{
> +       struct deprecated_policy *dep = container_of(rp, struct dep_policy, rcu);
> +
> +       if (dep->partial)
> +               selinux_policy_cond_free(dep->policy);
> +       else
> +               selinux_policy_free(dep->policy);
> +       kfree(dep);
> +}
> +
>  void selinux_policy_commit(struct selinux_state *state,
>                         struct selinux_policy *newpolicy)
>  {
>         struct selinux_policy *oldpolicy;
>         u32 seqno;
> +       struct deprecated_policy *dep;
>
>         /*
>          * NOTE: We do not need to take the rcu read lock
> @@ -2231,8 +2249,16 @@ void selinux_policy_commit(struct selinux_state *state,
>         }
>
>         /* Free the old policy */
> -       synchronize_rcu();
> -       selinux_policy_free(oldpolicy);
> +       /* if cant alloc we need to it the slow way */
> +       dep  = kzalloc(sizeof(struct deprecated_policy), GFP_KERNEL);
> +       if (dep) {
> +               dep->policy = oldpolicy;
> +               dep->partial = 0;
> +               call_rcu(&dep->rcu, policy_reclaim);
> +       } else {
> +               synchronize_rcu();
> +               selinux_policy_free(oldpolicy);
> +       }
>
>         /* Notify others of the policy change */
>         selinux_notify_policy_change(state, seqno);
[...]


--
Ondrej Mosnacek
Software Engineer, Platform Security - SELinux kernel
Red Hat, Inc.




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

  Powered by Linux