[Devel] [PATCH rh7] seccomp, ptrace: Save original BPF program when setting the filer
Cyrill Gorcunov
gorcunov at virtuozzo.com
Wed Dec 7 09:29:22 PST 2016
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 <avagin at openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov at 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;
More information about the Devel
mailing list