On Wed, Dec 07, 2016 at 08:29:22PM +0300, Cyrill Gorcunov wrote:
> The vanilla kernel is quite reworked in filter management, in particular
> the filters passed into sockets or seccomp are saved in the userspace form
> as struct bpf_prog::orig_prog. We can't port all the patches right now,
> lets rather do a trick for seccomp sake and simply carry a copy inside
> struct seccomp_filter. The socket filters are decoded into userspace form
> anyway so this area is safe.
> 
> https://jira.sw.ru/browse/PSBM-55593
> 
> CC: Andrey Vagin <ava...@openvz.org>
> Signed-off-by: Cyrill Gorcunov <gorcu...@openvz.org>
> ---
> The patch is on top of [PATCH rh7] seccomp, ptrace: Fix typo in filter 
> fetching
> 
>  kernel/seccomp.c |   25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> Index: linux-pcs7.git/kernel/seccomp.c
> ===================================================================
> --- linux-pcs7.git.orig/kernel/seccomp.c
> +++ linux-pcs7.git/kernel/seccomp.c
> @@ -54,6 +54,9 @@
>  struct seccomp_filter {
>       atomic_t usage;
>       struct seccomp_filter *prev;
> +#if CONFIG_VE

Why do you not use CONFIG_CHECKPOINT_RESTORE here?

> +     struct sock_fprog orig_prog;
> +#endif
>       unsigned short len;  /* Instruction count */
>       struct sock_filter insns[];
>  };
> @@ -265,6 +268,16 @@ static long seccomp_attach_filter(struct
>       if (copy_from_user(filter->insns, fprog->filter, fp_size))
>               goto fail;
>  
> +#if CONFIG_VE
> +     filter->orig_prog.len = fprog->len;
> +     filter->orig_prog.filter = kmemdup(filter->insns, fp_size,
> +                                        GFP_KERNEL|__GFP_NOWARN);
> +     if (!filter->orig_prog.filter) {
> +             ret = -ENOMEM;
> +             goto fail;
> +     }
> +#endif
> +
>       /* Check and rewrite the fprog via the skb checker */
>       ret = sk_chk_filter(filter->insns, filter->len);
>       if (ret)
> @@ -283,6 +296,9 @@ static long seccomp_attach_filter(struct
>       current->seccomp.filter = filter;
>       return 0;
>  fail:
> +#if CONFIG_VE
> +     kfree(filter->orig_prog.filter);
> +#endif
>       kfree(filter);
>       return ret;
>  }
> @@ -332,6 +348,9 @@ void put_seccomp_filter(struct task_stru
>       while (orig && atomic_dec_and_test(&orig->usage)) {
>               struct seccomp_filter *freeme = orig;
>               orig = orig->prev;
> +#if CONFIG_VE
> +             kfree(freeme->orig_prog.filter);
> +#endif
>               kfree(freeme);
>       }
>  }
> @@ -566,8 +585,14 @@ long seccomp_get_filter(struct task_stru
>       get_seccomp_filter(task);
>       spin_unlock_irq(&task->sighand->siglock);
>  
> +#if CONFIG_VE
> +     if (copy_to_user(data, filter->orig_prog.filter,
> +                      filter->orig_prog.len * 
> sizeof(filter->orig_prog.filter[0])))
> +             ret = -EFAULT;
> +#else
>       if (copy_to_user(data, filter->insns, filter->len * 
> sizeof(filter->insns[0])))
>               ret = -EFAULT;
> +#endif
>  
>       put_seccomp_filter(task);
>       return ret;
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to