Add the arch_syscall_translate() function which converts the syscall
table from the native architecture to the desired architecture.

Signed-off-by: Paul Moore <[email protected]>
---
 src/Makefile      |    2 +
 src/api.c         |    8 ++++++
 src/arch-i386.c   |    7 +++++
 src/arch-i386.h   |    1 +
 src/arch-x86_64.c |   33 ++++++++++++++++++++++++
 src/arch-x86_64.h |    1 +
 src/arch.c        |   73 ++++++++++++++++++++++++++++++++++++++++-------------
 src/arch.h        |    1 +
 8 files changed, 107 insertions(+), 19 deletions(-)
 create mode 100644 src/arch-x86_64.c

diff --git a/src/Makefile b/src/Makefile
index f2386a0..394e21a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -39,7 +39,7 @@ LIB_SHARED = libseccomp.so.$(VERSION_RELEASE)
 OBJS = \
        api.o db.o arch.o \
        arch-i386.o arch-i386-syscalls.o \
-       arch-x86_64-syscalls.o \
+       arch-x86_64.o arch-x86_64-syscalls.o \
        hash.o \
        gen_pfc.o gen_bpf.o
 
diff --git a/src/api.c b/src/api.c
index 7d6bf3a..3e7f8d7 100644
--- a/src/api.c
+++ b/src/api.c
@@ -160,6 +160,10 @@ int seccomp_syscall_priority(scmp_filter_ctx ctx, int 
syscall, uint8_t priority)
                return -EINVAL;
        filter = (struct db_filter *)ctx;
 
