The commit is pushed to "branch-rh7-3.10.0-327.36.1.vz7.20.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh7-3.10.0-327.36.1.vz7.20.12 ------> commit 185e8e4a2979bd98a935095fc19bdfefcabc78a5 Author: Cyrill Gorcunov <gorcu...@virtuozzo.com> Date: Thu Dec 8 17:30:03 2016 +0400
ve/seccomp, ptrace: Save original BPF program when setting the filer 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> --- kernel/seccomp.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/kernel/seccomp.c b/kernel/seccomp.c index b5f6d50..2d0927b 100644 --- a/kernel/seccomp.c +++ b/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 sock_fprog *fprog) 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 sock_fprog *fprog) 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_struct *tsk) 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_struct *task, unsigned long filter_off, 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