Andrey, i'm committing this, but please, review anyway.
-- Best regards, Konstantin Khorenko, Virtuozzo Linux Kernel Team On 12/07/2016 08:29 PM, 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 + 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