lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 29 Apr 2015 15:37:35 +0200
From:	Nicolas Schichan <nschichan@...ebox.fr>
To:	Kees Cook <keescook@...omium.org>,
	Andy Lutomirski <luto@...capital.net>,
	Will Drewry <wad@...omium.org>, linux-kernel@...r.kernel.org
Cc:	Nicolas Schichan <nschichan@...ebox.fr>
Subject: [PATCH 2/4] seccomp: rework seccomp_prepare_filter().

- Try to use the classic BPF JIT via bpf_jit_compile().

- Use bpf_migrate_filter() from NET filter code instead of the double
  bpf_convert_filter() followed by bpf_prog_select_runtime() if
  classic bpf_jit_compile() did not succeed in producing native code.

Signed-off-by: Nicolas Schichan <nschichan@...ebox.fr>
---
 kernel/seccomp.c | 47 ++++++++++++++++++++---------------------------
 1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 4f44028..4f9fea7 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -348,8 +348,7 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
 {
 	struct seccomp_filter *filter;
 	unsigned long fp_size;
-	struct sock_filter *fp;
-	int new_len;
+	struct bpf_prog *fp;
 	long ret;
 
 	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
@@ -368,29 +367,38 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
 				     CAP_SYS_ADMIN) != 0)
 		return ERR_PTR(-EACCES);
 
-	fp = kzalloc(fp_size, GFP_KERNEL|__GFP_NOWARN);
+	fp = bpf_prog_alloc(bpf_prog_size(fprog->len), __GFP_NOWARN);
 	if (!fp)
 		return ERR_PTR(-ENOMEM);
 
 	/* Copy the instructions from fprog. */
 	ret = -EFAULT;
-	if (copy_from_user(fp, fprog->filter, fp_size))
+	if (copy_from_user(fp->insns, fprog->filter, fp_size))
 		goto free_prog;
+	fp->len = fprog->len;
 
 	/* Check and rewrite the fprog via the skb checker */
-	ret = bpf_check_classic(fp, fprog->len);
+	ret = bpf_check_classic(fp->insns, fp->len);
 	if (ret)
 		goto free_prog;
 
 	/* Check and rewrite the fprog for seccomp use */
-	ret = seccomp_check_filter(fp, fprog->len);
+	ret = seccomp_check_filter(fp->insns, fp->len);
 	if (ret)
 		goto free_prog;
 
-	/* Convert 'sock_filter' insns to 'bpf_insn' insns */
-	ret = bpf_convert_filter(fp, fprog->len, NULL, &new_len);
-	if (ret)
-		goto free_prog;
+	/* try to use the classic JIT */
+	bpf_jit_compile(fp);
+
+	if (!fp->jited) {
+		/*
+		 * if classic JIT has failed, try to convert it to an
+		 * internal filter
+		 */
+		fp = bpf_migrate_filter(fp);
+		if (IS_ERR(fp))
+			return fp;
+	}
 
 	/* Allocate a new seccomp_filter */
 	ret = -ENOMEM;
@@ -399,28 +407,13 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
 	if (!filter)
 		goto free_prog;
 
-	filter->prog = bpf_prog_alloc(bpf_prog_size(new_len), __GFP_NOWARN);
-	if (!filter->prog)
-		goto free_filter;
-
-	ret = bpf_convert_filter(fp, fprog->len, filter->prog->insnsi, &new_len);
-	if (ret)
-		goto free_filter_prog;
-
-	kfree(fp);
+	filter->prog = fp;
 	atomic_set(&filter->usage, 1);
-	filter->prog->len = new_len;
-
-	bpf_prog_select_runtime(filter->prog);
 
 	return filter;
 
-free_filter_prog:
-	__bpf_prog_free(filter->prog);
-free_filter:
-	kfree(filter);
 free_prog:
-	kfree(fp);
+	bpf_prog_destroy(fp);
 	return ERR_PTR(ret);
 }
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