On 2020-03-20 08:47, Aurelien Jarno wrote:
> On 2020-03-20 01:35, Michael Biebl wrote:
> > Am 20.03.20 um 01:32 schrieb Michael Biebl:
> > > Have you tested, that seccomp is working on riscv64 with 5.5?
> > > Something like this should lead to a blocked ping:
> > 
> 
> Indeed that test doesn't work, I mean seccomp is ineffective and the
> ping succeed. It looks like that I should also update the patch you
> pointed, I'll work on that and keep you updated.

So you were right that there are way more things to change than my
initial patch. I came up with the attached patch. With it I confirm that
the test ping service you send fails correctly when running with a 5.5
kernel:

| # systemctl status test
| * test.service - test seccomp filter
|      Loaded: loaded (/etc/systemd/system/test.service; static; vendor preset: 
enabled)
|      Active: failed (Result: signal) since Fri 2020-03-20 17:45:38 CET; 6s ago
|     Process: 771 ExecStart=/bin/ping -c 1 www.debian.org (code=killed, 
signal=SYS)
|    Main PID: 771 (code=killed, signal=SYS)
| 
| Mar 20 17:45:38 riscv64 systemd[1]: Started test seccomp filter.
| Mar 20 17:45:38 riscv64 systemd[1]: test.service: Main process exited, 
code=killed, status=31/SYS
| Mar 20 17:45:38 riscv64 systemd[1]: test.service: Failed with result 'signal'.

Aurelien

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurel...@aurel32.net                 http://www.aurel32.net
From 9bf8b4f3ce9582170c610e57d9dd341ca84ad881 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurel...@aurel32.net>
Date: Fri, 20 Mar 2020 17:41:42 +0100
Subject: [PATCH] seccomp: add support for riscv64

This patch adds seccomp support to the riscv64 architecture. seccomp
support is available in the riscv64 kernel since version 5.5, and it
has just been added to the libseccomp library.

riscv64 uses generic syscalls like aarch64, so I used that architecture
as a reference to find which code has to be modified.

With this patch, the testsuite passes successfully, including the
test-seccomp test. The system boots and works fine with kernel 5.4 (i.e.
without seccomp support) and kernel 5.5 (i.e. with seccomp support). I
have also verified that the "SystemCallFilter=~socket" option prevents a
service to use the ping utility when running on kernel 5.5.
---
 src/nspawn/nspawn-oci.c   |  1 +
 src/shared/seccomp-util.c | 16 ++++++++++++----
 src/test/test-seccomp.c   |  1 +
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/nspawn/nspawn-oci.c b/src/nspawn/nspawn-oci.c
index 782c03c539..e0d42eb6e7 100644
--- a/src/nspawn/nspawn-oci.c
+++ b/src/nspawn/nspawn-oci.c
@@ -1694,6 +1694,7 @@ static int oci_seccomp_arch_from_string(const char *name, uint32_t *ret) {
                 { "SCMP_ARCH_PPC",         SCMP_ARCH_PPC         },
                 { "SCMP_ARCH_PPC64",       SCMP_ARCH_PPC64       },
                 { "SCMP_ARCH_PPC64LE",     SCMP_ARCH_PPC64LE     },
+                { "SCMP_ARCH_RISCV64",     SCMP_ARCH_RISCV64     },
                 { "SCMP_ARCH_S390",        SCMP_ARCH_S390        },
                 { "SCMP_ARCH_S390X",       SCMP_ARCH_S390X       },
                 { "SCMP_ARCH_X32",         SCMP_ARCH_X32         },
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
index eeca17f341..da7e46ac5b 100644
--- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -85,6 +85,8 @@ const uint32_t seccomp_local_archs[] = {
                 SCMP_ARCH_PPC64LE,     /* native */
 #elif defined(__powerpc__)
                 SCMP_ARCH_PPC,
+#elif defined(__riscv) && __riscv_xlen == 64
+                SCMP_ARCH_RISCV64,
 #elif defined(__s390x__)
                 SCMP_ARCH_S390,
                 SCMP_ARCH_S390X,      /* native */
@@ -131,6 +133,8 @@ const char* seccomp_arch_to_string(uint32_t c) {
                 return "ppc64";
         case SCMP_ARCH_PPC64LE:
                 return "ppc64-le";
+        case SCMP_ARCH_RISCV64:
+                return "riscv64";
         case SCMP_ARCH_S390:
                 return "s390";
         case SCMP_ARCH_S390X:
@@ -176,6 +180,8 @@ int seccomp_arch_from_string(const char *n, uint32_t *ret) {
                 *ret = SCMP_ARCH_PPC64;
         else if (streq(n, "ppc64-le"))
                 *ret = SCMP_ARCH_PPC64LE;
+        else if (streq(n, "riscv64"))
+                *ret = SCMP_ARCH_RISCV64;
         else if (streq(n, "s390"))
                 *ret = SCMP_ARCH_S390;
         else if (streq(n, "s390x"))
@@ -1253,7 +1259,7 @@ int seccomp_protect_sysctl(void) {
 
                 log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
-                if (IN_SET(arch, SCMP_ARCH_X32, SCMP_ARCH_AARCH64))
+                if (IN_SET(arch, SCMP_ARCH_X32, SCMP_ARCH_AARCH64, SCMP_ARCH_RISCV64))
                         /* No _sysctl syscall */
                         continue;
 
@@ -1337,6 +1343,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) {
                 case SCMP_ARCH_MIPS64N32:
                 case SCMP_ARCH_MIPSEL64:
                 case SCMP_ARCH_MIPS64:
+                case SCMP_ARCH_RISCV64:
                         /* These we know we support (i.e. are the ones that do not use socketcall()) */
                         supported = true;
                         break;
@@ -1575,7 +1582,7 @@ static int add_seccomp_syscall_filter(scmp_filter_ctx seccomp,
 }
 
 /* For known architectures, check that syscalls are indeed defined or not. */
-#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64)
 assert_cc(SCMP_SYS(shmget) > 0);
 assert_cc(SCMP_SYS(shmat) > 0);
 assert_cc(SCMP_SYS(shmdt) > 0);
@@ -1620,13 +1627,14 @@ int seccomp_memory_deny_write_execute(void) {
                 case SCMP_ARCH_X86_64:
                 case SCMP_ARCH_X32:
                 case SCMP_ARCH_AARCH64:
-                        filter_syscall = SCMP_SYS(mmap); /* amd64, x32 and arm64 have only mmap */
+                case SCMP_ARCH_RISCV64:
+                        filter_syscall = SCMP_SYS(mmap); /* amd64, x32, arm64 and riscv64 have only mmap */
                         shmat_syscall = SCMP_SYS(shmat);
                         break;
 
                 /* Please add more definitions here, if you port systemd to other architectures! */
 
-#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__s390__) && !defined(__s390x__)
+#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__s390__) && !defined(__s390x__) && !(defined(__riscv) && __riscv_xlen == 64)
 #warning "Consider adding the right mmap() syscall definitions here!"
 #endif
                 }
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
index 67900d85e9..8c13b6971c 100644
--- a/src/test/test-seccomp.c
+++ b/src/test/test-seccomp.c
@@ -72,6 +72,7 @@ static void test_architecture_table(void) {
                        "ppc\0"
                        "ppc64\0"
                        "ppc64-le\0"
+                       "riscv64\0"
                        "s390\0"
                        "s390x\0") {
                 uint32_t c;
-- 
2.24.1

Attachment: signature.asc
Description: PGP signature

Reply via email to