+       rc = arch_syscall_translate(filter->arch, &syscall);
+       if (rc < 0)
+               return rc;
+
        /* if this is a pseudo syscall (syscall < 0) then we need to rewrite
         * the syscall for some arch specific reason */
        if (syscall < 0) {
@@ -209,6 +213,10 @@ static int _seccomp_rule_add(struct db_filter *filter,
        if (action == filter->attr.act_default)
                return -EPERM;
 
+       rc = arch_syscall_translate(filter->arch, &syscall);
+       if (rc < 0)
+               return rc;
+
        /* collect the arguments for the filter rule */
        chain_len_max = arch_arg_count_max(filter->arch);
        chain = malloc(sizeof(*chain) * chain_len_max);
diff --git a/src/arch-i386.c b/src/arch-i386.c
index 7695bfc..577d6c8 100644
--- a/src/arch-i386.c
+++ b/src/arch-i386.c
@@ -21,6 +21,7 @@
 
 #include <stdlib.h>
 #include <errno.h>
+#include <linux/audit.h>
 
 #include "arch.h"
 #include "arch-i386.h"
@@ -29,6 +30,12 @@
 #define __i386_NR_socketcall           102
 #define __i386_NR_ipc                  117
 
+const struct arch_def arch_def_i386 = {
+       .token = AUDIT_ARCH_I386,
+       .size = ARCH_SIZE_32,
+       .endian = ARCH_ENDIAN_LITTLE,
+};
+
 /**
  * Rewrite a syscall value to match the architecture
  * @param arch the architecture definition
diff --git a/src/arch-i386.h b/src/arch-i386.h
index cea4e9a..bc24dbe 100644
--- a/src/arch-i386.h
+++ b/src/arch-i386.h
@@ -28,6 +28,7 @@
 
 #define i386_arg_count_max             6
 
+extern const struct arch_def arch_def_i386;
 extern const struct arch_syscall_def i386_syscall_table[];
 
 int i386_syscall_rewrite(const struct arch_def *arch, int *syscall);
diff --git a/src/arch-x86_64.c b/src/arch-x86_64.c
new file mode 100644
index 0000000..9f6af9c
--- /dev/null
+++ b/src/arch-x86_64.c
@@ -0,0 +1,33 @@
+/**
+ * Enhanced Seccomp x86_64 Specific Code
+ *
+ * Copyright (c) 2012 Red Hat <[email protected]>
+ * Author: Paul Moore <[email protected]>
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <linux/audit.h>
+
+#include "arch.h"
+#include "arch-x86_64.h"
+
+const struct arch_def arch_def_x86_64 = {
+       .token = AUDIT_ARCH_X86_64,
+       .size = ARCH_SIZE_64,
+       .endian = ARCH_ENDIAN_LITTLE,
+};
diff --git a/src/arch-x86_64.h b/src/arch-x86_64.h
index 3f13c17..73de6db 100644
--- a/src/arch-x86_64.h
+++ b/src/arch-x86_64.h
@@ -29,6 +29,7 @@
 
 #define x86_64_arg_count_max           6
 
+extern const struct arch_def arch_def_x86_64;
 extern const struct arch_syscall_def x86_64_syscall_table[];
 
 #define x86_64_arg_offset_lo(x)                (arch_arg_offset(x))
diff --git a/src/arch.c b/src/arch.c
index ddd6dce..8ab3c0a 100644
--- a/src/arch.c
+++ b/src/arch.c
@@ -59,6 +59,27 @@ const struct arch_def arch_def_native = {
 };
 
 /**
+ * Lookup the syscall table for an architecture
+ * @param token the architecure token
+ *
+ * Return the architecture's syscall table, returns NULL on failure.
+ *
+ */
+const struct arch_syscall_def *_arch_def_lookup(uint32_t token)
+{
+       switch (token) {
+       case AUDIT_ARCH_I386:
+               return i386_syscall_table;
+               break;
+       case AUDIT_ARCH_X86_64:
+               return x86_64_syscall_table;
+               break;
+       }
+
+       return NULL;
+}
+
+/**
  * Determine the maximum number of syscall arguments
  * @param arch the architecture definition
  *
@@ -133,16 +154,9 @@ int arch_syscall_resolve_name(const struct arch_def *arch, 
const char *name)
        unsigned int iter;
        const struct arch_syscall_def *table;
 
-       switch (arch->token) {
-       case AUDIT_ARCH_I386:
-               table = i386_syscall_table;
-               break;
-       case AUDIT_ARCH_X86_64:
-               table = x86_64_syscall_table;
-               break;
-       default:
+       table = _arch_def_lookup(arch->token);
+       if (table == NULL)
                return __NR_SCMP_ERROR;
-       }
 
        /* XXX - plenty of room for future improvement here */
        for (iter = 0; table[iter].name != NULL; iter++) {
@@ -168,16 +182,9 @@ const char *arch_syscall_resolve_num(const struct arch_def 
*arch, int num)
        unsigned int iter;
        const struct arch_syscall_def *table;
 
-       switch (arch->token) {
-       case AUDIT_ARCH_I386:
-               table = i386_syscall_table;
-               break;
-       case AUDIT_ARCH_X86_64:
-               table = x86_64_syscall_table;
-               break;
-       default:
+       table = _arch_def_lookup(arch->token);
+       if (table == NULL)
                return NULL;
-       }
 
        /* XXX - plenty of room for future improvement here */
        for (iter = 0; table[iter].num != __NR_SCMP_ERROR; iter++) {
@@ -189,6 +196,36 @@ const char *arch_syscall_resolve_num(const struct arch_def 
*arch, int num)
 }
 
 /**
+ * Translate the syscall number
+ * @param arch the architecture definition
+ * @param syscall the syscall number
+ *
+ * Translate the syscall number, in the context of the native architecure, to
+ * the provided architecure.  Returns zero on success, negative values on
+ * failure.
+ *
+ */
+int arch_syscall_translate(const struct arch_def *arch, int *syscall)
+{
+       int sc_num;
+       const char *sc_name;
+
+       if (arch->token != arch_def_native.token) {
+               sc_name = arch_syscall_resolve_num(&arch_def_native, *syscall);
+               if (sc_name == NULL)
+                       return -EFAULT;
+
+               sc_num = arch_syscall_resolve_name(arch, sc_name);
+               if (sc_num == __NR_SCMP_ERROR)
+                       return -EFAULT;
+
+               *syscall = sc_num;
+       }
+
+       return 0;
+}
+
+/**
  * Rewrite a syscall value to match the architecture
  * @param arch the architecture definition
  * @param syscall the syscall number
diff --git a/src/arch.h b/src/arch.h
index 31a965e..4e14ca6 100644
--- a/src/arch.h
+++ b/src/arch.h
@@ -89,6 +89,7 @@ int arch_arg_offset_hi(const struct arch_def *arch, unsigned 
int arg);
 int arch_syscall_resolve_name(const struct arch_def *arch, const char *name);
 const char *arch_syscall_resolve_num(const struct arch_def *arch, int num);
 
+int arch_syscall_translate(const struct arch_def *arch, int *syscall);
 int arch_syscall_rewrite(const struct arch_def *arch, int *syscall);
 
 int arch_filter_rewrite(const struct arch_def *arch,


------------------------------------------------------------------------------
Got visibility?
Most devs has no idea what their production app looks like.
Find out how fast your code is with AppDynamics Lite.
http://ad.doubleclick.net/clk;262219671;13503038;y?
http://info.appdynamics.com/FreeJavaPerformanceDownload.html
_______________________________________________
libseccomp-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libseccomp-discuss

Reply via email to