[lxc-devel] [lxd/master] seccomp: cap instruction limit and log buffer to reasonable sizes

brauner on Github lxc-bot at linuxcontainers.org
Wed Aug 12 21:19:18 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 527 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200812/1ac4cab8/attachment.bin>
-------------- next part --------------
From a4ad0739d51f8a5a06da129490891e109917c9e8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 12 Aug 2020 23:16:21 +0200
Subject: [PATCH] seccomp: cap instruction limit and log buffer to reasonable
 sizes

No more than the current limit of 1 million instructions aka 8 mb and no more
than a 4096 byte log buffer.

Reported-by: Alban Crequy <alban.crequy at gmail.com>
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/seccomp/seccomp.go | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/lxd/seccomp/seccomp.go b/lxd/seccomp/seccomp.go
index 2565e0d477..4f7647893e 100644
--- a/lxd/seccomp/seccomp.go
+++ b/lxd/seccomp/seccomp.go
@@ -277,8 +277,8 @@ static int handle_bpf_syscall(int notify_fd, int mem_fd, struct seccomp_notify_p
 {
 	__do_close int pidfd = -EBADF, bpf_target_fd = -EBADF, bpf_attach_fd = -EBADF,
 		       bpf_prog_fd = -EBADF;
-	__do_free char *log_buf = NULL;
 	__do_free struct bpf_insn *insn = NULL;
+	char log_buf[4096];
 	char license[128];
 	size_t insn_size;
 	union bpf_attr attr = {}, new_attr;
@@ -287,9 +287,9 @@ static int handle_bpf_syscall(int notify_fd, int mem_fd, struct seccomp_notify_p
 	int ret;
 	int cmd;
 
-	*bpf_cmd = -EINVAL;
-	*bpf_prog_type = -EINVAL;
-	*bpf_attach_type = -EINVAL;
+	*bpf_cmd		= -EINVAL;
+	*bpf_prog_type		= -EINVAL;
+	*bpf_attach_type	= -EINVAL;
 
 	if (attr_len < req->data.args[2])
 		return -EFBIG;
@@ -328,6 +328,11 @@ static int handle_bpf_syscall(int notify_fd, int mem_fd, struct seccomp_notify_p
 		if (attr.prog_type != BPF_PROG_TYPE_CGROUP_DEVICE)
 			return -EINVAL;
 
+		// bpf is currently limited to 1 million instructions. Don't
+		// allow the container to allocate more than that.
+		if (attr.insn_cnt > 1000000)
+			return -EINVAL;
+
 		insn_size = sizeof(struct bpf_insn) * attr.insn_cnt;
 
 		insn = malloc(insn_size);
@@ -342,13 +347,11 @@ static int handle_bpf_syscall(int notify_fd, int mem_fd, struct seccomp_notify_p
 
 		memcpy(&new_attr, &attr, sizeof(attr));
 
-		if (attr.log_size > 0 && attr.log_size <= (UINT_MAX / 2)) {
-			log_buf = malloc(attr.log_size);
-			if (!log_buf)
-				return -ENOMEM;
-		} else {
-			new_attr.log_size = 0;
-		}
+		if (attr.log_size > sizeof(log_buf))
+			new_attr.log_size = sizeof(log_buf);
+
+		if (new_attr.log_size > 0)
+			new_attr.log_buf = ptr_to_u64(log_buf);
 
 		if (attr.license && pread(mem_fd, license, sizeof(license), attr.license) < 0)
 			return -errno;
@@ -358,7 +361,9 @@ static int handle_bpf_syscall(int notify_fd, int mem_fd, struct seccomp_notify_p
 		bpf_prog_fd = bpf(cmd, &new_attr, sizeof(new_attr));
 		if (bpf_prog_fd < 0) {
 			int saved_errno = errno;
-			if (log_buf && pwrite(mem_fd, log_buf, attr.log_size, attr.log_buf) != attr.log_size)
+
+			if ((new_attr.log_size) > 0 && (pwrite(mem_fd, log_buf, new_attr.log_size,
+							       attr.log_buf) != new_attr.log_size))
 				errno = saved_errno;
 			return -errno;
 		}


More information about the lxc-devel mailing list