[lxc-devel] [lxc/master] Add MIPS support

jcowgill on Github lxc-bot at linuxcontainers.org
Tue Aug 16 11:09:58 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 586 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160816/31811fc0/attachment.bin>
-------------- next part --------------
From 6b8f203a0186b1eb0217b1153bf26d78b8b23862 Mon Sep 17 00:00:00 2001
From: James Cowgill <james410 at cowgill.org.uk>
Date: Fri, 12 Aug 2016 15:54:14 +0000
Subject: [PATCH 1/3] Add mips signalfd syscall numbers

Signed-off-by: James Cowgill <james410 at cowgill.org.uk>
---
 src/lxc/utils.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index b541e07..98b4e13 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -117,6 +117,12 @@ struct signalfd_siginfo
 #      define __NR_signalfd4 322
 #    elif __arm__
 #      define __NR_signalfd4 355
+#    elif __mips__ && _MIPS_SIM == _ABIO32
+#      define __NR_signalfd4 4324
+#    elif __mips__ && _MIPS_SIM == _ABI64
+#      define __NR_signalfd4 5283
+#    elif __mips__ && _MIPS_SIM == _ABIN32
+#      define __NR_signalfd4 6287
 #    endif
 #endif
 
@@ -132,6 +138,12 @@ struct signalfd_siginfo
 #      define __NR_signalfd 316
 #    elif __arm__
 #      define __NR_signalfd 349
+#    elif __mips__ && _MIPS_SIM == _ABIO32
+#      define __NR_signalfd 4317
+#    elif __mips__ && _MIPS_SIM == _ABI64
+#      define __NR_signalfd 5276
+#    elif __mips__ && _MIPS_SIM == _ABIN32
+#      define __NR_signalfd 6280
 #    endif
 #endif
 

From f6e626131676f55115e5a6023dcba59835d30abf Mon Sep 17 00:00:00 2001
From: James Cowgill <james410 at cowgill.org.uk>
Date: Mon, 15 Aug 2016 16:09:44 +0000
Subject: [PATCH 2/3] Implement MIPS seccomp handling

MIPS processors implement 3 ABIs: o32, n64 and n32 (similar to x32). The kernel
treats each ABI separately so syscalls disallowed on "all" arches should be
added to all three seccomp sets. This is implemented by expanding compat_arch
and compat_ctx to accept two compat architectures.

After this, the MIPS hostarch detection code and config section code is added.

Signed-off-by: James Cowgill <james410 at cowgill.org.uk>
---
 src/lxc/seccomp.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 123 insertions(+), 18 deletions(-)

diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c
index 451e315..0374eca 100644
--- a/src/lxc/seccomp.c
+++ b/src/lxc/seccomp.c
@@ -125,9 +125,23 @@ enum lxc_hostarch_t {
 	lxc_seccomp_arch_ppc64,
 	lxc_seccomp_arch_ppc64le,
 	lxc_seccomp_arch_ppc,
+	lxc_seccomp_arch_mips,
+	lxc_seccomp_arch_mips64,
+	lxc_seccomp_arch_mips64n32,
+	lxc_seccomp_arch_mipsel,
+	lxc_seccomp_arch_mipsel64,
+	lxc_seccomp_arch_mipsel64n32,
 	lxc_seccomp_arch_unknown = 999,
 };
 
+#ifdef __MIPSEL__
+# define MIPS_ARCH_O32 lxc_seccomp_arch_mipsel
+# define MIPS_ARCH_N64 lxc_seccomp_arch_mipsel64
+#else
+# define MIPS_ARCH_O32 lxc_seccomp_arch_mips
+# define MIPS_ARCH_N64 lxc_seccomp_arch_mips64
+#endif
+
 int get_hostarch(void)
 {
 	struct utsname uts;
@@ -149,6 +163,10 @@ int get_hostarch(void)
 		return lxc_seccomp_arch_ppc64;
 	else if (strncmp(uts.machine, "ppc", 3) == 0)
 		return lxc_seccomp_arch_ppc;
+	else if (strncmp(uts.machine, "mips64", 6) == 0)
+		return MIPS_ARCH_N64;
+	else if (strncmp(uts.machine, "mips", 4) == 0)
+		return MIPS_ARCH_O32;
 	return lxc_seccomp_arch_unknown;
 }
 
