[lxc-devel] [lxc/master] Seccomp fixes

flx42 on Github lxc-bot at linuxcontainers.org
Thu May 24 06:07:07 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 439 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180524/c00c34fc/attachment.bin>
-------------- next part --------------
From 3a2cd4b95836130ca4a8bec9157eea52daaeba41 Mon Sep 17 00:00:00 2001
From: Felix Abecassis <fabecassis at nvidia.com>
Date: Wed, 23 May 2018 20:51:42 -0700
Subject: [PATCH 1/4] seccomp: fix off-by-one error in array allocation for
 sscanf

The maximum field width does not include the null terminator.

Signed-off-by: Felix Abecassis <fabecassis at nvidia.com>
---
 src/lxc/seccomp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c
index eeb9c8bf3..6a0a1ffd0 100644
--- a/src/lxc/seccomp.c
+++ b/src/lxc/seccomp.c
@@ -181,7 +181,7 @@ static int get_seccomp_arg_value(char *key, struct v2_rule_args *rule_args)
 	uint64_t mask = 0;
 	enum scmp_compare op = 0;
 	uint32_t index = 0;
-	char s[30] = {0};
+	char s[31] = {0};
 	char *tmp = NULL;
 
 	memset(s, 0, sizeof(s));

From 9c7423ce2f9e96e8f62c3c529855a2b361406e8b Mon Sep 17 00:00:00 2001
From: Felix Abecassis <fabecassis at nvidia.com>
Date: Wed, 23 May 2018 21:28:01 -0700
Subject: [PATCH 2/4] seccomp: remove confusing comment line

Signed-off-by: Felix Abecassis <fabecassis at nvidia.com>
---
 src/lxc/seccomp.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c
index 6a0a1ffd0..9787d0791 100644
--- a/src/lxc/seccomp.c
+++ b/src/lxc/seccomp.c
@@ -164,7 +164,6 @@ static enum scmp_compare parse_v2_rule_op(char *s)
 
 /* This function is used to parse the args string into the structure.
  * args string format:[index,value,op,valueTwo] or [index,value,op]
- * For one arguments, [index,value,valueTwo,op]
  * index: the index for syscall arguments (type uint)
  * value: the value for syscall arguments (type uint64)
  * op: the operator for syscall arguments(string),

From 30adf868bf08b8c2d3197b67fe61159514ff76b6 Mon Sep 17 00:00:00 2001
From: Felix Abecassis <fabecassis at nvidia.com>
Date: Wed, 23 May 2018 21:28:39 -0700
Subject: [PATCH 3/4] seccomp: remove unnecessary memset

Signed-off-by: Felix Abecassis <fabecassis at nvidia.com>
---
 src/lxc/seccomp.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c
index 9787d0791..98ab5cf26 100644
--- a/src/lxc/seccomp.c
+++ b/src/lxc/seccomp.c
@@ -183,7 +183,6 @@ static int get_seccomp_arg_value(char *key, struct v2_rule_args *rule_args)
 	char s[31] = {0};
 	char *tmp = NULL;
 
-	memset(s, 0, sizeof(s));
 	tmp = strchr(key, '[');
 	if (!tmp) {
 		ERROR("Failed to interpret args");

From eacebcc3cb8cf5d29556c85fe826096723475242 Mon Sep 17 00:00:00 2001
From: Felix Abecassis <fabecassis at nvidia.com>
Date: Wed, 23 May 2018 22:25:53 -0700
Subject: [PATCH 4/4] seccomp: fix type mismatch when parsing syscall arguments
 filters

Specifier %lli was insufficient for the type uint64_t, all values
between 2^63-1 and 2^64-1 were silently converted to 2^63-1.

We can't use %llu since it doesn't handle hexadecimal. Instead, we
parse the values as strings and then use strtoull(3).

Signed-off-by: Felix Abecassis <fabecassis at nvidia.com>
---
 src/lxc/seccomp.c | 17 +++++++++++++++--
 src/lxc/utils.c   | 23 +++++++++++++++++++++++
 src/lxc/utils.h   |  1 +
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c
index 98ab5cf26..c7b8c1219 100644
--- a/src/lxc/seccomp.c
+++ b/src/lxc/seccomp.c
@@ -32,6 +32,7 @@
 #include "config.h"
 #include "log.h"
 #include "lxcseccomp.h"
+#include "utils.h"
 
 lxc_log_define(lxc_seccomp, lxc);
 
@@ -180,7 +181,7 @@ static int get_seccomp_arg_value(char *key, struct v2_rule_args *rule_args)
 	uint64_t mask = 0;
 	enum scmp_compare op = 0;
 	uint32_t index = 0;
-	char s[31] = {0};
+	char s[31] = {0}, v[24] = {0}, m[24] = {0};
 	char *tmp = NULL;
 
 	tmp = strchr(key, '[');
@@ -188,12 +189,24 @@ static int get_seccomp_arg_value(char *key, struct v2_rule_args *rule_args)
 		ERROR("Failed to interpret args");
 		return -1;
 	}
-	ret = sscanf(tmp, "[%i,%lli,%30[^0-9^,],%lli", &index, (long long unsigned int *)&value, s, (long long unsigned int *)&mask);
+	ret = sscanf(tmp, "[%i,%23[^,],%30[^0-9^,],%23[^,]", &index, v, s, m);
 	if ((ret != 3 && ret != 4) || index >= 6) {
 		ERROR("Failed to interpret args value");
 		return -1;
 	}
 
+	ret = lxc_safe_uint64(v, &value);
+	if (ret < 0) {
+		ERROR("Invalid argument value");
+		return -1;
+	}
+
+	ret = lxc_safe_uint64(v, &mask);
+	if (ret < 0) {
+		ERROR("Invalid argument mask");
+		return -1;
+	}
+
 	op = parse_v2_rule_op(s);
 	if (op == _SCMP_CMP_MAX) {
 		ERROR("Failed to interpret args operator value");
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index a734b3d6c..2669a4d4b 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -1958,6 +1958,29 @@ int lxc_safe_ulong(const char *numstr, unsigned long *converted)
 	return 0;
 }
 
+int lxc_safe_uint64(const char *numstr, uint64_t *converted)
+{
+	char *err = NULL;
+	uint64_t u;
+
+	while (isspace(*numstr))
+		numstr++;
+
+	if (*numstr == '-')
+		return -EINVAL;
+
+	errno = 0;
+	u = strtoull(numstr, &err, 0);
+	if (errno == ERANGE && u == ULLONG_MAX)
+		return -ERANGE;
+
+	if (err == numstr || *err != '\0')
+		return -EINVAL;
+
+	*converted = u;
+	return 0;
+}
+
 int lxc_safe_int(const char *numstr, int *converted)
 {
 	char *err = NULL;
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 62f087311..dd4510644 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -530,6 +530,7 @@ extern int lxc_safe_int(const char *numstr, int *converted);
 extern int lxc_safe_long(const char *numstr, long int *converted);
 extern int lxc_safe_long_long(const char *numstr, long long int *converted);
 extern int lxc_safe_ulong(const char *numstr, unsigned long *converted);
+extern int lxc_safe_uint64(const char *numstr, uint64_t *converted);
 /* Handles B, kb, MB, GB. Detects overflows and reports -ERANGE. */
 extern int parse_byte_size_string(const char *s, int64_t *converted);
 


More information about the lxc-devel mailing list