@@ -174,6 +192,14 @@ scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, uint32_t default_policy_
 #ifdef SCMP_ARCH_PPC
 	case lxc_seccomp_arch_ppc: arch = SCMP_ARCH_PPC; break;
 #endif
+#ifdef SCMP_ARCH_MIPS
+	case lxc_seccomp_arch_mips: arch = SCMP_ARCH_MIPS; break;
+	case lxc_seccomp_arch_mips64: arch = SCMP_ARCH_MIPS64; break;
+	case lxc_seccomp_arch_mips64n32: arch = SCMP_ARCH_MIPS64N32; break;
+	case lxc_seccomp_arch_mipsel: arch = SCMP_ARCH_MIPSEL; break;
+	case lxc_seccomp_arch_mipsel64: arch = SCMP_ARCH_MIPSEL64; break;
+	case lxc_seccomp_arch_mipsel64n32: arch = SCMP_ARCH_MIPSEL64N32; break;
+#endif
 	default: return NULL;
 	}
 
@@ -260,12 +286,12 @@ static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf)
 {
 	char *p;
 	int ret;
-	scmp_filter_ctx compat_ctx = NULL;
+	scmp_filter_ctx compat_ctx[2] = { NULL, NULL };
 	bool blacklist = false;
 	uint32_t default_policy_action = -1, default_rule_action = -1, action;
 	enum lxc_hostarch_t native_arch = get_hostarch(),
 			    cur_rule_arch = native_arch;
-	uint32_t compat_arch = SCMP_ARCH_NATIVE;
+	uint32_t compat_arch[2] = { SCMP_ARCH_NATIVE, SCMP_ARCH_NATIVE };
 
 	if (strncmp(line, "blacklist", 9) == 0)
 		blacklist = true;
@@ -295,27 +321,49 @@ static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf)
 
 	if (native_arch == lxc_seccomp_arch_amd64) {
 		cur_rule_arch = lxc_seccomp_arch_all;
-		compat_arch = SCMP_ARCH_X86;
-		compat_ctx = get_new_ctx(lxc_seccomp_arch_i386,
+		compat_arch[0] = SCMP_ARCH_X86;
+		compat_ctx[0] = get_new_ctx(lxc_seccomp_arch_i386,
 				default_policy_action);
-		if (!compat_ctx)
+		if (!compat_ctx[0])
 			goto bad;
 #ifdef SCMP_ARCH_PPC
 	} else if (native_arch == lxc_seccomp_arch_ppc64) {
 		cur_rule_arch = lxc_seccomp_arch_all;
-		compat_arch = SCMP_ARCH_PPC;
-		compat_ctx = get_new_ctx(lxc_seccomp_arch_ppc,
+		compat_arch[0] = SCMP_ARCH_PPC;
+		compat_ctx[0] = get_new_ctx(lxc_seccomp_arch_ppc,
 				default_policy_action);
-		if (!compat_ctx)
+		if (!compat_ctx[0])
 			goto bad;
 #endif
 #ifdef SCMP_ARCH_ARM
 	} else if (native_arch == lxc_seccomp_arch_arm64) {
 		cur_rule_arch = lxc_seccomp_arch_all;
-		compat_arch = SCMP_ARCH_ARM;
-		compat_ctx = get_new_ctx(lxc_seccomp_arch_arm,
+		compat_arch[0] = SCMP_ARCH_ARM;
+		compat_ctx[0] = get_new_ctx(lxc_seccomp_arch_arm,
+				default_policy_action);
+		if (!compat_ctx[0])
+			goto bad;
+#endif
+#ifdef SCMP_ARCH_MIPS
+	} else if (native_arch == lxc_seccomp_arch_mips64) {
+		cur_rule_arch = lxc_seccomp_arch_all;
+		compat_arch[0] = SCMP_ARCH_MIPS;
+		compat_arch[1] = SCMP_ARCH_MIPS64N32;
+		compat_ctx[0] = get_new_ctx(lxc_seccomp_arch_mips,
+				default_policy_action);
+		compat_ctx[1] = get_new_ctx(lxc_seccomp_arch_mips64n32,
+				default_policy_action);
+		if (!compat_ctx[0] || !compat_ctx[1])
+			goto bad;
+	} else if (native_arch == lxc_seccomp_arch_mipsel64) {
+		cur_rule_arch = lxc_seccomp_arch_all;
+		compat_arch[0] = SCMP_ARCH_MIPSEL;
+		compat_arch[1] = SCMP_ARCH_MIPSEL64N32;
+		compat_ctx[0] = get_new_ctx(lxc_seccomp_arch_mipsel,
 				default_policy_action);
-		if (!compat_ctx)
+		compat_ctx[1] = get_new_ctx(lxc_seccomp_arch_mipsel64n32,
+				default_policy_action);
+		if (!compat_ctx[0] || !compat_ctx[1])
 			goto bad;
 #endif
 	}
@@ -413,6 +461,53 @@ static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf)
 				cur_rule_arch = lxc_seccomp_arch_ppc;
 			}
 #endif
+#ifdef SCMP_ARCH_MIPS
+			else if (strcmp(line, "[mips64]") == 0 ||
+					strcmp(line, "[MIPS64]") == 0) {
+				if (native_arch != lxc_seccomp_arch_mips64) {
+					cur_rule_arch = lxc_seccomp_arch_unknown;
+					continue;
+				}
+				cur_rule_arch = lxc_seccomp_arch_mips64;
+			} else if (strcmp(line, "[mips64n32]") == 0 ||
+					strcmp(line, "[MIPS64N32]") == 0) {
+				if (native_arch != lxc_seccomp_arch_mips64) {
+					cur_rule_arch = lxc_seccomp_arch_unknown;
+					continue;
+				}
+				cur_rule_arch = lxc_seccomp_arch_mips64n32;
+			} else if (strcmp(line, "[mips]") == 0 ||
+					strcmp(line, "[MIPS]") == 0) {
+				if (native_arch != lxc_seccomp_arch_mips &&
+						native_arch != lxc_seccomp_arch_mips64) {
+					cur_rule_arch = lxc_seccomp_arch_unknown;
+					continue;
+				}
+				cur_rule_arch = lxc_seccomp_arch_mips;
+			} else if (strcmp(line, "[mipsel64]") == 0 ||
+					strcmp(line, "[MIPSEL64]") == 0) {
+				if (native_arch != lxc_seccomp_arch_mipsel64) {
+					cur_rule_arch = lxc_seccomp_arch_unknown;
+					continue;
+				}
+				cur_rule_arch = lxc_seccomp_arch_mipsel64;
+			} else if (strcmp(line, "[mipsel64n32]") == 0 ||
+					strcmp(line, "[MIPSEL64N32]") == 0) {
+				if (native_arch != lxc_seccomp_arch_mipsel64) {
+					cur_rule_arch = lxc_seccomp_arch_unknown;
+					continue;
+				}
+				cur_rule_arch = lxc_seccomp_arch_mipsel64n32;
+			} else if (strcmp(line, "[mipsel]") == 0 ||
+					strcmp(line, "[MIPSEL]") == 0) {
+				if (native_arch != lxc_seccomp_arch_mipsel &&
+						native_arch != lxc_seccomp_arch_mipsel64) {
+					cur_rule_arch = lxc_seccomp_arch_unknown;
+					continue;
+				}
+				cur_rule_arch = lxc_seccomp_arch_mipsel;
+			}
+#endif
 			else
 				goto bad_arch;
 
@@ -432,14 +527,18 @@ static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf)
 
 		if (cur_rule_arch == native_arch ||
 		    cur_rule_arch == lxc_seccomp_arch_native ||
-		    compat_arch == SCMP_ARCH_NATIVE) {
+		    compat_arch[0] == SCMP_ARCH_NATIVE) {
 			INFO("Adding native rule for %s action %d", line, action);
 			if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, conf->seccomp_ctx, action))
 				goto bad_rule;
 		}
 		else if (cur_rule_arch != lxc_seccomp_arch_all) {
+			int arch_index =
+				cur_rule_arch == lxc_seccomp_arch_mips64n32 ||
+				cur_rule_arch == lxc_seccomp_arch_mipsel64n32 ? 1 : 0;
+
 			INFO("Adding compat-only rule for %s action %d", line, action);
-			if (!do_resolve_add_rule(compat_arch, line, compat_ctx, action))
+			if (!do_resolve_add_rule(compat_arch[arch_index], line, compat_ctx[arch_index], action))
 				goto bad_rule;
 		}
 		else {
@@ -447,14 +546,18 @@ static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf)
 			if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, conf->seccomp_ctx, action))
 				goto bad_rule;
 			INFO("Adding compat rule for %s action %d", line, action);
-			if (!do_resolve_add_rule(compat_arch, line, compat_ctx, action))
+			if (!do_resolve_add_rule(compat_arch[0], line, compat_ctx[0], action))
+				goto bad_rule;
+			if (compat_arch[1] != SCMP_ARCH_NATIVE &&
+				!do_resolve_add_rule(compat_arch[1], line, compat_ctx[1], action))
 				goto bad_rule;
 		}
 	}
 
-	if (compat_ctx) {
+	if (compat_ctx[0]) {
 		INFO("Merging in the compat seccomp ctx into the main one");
-		if (seccomp_merge(conf->seccomp_ctx, compat_ctx) != 0) {
+		if (seccomp_merge(conf->seccomp_ctx, compat_ctx[0]) != 0 ||
+			(compat_ctx[1] != NULL && seccomp_merge(conf->seccomp_ctx, compat_ctx[1]) != 0)) {
 			ERROR("Error merging compat seccomp contexts");
 			goto bad;
 		}
@@ -466,8 +569,10 @@ static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf)
 	ERROR("Unsupported arch: %s", line);
 bad_rule:
 bad:
-	if (compat_ctx)
-		seccomp_release(compat_ctx);
+	if (compat_ctx[0])
+		seccomp_release(compat_ctx[0]);
+	if (compat_ctx[1])
+		seccomp_release(compat_ctx[1]);
 	return -1;
 }
 #else /* HAVE_DECL_SECCOMP_SYSCALL_RESOLVE_NAME_ARCH */

From 7114cce184fb50151df5e17114e01a9ea5cc89f2 Mon Sep 17 00:00:00 2001
From: James Cowgill <james410 at cowgill.org.uk>
Date: Mon, 15 Aug 2016 16:10:00 +0000
Subject: [PATCH 3/3] Add mips hostarch detection to templates/lxc-debian.in

Signed-off-by: James Cowgill <james410 at cowgill.org.uk>
---
 templates/lxc-debian.in | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/templates/lxc-debian.in b/templates/lxc-debian.in
index 3ada90d..18d8422 100644
--- a/templates/lxc-debian.in
+++ b/templates/lxc-debian.in
@@ -647,6 +647,8 @@ if [ $? -ne 0 ]; then
 fi
 eval set -- "$options"
 
+littleendian=$(lscpu | grep '^Byte Order' | grep -q Little && echo yes)
+
 arch=$(uname -m)
 if [ "$arch" = "i686" ]; then
     arch="i386"
@@ -654,6 +656,10 @@ elif [ "$arch" = "x86_64" ]; then
     arch="amd64"
 elif [ "$arch" = "armv7l" ]; then
     arch="armhf"
+elif [ "$arch" = "mips" -a "$littleendian" = "yes" ]; then
+    arch="mipsel"
+elif [ "$arch" = "mips64" -a "$littleendian" = "yes" ]; then
+    arch="mips64el"
 fi
 hostarch=$arch
 mainonly=1
@@ -711,6 +717,14 @@ if [ "$interpreter" = "" ] ; then
         echo "can't create $arch container on $hostarch"
         exit 1
     fi
+
+    if [ $hostarch = "mips" -a $arch != "mips" ] || \
+       [ $hostarch = "mipsel" -a $arch != "mipsel" ] || \
+       [ $hostarch = "mips64" -a $arch != "mips" -a $arch != "mips64" ] || \
+       [ $hostarch = "mips64el" -a $arch != "mipsel" -a $arch != "mips64el" ]; then
+        echo "can't create $arch container on $hostarch"
+        exit 1
+    fi
 else
     if ! file -b "${interpreter}" |grep -q "statically linked" ; then
         echo "'${interpreter}' must be statically linked" 1>&2


More information about the lxc-devel mailing list