Provide syscall name to syscall number resolution.

Signed-off-by: Paul Moore <[email protected]>
---
 doc/Makefile                                |    1 
 doc/man/man3/seccomp_syscall_resolve_name.3 |   96 ++++++
 include/seccomp.h                           |   12 +
 src/Makefile                                |    5 
 src/api.c                                   |   28 ++
 src/arch-i386-syscalls.c                    |  405 +++++++++++++++++++++++++++
 src/arch-i386.h                             |    2 
 src/arch-x86_64-syscalls.c                  |  344 +++++++++++++++++++++++
 src/arch-x86_64.h                           |    2 
 src/arch.c                                  |   73 +++++
 src/arch.h                                  |   24 ++
 tests/.gitignore                            |    1 
 tests/15-resolver.c                         |   36 ++
 tests/15-resolver.tests                     |   11 +
 tests/Makefile                              |    3 
 15 files changed, 1037 insertions(+), 6 deletions(-)
 create mode 100644 doc/man/man3/seccomp_syscall_resolve_name.3
 create mode 100644 src/arch-i386-syscalls.c
 create mode 100644 src/arch-x86_64-syscalls.c
 create mode 100644 tests/15-resolver.c
 create mode 100644 tests/15-resolver.tests

diff --git a/doc/Makefile b/doc/Makefile
index c6d3f52..0869c8e 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -41,6 +41,7 @@ MAN3 = \
        man/man3/seccomp_rule_add.3 \
        man/man3/seccomp_rule_add_exact.3 \
        man/man3/seccomp_syscall_priority.3 \
+       man/man3/seccomp_syscall_resolve_name.3 \
        man/man3/seccomp_export_bpf.3 \
        man/man3/seccomp_export_pfc.3 \
        man/man3/seccomp_attr_set.3 \
diff --git a/doc/man/man3/seccomp_syscall_resolve_name.3 
b/doc/man/man3/seccomp_syscall_resolve_name.3
new file mode 100644
index 0000000..267460c
--- /dev/null
+++ b/doc/man/man3/seccomp_syscall_resolve_name.3
@@ -0,0 +1,96 @@
+.TH "seccomp_syscall_resolve_name" 3 "16 August 2012" "[email protected]" 
"libseccomp Documentation"
+.\" //////////////////////////////////////////////////////////////////////////
+.SH NAME
+.\" //////////////////////////////////////////////////////////////////////////
+seccomp_syscall_resolve_name \- Resolve a syscall name
+.\" //////////////////////////////////////////////////////////////////////////
+.SH SYNOPSIS
+.\" //////////////////////////////////////////////////////////////////////////
+.nf
+.B #include <seccomp.h>
+.sp
+.B typedef void * scmp_filter_ctx;
+.sp
+.BI "int seccomp_rule_add(const char *" name ");"
+.sp
+Link with \fI\-lseccomp\fP.
+.fi
+.\" //////////////////////////////////////////////////////////////////////////
+.SH DESCRIPTION
+.\" //////////////////////////////////////////////////////////////////////////
+.P
+The
+.BR seccomp_syscall_resolve_name ()
+function resolves the commonly used syscall name to the syscall number used by
+the kernel and the rest of the libseccomp API.
+.\" //////////////////////////////////////////////////////////////////////////
+.SH RETURN VALUE
+.\" //////////////////////////////////////////////////////////////////////////
+.P
+The associated syscall number is returned, with the negative pseudo syscall
+number being returned in cases where the given syscall does not exist for the
+architeture.  The value
+.BR __NR_SCMP_ERROR
+is returned in case of error.
+.P
+In all cases, the return value is suitable for use in any libseccomp API
+function which requires the syscall number, examples include
+.BR seccomp_rule_add ()
+and
+.BR seccomp_rule_add_exact ().
+.\" //////////////////////////////////////////////////////////////////////////
+.SH EXAMPLES
+.\" //////////////////////////////////////////////////////////////////////////
+.nf
+#include <seccomp.h>
+
+int main(int argc, char *argv[])
+{
+       int rc = -1;
+       scmp_filter_ctx ctx;
+
+       ctx = seccomp_init(SCMP_ACT_KILL);
+       if (ctx == NULL)
+               goto out;
+
+       /* ... */
+
+       rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW,
+                             seccomp_syscall_resolve_name("open"), 0);
+       if (rc < 0)
+               goto out;
+
+       /* ... */
+
+       rc = seccomp_load(ctx);
+       if (rc < 0)
+               goto out;
+
+       /* ... */
+
+out:
+       seccomp_release(ctx);
+       return -rc;
+}
+.fi
+.\" //////////////////////////////////////////////////////////////////////////
+.SH NOTES
+.\" //////////////////////////////////////////////////////////////////////////
+.P
+While the seccomp filter can be generated independent of the kernel, kernel
+support is required to load and enforce the seccomp filter generated by
+libseccomp.
+.P
+The libseccomp project site, with more information and the source code
+repository, can be found at http://libseccomp.sf.net.  This library is 
currently
+under development, please report any bugs at the project site or directly to
+the author.
+.\" //////////////////////////////////////////////////////////////////////////
+.SH AUTHOR
+.\" //////////////////////////////////////////////////////////////////////////
+Paul Moore <[email protected]>
+.\" //////////////////////////////////////////////////////////////////////////
+.SH SEE ALSO
+.\" //////////////////////////////////////////////////////////////////////////
+.BR seccomp_rule_add (3),
+.BR seccomp_rule_add_exact (3)
diff --git a/include/seccomp.h b/include/seccomp.h
index 162bac1..f6cffea 100644
--- a/include/seccomp.h
+++ b/include/seccomp.h
@@ -232,6 +232,17 @@ int seccomp_attr_set(scmp_filter_ctx ctx,
                     enum scmp_filter_attr attr, uint32_t value);
 
 /**
+ * Resolve a syscall name to a number
+ * @param name the syscall name
+ *
+ * Resolve the given syscall name to the syscall number.  Returns the syscall
+ * number on success, including negative pseudo syscall numbers (e.g. __PNR_*);
+ * returns __NR_SCMP_ERROR on failure.
+ *
+ */
+int seccomp_syscall_resolve_name(const char *name);
+
+/**
  * Set the priority of a given syscall
  * @param ctx the filter context
  * @param syscall the syscall number
@@ -310,6 +321,7 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd);
  */
 
 /* NOTE - pseudo syscall values {-1..-99} are reserved */
+#define __NR_SCMP_ERROR                -1
 
 #define __PNR_socket           -100
 #ifndef __NR_socket
diff --git a/src/Makefile b/src/Makefile
index 801e814..f2386a0 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -37,8 +37,9 @@ LIB_STATIC = libseccomp.a
 LIB_SHARED = libseccomp.so.$(VERSION_RELEASE)
 
 OBJS = \
-       api.o db.o \
-       arch.o arch-i386.o \
+       api.o db.o arch.o \
+       arch-i386.o arch-i386-syscalls.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 64ee4c6..7d6bf3a 100644
--- a/src/api.c
+++ b/src/api.c
@@ -49,6 +49,21 @@ static int _ctx_valid(const scmp_filter_ctx *ctx)
        return db_valid((struct db_filter *)ctx);
 }
 
+/**
+ * Validate a syscall number
+ * @param syscall the syscall number
+ *
+ * Attempt to perform basic syscall number validation.  Returns zero of the
+ * syscall appears valid, negative values on failure.
+ *
+ */
+static int _syscall_valid(int syscall)
+{
+       if (syscall <= -1 && syscall >= -99)
+               return -EINVAL;
+       return 0;
+}
+
 /* NOTE - function header comment in include/seccomp.h */
 scmp_filter_ctx seccomp_init(uint32_t def_action)
 {
@@ -127,12 +142,21 @@ int seccomp_attr_set(scmp_filter_ctx ctx,
 }
 
 /* NOTE - function header comment in include/seccomp.h */
+int seccomp_syscall_resolve_name(const char *name)
+{
+       if (name == NULL)
+               return -EINVAL;
+
+       return arch_syscall_resolve_name(&arch_def_native, name);
+}
+
+/* NOTE - function header comment in include/seccomp.h */
 int seccomp_syscall_priority(scmp_filter_ctx ctx, int syscall, uint8_t 
priority)
 {
        int rc;
        struct db_filter *filter;
 
-       if (_ctx_valid(ctx))
+       if (_ctx_valid(ctx) || _syscall_valid(syscall))
                return -EINVAL;
        filter = (struct db_filter *)ctx;
 
@@ -176,7 +200,7 @@ static int _seccomp_rule_add(struct db_filter *filter,
        struct db_api_arg *chain = NULL;
        struct scmp_arg_cmp arg_data;
 
-       if (db_valid(filter))
+       if (db_valid(filter) || _syscall_valid(syscall))
                return -EINVAL;
 
        rc = db_action_valid(action);
diff --git a/src/arch-i386-syscalls.c b/src/arch-i386-syscalls.c
new file mode 100644
index 0000000..6a4f0a3
--- /dev/null
+++ b/src/arch-i386-syscalls.c
@@ -0,0 +1,405 @@
+/**
+ * Enhanced Seccomp i386 Syscall Table
+ *
+ * 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 <seccomp.h>
+
+#include "arch.h"
+#include "arch-i386.h"
+
+/* NOTE: based on Linux 3.4.7 */
+const struct arch_syscall_def i386_syscall_table[] = \
+{
+       { "accept", __PNR_accept },
+       { "access", 33 },
+       { "acct", 51 },
+       { "add_key", 286 },
+       { "adjtimex", 124 },
+       { "afs_syscall", 137 },
+       { "alarm", 27 },
+       { "bdflush", 134 },
+       { "bind", __PNR_bind },
+       { "break", 17 },
+       { "brk", 45 },
+       { "capget", 184 },
+       { "capset", 185 },
+       { "chdir", 12 },
+       { "chmod", 15 },
+       { "chown", 182 },
+       { "chown32", 212 },
+       { "chroot", 61 },
+       { "clock_adjtime", 343 },
+       { "clock_getres", 266 },
+       { "clock_gettime", 265 },
+       { "clock_nanosleep", 267 },
+       { "clock_settime", 264 },
+       { "clone", 120 },
+       { "close", 6 },
+       { "connect", __PNR_connect },
+       { "creat", 8 },
+       { "create_module", 127 },
+       { "delete_module", 129 },
+       { "dup", 41 },
+       { "dup2", 63 },
+       { "dup3", 330 },
+       { "epoll_create", 254 },
+       { "epoll_create1", 329 },
+       { "epoll_ctl", 255 },
+       { "epoll_pwait", 319 },
+       { "epoll_wait", 256 },
+       { "eventfd", 323 },
+       { "eventfd2", 328 },
+       { "execve", 11 },
+       { "exit", 1 },
+       { "exit_group", 252 },
+       { "faccessat", 307 },
+       { "fadvise64", 250 },
+       { "fadvise64_64", 272 },
+       { "fallocate", 324 },
+       { "fanotify_init", 338 },
+       { "fanotify_mark", 339 },
+       { "fchdir", 133 },
+       { "fchmod", 94 },
+       { "fchmodat", 306 },
+       { "fchown", 95 },
+       { "fchown32", 207 },
+       { "fchownat", 298 },
+       { "fcntl", 55 },
+       { "fcntl64", 221 },
+       { "fdatasync", 148 },
+       { "fgetxattr", 231 },
+       { "flistxattr", 234 },
+       { "flock", 143 },
+       { "fork", 2 },
+       { "fremovexattr", 237 },
+       { "fsetxattr", 228 },
+       { "fstat", 108 },
+       { "fstat64", 197 },
+       { "fstatat64", 300 },
+       { "fstatfs", 100 },
+       { "fstatfs64", 269 },
+       { "fsync", 118 },
+       { "ftime", 35 },
+       { "ftruncate", 93 },
+       { "ftruncate64", 194 },
+       { "futex", 240 },
+       { "futimesat", 299 },
+       { "get_kernel_syms", 130 },
+       { "get_mempolicy", 275 },
+       { "get_robust_list", 312 },
+       { "get_thread_area", 244 },
+       { "getcpu", 318 },
+       { "getcwd", 183 },
+       { "getdents", 141 },
+       { "getdents64", 220 },
+       { "getegid", 50 },
+       { "getegid32", 202 },
+       { "geteuid", 49 },
+       { "geteuid32", 201 },
+       { "getgid", 47 },
+       { "getgid32", 200 },
+       { "getgroups", 80 },
+       { "getgroups32", 205 },
+       { "getitimer", 105 },
+       { "getpeername", __PNR_getpeername },
+       { "getpgid", 132 },
+       { "getpgrp", 65 },
+       { "getpid", 20 },
+       { "getpmsg", 188 },
+       { "getppid", 64 },
+       { "getpriority", 96 },
+       { "getresgid", 171 },
+       { "getresgid32", 211 },
+       { "getresuid", 165 },
+       { "getresuid32", 209 },
+       { "getrlimit", 76 },
+       { "getrusage", 77 },
+       { "getsid", 147 },
+       { "getsockname", __PNR_getsockname },
+       { "getsockopt", __PNR_getsockopt },
+       { "gettid", 224 },
+       { "gettimeofday", 78 },
+       { "getuid", 24 },
+       { "getuid32", 199 },
+       { "getxattr", 229 },
+       { "gtty", 32 },
+       { "idle", 112 },
+       { "init_module", 128 },
+       { "inotify_add_watch", 292 },
+       { "inotify_init", 291 },
+       { "inotify_init1", 332 },
+       { "inotify_rm_watch", 293 },
+       { "io_cancel", 249 },
+       { "io_destroy", 246 },
+       { "io_getevents", 247 },
+       { "io_setup", 245 },
+       { "io_submit", 248 },
+       { "ioctl", 54 },
+       { "ioperm", 101 },
+       { "iopl", 110 },
+       { "ioprio_get", 290 },
+       { "ioprio_set", 289 },
+       { "ipc", 117 },
+       { "kcmp", 349 },
+       { "kexec_load", 283 },
+       { "keyctl", 288 },
+       { "kill", 37 },
+       { "lchown", 16 },
+       { "lchown32", 198 },
+       { "lgetxattr", 230 },
+       { "link", 9 },
+       { "linkat", 303 },
+       { "listen", __PNR_listen },
+       { "listxattr", 232 },
+       { "llistxattr", 233 },
+       { "_llseek", 140 },
+       { "lock", 53 },
+       { "lookup_dcookie", 253 },
+       { "lremovexattr", 236 },
+       { "lseek", 19 },
+       { "lsetxattr", 227 },
+       { "lstat", 107 },
+       { "lstat64", 196 },
+       { "madvise", 219 },
+       { "mbind", 274 },
+       { "migrate_pages", 294 },
+       { "mincore", 218 },
+       { "mkdir", 39 },
+       { "mkdirat", 296 },
+       { "mknod", 14 },
+       { "mknodat", 297 },
+       { "mlock", 150 },
+       { "mlockall", 152 },
+       { "mmap", 90 },
+       { "mmap2", 192 },
+       { "modify_ldt", 123 },
+       { "mount", 21 },
+       { "move_pages", 317 },
+       { "mprotect", 125 },
+       { "mpx", 56 },
+       { "mq_getsetattr", 282 },
+       { "mq_notify", 281 },
+       { "mq_open", 277 },
+       { "mq_timedreceive", 280 },
+       { "mq_timedsend", 279 },
+       { "mq_unlink", 278 },
+       { "mremap", 163 },
+       { "msgctl", __PNR_msgctl },
+       { "msgget", __PNR_msgget },
+       { "msgrcv", __PNR_msgrcv },
+       { "msgsnd", __PNR_msgsnd },
+       { "msync", 144 },
+       { "munlock", 151 },
+       { "munlockall", 153 },
+       { "munmap", 91 },
+       { "name_to_handle_at", 341 },
+       { "nanosleep", 162 },
+       { "_newselect", 142 },
+       { "nfsservctl", 169 },
+       { "nice", 34 },
+       { "oldfstat", 28 },
+       { "oldlstat", 84 },
+       { "oldolduname", 59 },
+       { "oldstat", 18 },
+       { "olduname", 109 },
+       { "open", 5 },
+       { "open_by_handle_at", 342 },
+       { "openat", 295 },
+       { "pause", 29 },
+       { "perf_event_open", 336 },
+       { "personality", 136 },
+       { "pipe", 42 },
+       { "pipe2", 331 },
+       { "pivot_root", 217 },
+       { "poll", 168 },
+       { "ppoll", 309 },
+       { "prctl", 172 },
+       { "pread64", 180 },
+       { "preadv", 333 },
+       { "prlimit64", 340 },
+       { "process_vm_readv", 347 },
+       { "process_vm_writev", 348 },
+       { "prof", 44 },
+       { "profil", 98 },
+       { "pselect6", 308 },
+       { "ptrace", 26 },
+       { "putpmsg", 189 },
+       { "pwrite64", 181 },
+       { "pwritev", 334 },
+       { "query_module", 167 },
+       { "quotactl", 131 },
+       { "read", 3 },
+       { "readahead", 225 },
+       { "readdir", 89 },
+       { "readlink", 85 },
+       { "readlinkat", 305 },
+       { "readv", 145 },
+       { "reboot", 88 },
+       { "recv", __PNR_recv },
+       { "recvfrom", __PNR_recvfrom },
+       { "recvmsg", __PNR_recvmsg },
+       { "recvmmsg", 337 },
+       { "remap_file_pages", 257 },
+       { "removexattr", 235 },
+       { "rename", 38 },
+       { "renameat", 302 },
+       { "request_key", 287 },
+       { "restart_syscall", 0 },
+       { "rmdir", 40 },
+       { "rt_sigaction", 174 },
+       { "rt_sigpending", 176 },
+       { "rt_sigprocmask", 175 },
+       { "rt_sigqueueinfo", 178 },
+       { "rt_sigreturn", 173 },
+       { "rt_sigsuspend", 179 },
+       { "rt_sigtimedwait", 177 },
+       { "rt_tgsigqueueinfo", 335 },
+       { "sched_get_priority_max", 159 },
+       { "sched_get_priority_min", 160 },
+       { "sched_getaffinity", 242 },
+       { "sched_getparam", 155 },
+       { "sched_getscheduler", 157 },
+       { "sched_rr_get_interval", 161 },
+       { "sched_setaffinity", 241 },
+       { "sched_setparam", 154 },
+       { "sched_setscheduler", 156 },
+       { "sched_yield", 158 },
+       { "select", 82 },
+       { "semctl", __PNR_semctl },
+       { "semget", __PNR_semget },
+       { "semop", __PNR_semop },
+       { "semtimedop", __PNR_semtimedop },
+       { "send", __PNR_send },
+       { "sendfile", 187 },
+       { "sendfile64", 239 },
+       { "sendmsg", __PNR_sendmsg },
+       { "sendmmsg", 345 },
+       { "sendto", __PNR_sendto },
+       { "set_mempolicy", 276 },
+       { "set_robust_list", 311 },
+       { "set_thread_area", 243 },
+       { "set_tid_address", 258 },
+       { "setdomainname", 121 },
+       { "setfsgid", 139 },
+       { "setfsgid32", 216 },
+       { "setfsuid", 138 },
+       { "setfsuid32", 215 },
+       { "setgid", 46 },
+       { "setgid32", 214 },
+       { "setgroups", 81 },
+       { "setgroups32", 206 },
+       { "sethostname", 74 },
+       { "setitimer", 104 },
+       { "setns", 346 },
+       { "setpgid", 57 },
+       { "setpriority", 97 },
+       { "setregid", 71 },
+       { "setregid32", 204 },
+       { "setresgid", 170 },
+       { "setresgid32", 210 },
+       { "setresuid", 164 },
+       { "setresuid32", 208 },
+       { "setreuid", 70 },
+       { "setreuid32", 203 },
+       { "setrlimit", 75 },
+       { "setsid", 66 },
+       { "settimeofday", 79 },
+       { "setuid", 23 },
+       { "setuid32", 213 },
+       { "setxattr", 226 },
+       { "sgetmask", 68 },
+       { "shmat", __PNR_shmat },
+       { "shmctl", __PNR_shmctl },
+       { "shmdt", __PNR_shmdt },
+       { "shmget", __PNR_shmget },
+       { "shutdown", __PNR_shutdown },
+       { "sigaction", 67 },
+       { "sigaltstack", 186 },
+       { "signal", 48 },
+       { "signalfd", 321 },
+       { "signalfd4", 327 },
+       { "sigpending", 73 },
+       { "sigprocmask", 126 },
+       { "sigreturn", 119 },
+       { "sigsuspend", 72 },
+       { "socket", __PNR_socket },
+       { "socketcall", 102 },
+       { "socketpair", __PNR_socketpair },
+       { "splice", 313 },
+       { "ssetmask", 69 },
+       { "stat", 106 },
+       { "stat64", 195 },
+       { "statfs", 99 },
+       { "statfs64", 268 },
+       { "stime", 25 },
+       { "stty", 31 },
+       { "swapoff", 115 },
+       { "swapon", 87 },
+       { "symlink", 83 },
+       { "symlinkat", 304 },
+       { "sync", 36 },
+       { "sync_file_range", 314 },
+       { "syncfs", 344 },
+       { "_sysctl", 149 },
+       { "sysfs", 135 },
+       { "sysinfo", 116 },
+       { "syslog", 103 },
+       { "tee", 315 },
+       { "tgkill", 270 },
+       { "time", 13 },
+       { "timer_create", 259 },
+       { "timer_delete", 263 },
+       { "timer_getoverrun", 262 },
+       { "timer_gettime", 261 },
+       { "timer_settime", 260 },
+       { "timerfd_create", 322 },
+       { "timerfd_gettime", 326 },
+       { "timerfd_settime", 325 },
+       { "times", 43 },
+       { "tkill", 238 },
+       { "truncate", 92 },
+       { "truncate64", 193 },
+       { "ugetrlimit", 191 },
+       { "ulimit", 58 },
+       { "umask", 60 },
+       { "umount", 22 },
+       { "umount2", 52 },
+       { "uname", 122 },
+       { "unlink", 10 },
+       { "unlinkat", 301 },
+       { "unshare", 310 },
+       { "uselib", 86 },
+       { "ustat", 62 },
+       { "utime", 30 },
+       { "utimensat", 320 },
+       { "utimes", 271 },
+       { "vfork", 190 },
+       { "vhangup", 111 },
+       { "vm86", 166 },
+       { "vm86old", 113 },
+       { "vmsplice", 316 },
+       { "vserver", 273 },
+       { "wait4", 114 },
+       { "waitid", 284 },
+       { "waitpid", 7 },
+       { "write", 4 },
+       { "writev", 146 },
+       { NULL, __NR_SCMP_ERROR },
+};
diff --git a/src/arch-i386.h b/src/arch-i386.h
index 09e43c8..cea4e9a 100644
--- a/src/arch-i386.h
+++ b/src/arch-i386.h
@@ -28,6 +28,8 @@
 
 #define i386_arg_count_max             6
 
+extern const struct arch_syscall_def i386_syscall_table[];
+
 int i386_syscall_rewrite(const struct arch_def *arch, int *syscall);
 
 int i386_filter_rewrite(const struct arch_def *arch,
diff --git a/src/arch-x86_64-syscalls.c b/src/arch-x86_64-syscalls.c
new file mode 100644
index 0000000..f6c521d
--- /dev/null
+++ b/src/arch-x86_64-syscalls.c
@@ -0,0 +1,344 @@
+/**
+ * Enhanced Seccomp x86_64 Syscall Table
+ *
+ * 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 <seccomp.h>
+
+#include "arch.h"
+#include "arch-x86_64.h"
+
+/* NOTE: based on Linux 3.4.7 */
+const struct arch_syscall_def x86_64_syscall_table[] = \
+{
+       { "accept", 43 },
+       { "accept4", 288 },
+       { "access", 21 },
+       { "acct", 163 },
+       { "add_key", 248 },
+       { "adjtimex", 159 },
+       { "afs_syscall", 183 },
+       { "alarm", 37 },
+       { "arch_prctl", 158 },
+       { "bind", 49 },
+       { "brk", 12 },
+       { "capget", 125 },
+       { "capset", 126 },
+       { "chdir", 80 },
+       { "chmod", 90 },
+       { "chown", 92 },
+       { "chroot", 161 },
+       { "clock_adjtime", 305 },
+       { "clock_getres", 229 },
+       { "clock_gettime", 228 },
+       { "clock_nanosleep", 230 },
+       { "clock_settime", 227 },
+       { "clone", 56 },
+       { "close", 3 },
+       { "connect", 42 },
+       { "creat", 85 },
+       { "create_module", 174 },
+       { "delete_module", 176 },
+       { "dup", 32 },
+       { "dup2", 33 },
+       { "dup3", 292 },
+       { "epoll_create", 213 },
+       { "epoll_create1", 291 },
+       { "epoll_ctl", 233 },
+       { "epoll_ctl_old", 214 },
+       { "epoll_pwait", 281 },
+       { "epoll_wait", 232 },
+       { "epoll_wait_old", 215 },
+       { "eventfd", 284 },
+       { "eventfd2", 290 },
+       { "execve", 59 },
+       { "exit", 60 },
+       { "exit_group", 231 },
+       { "faccessat", 269 },
+       { "fadvise64", 221 },
+       { "fallocate", 285 },
+       { "fanotify_init", 300 },
+       { "fanotify_mark", 301 },
+       { "fchdir", 81 },
+       { "fchmod", 91 },
+       { "fchmodat", 268 },
+       { "fchown", 93 },
+       { "fchownat", 260 },
+       { "fcntl", 72 },
+       { "fdatasync", 75 },
+       { "fgetxattr", 193 },
+       { "flistxattr", 196 },
+       { "flock", 73 },
+       { "fork", 57 },
+       { "fremovexattr", 199 },
+       { "fsetxattr", 190 },
+       { "fstat", 5 },
+       { "fstatfs", 138 },
+       { "fsync", 74 },
+       { "ftruncate", 77 },
+       { "futex", 202 },
+       { "futimesat", 261 },
+       { "get_kernel_syms", 177 },
+       { "get_mempolicy", 239 },
+       { "get_robust_list", 274 },
+       { "get_thread_area", 211 },
+       { "getcpu", 309 },
+       { "getcwd", 79 },
+       { "getdents", 78 },
+       { "getdents64", 217 },
+       { "getegid", 108 },
+       { "geteuid", 107 },
+       { "getgid", 104 },
+       { "getgroups", 115 },
+       { "getitimer", 36 },
+       { "getpeername", 52 },
+       { "getpgid", 121 },
+       { "getpgrp", 111 },
+       { "getpid", 39 },
+       { "getpmsg", 181 },
+       { "getppid", 110 },
+       { "getpriority", 140 },
+       { "getresgid", 120 },
+       { "getresuid", 118 },
+       { "getrlimit", 97 },
+       { "getrusage", 98 },
+       { "getsid", 124 },
+       { "getsockname", 51 },
+       { "getsockopt", 55 },
+       { "gettid", 186 },
+       { "gettimeofday", 96 },
+       { "getuid", 102 },
+       { "getxattr", 191 },
+       { "init_module", 175 },
+       { "inotify_add_watch", 254 },
+       { "inotify_init", 253 },
+       { "inotify_init1", 294 },
+       { "inotify_rm_watch", 255 },
+       { "io_cancel", 210 },
+       { "io_destroy", 207 },
+       { "io_getevents", 208 },
+       { "io_setup", 206 },
+       { "io_submit", 209 },
+       { "ioctl", 16 },
+       { "ioperm", 173 },
+       { "iopl", 172 },
+       { "ioprio_get", 252 },
+       { "ioprio_set", 251 },
+       { "kcmp", 312 },
+       { "kexec_load", 246 },
+       { "keyctl", 250 },
+       { "kill", 62 },
+       { "lchown", 94 },
+       { "lgetxattr", 192 },
+       { "link", 86 },
+       { "linkat", 265 },
+       { "listen", 50 },
+       { "listxattr", 194 },
+       { "llistxattr", 195 },
+       { "lookup_dcookie", 212 },
+       { "lremovexattr", 198 },
+       { "lseek", 8 },
+       { "lsetxattr", 189 },
+       { "lstat", 6 },
+       { "madvise", 28 },
+       { "mbind", 237 },
+       { "migrate_pages", 256 },
+       { "mincore", 27 },
+       { "mkdir", 83 },
+       { "mkdirat", 258 },
+       { "mknod", 133 },
+       { "mknodat", 259 },
+       { "mlock", 149 },
+       { "mlockall", 151 },
+       { "mmap", 9 },
+       { "modify_ldt", 154 },
+       { "mount", 165 },
+       { "move_pages", 279 },
+       { "mprotect", 10 },
+       { "mq_getsetattr", 245 },
+       { "mq_notify", 244 },
+       { "mq_open", 240 },
+       { "mq_timedreceive", 243 },
+       { "mq_timedsend", 242 },
+       { "mq_unlink", 241 },
+       { "mremap", 25 },
+       { "msgctl", 71 },
+       { "msgget", 68 },
+       { "msgrcv", 70 },
+       { "msgsnd", 69 },
+       { "msync", 26 },
+       { "munlock", 150 },
+       { "munlockall", 152 },
+       { "munmap", 11 },
+       { "name_to_handle_at", 303 },
+       { "nanosleep", 35 },
+       { "newfstatat", 262 },
+       { "nfsservctl", 180 },
+       { "open", 2 },
+       { "open_by_handle_at", 304 },
+       { "openat", 257 },
+       { "pause", 34 },
+       { "perf_event_open", 298 },
+       { "personality", 135 },
+       { "pipe", 22 },
+       { "pipe2", 293 },
+       { "pivot_root", 155 },
+       { "poll", 7 },
+       { "ppoll", 271 },
+       { "prctl", 157 },
+       { "pread64", 17 },
+       { "preadv", 295 },
+       { "prlimit64", 302 },
+       { "process_vm_readv", 310 },
+       { "process_vm_writev", 311 },
+       { "pselect6", 270 },
+       { "ptrace", 101 },
+       { "putpmsg", 182 },
+       { "pwrite64", 18 },
+       { "pwritev", 296 },
+       { "query_module", 178 },
+       { "quotactl", 179 },
+       { "read", 0 },
+       { "readahead", 187 },
+       { "readlink", 89 },
+       { "readlinkat", 267 },
+       { "readv", 19 },
+       { "reboot", 169 },
+       { "recvfrom", 45 },
+       { "recvmmsg", 299 },
+       { "recvmsg", 47 },
+       { "remap_file_pages", 216 },
+       { "removexattr", 197 },
+       { "rename", 82 },
+       { "renameat", 264 },
+       { "request_key", 249 },
+       { "restart_syscall", 219 },
+       { "rmdir", 84 },
+       { "rt_sigaction", 13 },
+       { "rt_sigpending", 127 },
+       { "rt_sigprocmask", 14 },
+       { "rt_sigqueueinfo", 129 },
+       { "rt_sigreturn", 15 },
+       { "rt_sigsuspend", 130 },
+       { "rt_sigtimedwait", 128 },
+       { "rt_tgsigqueueinfo", 297 },
+       { "sched_get_priority_max", 146 },
+       { "sched_get_priority_min", 147 },
+       { "sched_getaffinity", 204 },
+       { "sched_getparam", 143 },
+       { "sched_getscheduler", 145 },
+       { "sched_rr_get_interval", 148 },
+       { "sched_setaffinity", 203 },
+       { "sched_setparam", 142 },
+       { "sched_setscheduler", 144 },
+       { "sched_yield", 24 },
+       { "security", 185 },
+       { "select", 23 },
+       { "semctl", 66 },
+       { "semget", 64 },
+       { "semop", 65 },
+       { "semtimedop", 220 },
+       { "sendfile", 40 },
+       { "sendmmsg", 307 },
+       { "sendmsg", 46 },
+       { "sendto", 44 },
+       { "set_mempolicy", 238 },
+       { "set_robust_list", 273 },
+       { "set_thread_area", 205 },
+       { "set_tid_address", 218 },
+       { "setdomainname", 171 },
+       { "setfsgid", 123 },
+       { "setfsuid", 122 },
+       { "setgid", 106 },
+       { "setgroups", 116 },
+       { "sethostname", 170 },
+       { "setitimer", 38 },
+       { "setns", 308 },
+       { "setpgid", 109 },
+       { "setpriority", 141 },
+       { "setregid", 114 },
+       { "setresgid", 119 },
+       { "setresuid", 117 },
+       { "setreuid", 113 },
+       { "setrlimit", 160 },
+       { "setsid", 112 },
+       { "setsockopt", 54 },
+       { "settimeofday", 164 },
+       { "setuid", 105 },
+       { "setxattr", 188 },
+       { "shmat", 30 },
+       { "shmctl", 31 },
+       { "shmdt", 67 },
+       { "shmget", 29 },
+       { "shutdown", 48 },
+       { "sigaltstack", 131 },
+       { "signalfd", 282 },
+       { "signalfd4", 289 },
+       { "socket", 41 },
+       { "socketpair", 53 },
+       { "splice", 275 },
+       { "stat", 4 },
+       { "statfs", 137 },
+       { "swapoff", 168 },
+       { "swapon", 167 },
+       { "symlink", 88 },
+       { "symlinkat", 266 },
+       { "sync", 162 },
+       { "sync_file_range", 277 },
+       { "syncfs", 306 },
+       { "_sysctl", 156 },
+       { "sysfs", 139 },
+       { "sysinfo", 99 },
+       { "syslog", 103 },
+       { "tee", 276 },
+       { "tgkill", 234 },
+       { "time", 201 },
+       { "timer_create", 222 },
+       { "timer_delete", 226 },
+       { "timer_getoverrun", 225 },
+       { "timer_gettime", 224 },
+       { "timer_settime", 223 },
+       { "timerfd_create", 283 },
+       { "timerfd_gettime", 287 },
+       { "timerfd_settime", 286 },
+       { "times", 100 },
+       { "tkill", 200 },
+       { "truncate", 76 },
+       { "tuxcall", 184 },
+       { "umask", 95 },
+       { "umount2", 166 },
+       { "uname", 63 },
+       { "unlink", 87 },
+       { "unlinkat", 263 },
+       { "unshare", 272 },
+       { "uselib", 134 },
+       { "ustat", 136 },
+       { "utime", 132 },
+       { "utimensat", 280 },
+       { "utimes", 235 },
+       { "vfork", 58 },
+       { "vhangup", 153 },
+       { "vmsplice", 278 },
+       { "vserver", 236 },
+       { "wait4", 61 },
+       { "waitid", 247 },
+       { "write", 1 },
+       { "writev", 20 },
+       { NULL, __NR_SCMP_ERROR },
+};
diff --git a/src/arch-x86_64.h b/src/arch-x86_64.h
index 19ee883..3f13c17 100644
--- a/src/arch-x86_64.h
+++ b/src/arch-x86_64.h
@@ -29,6 +29,8 @@
 
 #define x86_64_arg_count_max           6
 
+extern const struct arch_syscall_def x86_64_syscall_table[];
+
 #define x86_64_arg_offset_lo(x)                (arch_arg_offset(x))
 #define x86_64_arg_offset_hi(x)                (arch_arg_offset(x) + 4)
 
diff --git a/src/arch.c b/src/arch.c
index ff80c53..ddd6dce 100644
--- a/src/arch.c
+++ b/src/arch.c
@@ -21,9 +21,12 @@
 
 #include <errno.h>
 #include <stdlib.h>
+#include <string.h>
 #include <asm/bitsperlong.h>
 #include <linux/audit.h>
 
+#include <seccomp.h>
+
 #include "arch.h"
 #include "arch-i386.h"
 #include "arch-x86_64.h"
@@ -116,6 +119,76 @@ int arch_arg_offset_hi(const struct arch_def *arch, 
unsigned int arg)
 }
 
 /**
+ * Resolve a syscall name to a number
+ * @param arch the architecture definition
+ * @param name the syscall name
+ *
+ * Resolve the given syscall name to the syscall number based on the given
+ * architecture.  Returns the syscall number on success, including negative
+ * pseudo syscall numbers; returns -1 on failure.
+ *
+ */
+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:
+               return __NR_SCMP_ERROR;
+       }
+
+       /* XXX - plenty of room for future improvement here */
+       for (iter = 0; table[iter].name != NULL; iter++) {
+               if (strcmp(name, table[iter].name) == 0)
+                       return table[iter].num;
+       }
+
+       return __NR_SCMP_ERROR;
+}
+
+/**
+ * Resolve a syscall number to a name
+ * @param arch the architecture definition
+ * @param num the syscall number
+ *
+ * Resolve the given syscall number to the syscall name based on the given
+ * architecture.  Returns a pointer to the syscall name string on success,
+ * including pseudo syscall names; returns NULL on failure.
+ *
+ */
+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:
+               return NULL;
+       }
+
+       /* XXX - plenty of room for future improvement here */
+       for (iter = 0; table[iter].num != __NR_SCMP_ERROR; iter++) {
+               if (num == table[iter].num)
+                       return table[iter].name;
+       }
+
+       return NULL;
+}
+
+/**
  * 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 584be69..31a965e 100644
--- a/src/arch.h
+++ b/src/arch.h
@@ -45,9 +45,28 @@ struct arch_def {
        } endian;
 };
 
-/* arch_def for the current process */
+/* arch_def for the current architecture */
 extern const struct arch_def arch_def_native;
 
+/* NOTE: Syscall mappings can be found by running the following commands
+ *      on the specific architecture's include file:
+ *        # gcc -E -dM <file> | grep '__NR_'
+ *      where <file> in many cases is /usr/include/asm/unistd.h, however,
+ *      depending on the architecture you may need to use a different header.
+ *      Further, you can automatically format this list for use as a struct
+ *      initializer with the following command:
+ *        # gcc -E -dM <file> | grep '__NR_' | \
+ *          sed -e 's/#define[ \t]\+__NR_//' | sort | \
+ *          sed -e 's/\([^ \t]\+\)\([ \t]\+\)\([0-9]\+\)/\t{ \"\1\", \3 },/'
+ *      Finally, when creating a table/array of this structure, the final
+ *      sentinel entry should be "{ NULL, __NR_SCMP_ERROR }"; see the existing
+ *      tables as an example.
+ */
+struct arch_syscall_def {
+       const char *name;
+       unsigned int num;
+};
+
 #define DATUM_MAX      ((scmp_datum_t)-1)
 #define D64_LO(x)      ((uint32_t)((uint64_t)(x) & 0x00000000ffffffff))
 #define D64_HI(x)      ((uint32_t)((uint64_t)(x) >> 32))
@@ -67,6 +86,9 @@ int arch_arg_count_max(const struct arch_def *arch);
 int arch_arg_offset_lo(const struct arch_def *arch, unsigned int arg);
 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_rewrite(const struct arch_def *arch, int *syscall);
 
 int arch_filter_rewrite(const struct arch_def *arch,
diff --git a/tests/.gitignore b/tests/.gitignore
index f582b2e..4766982 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -13,3 +13,4 @@
 12-basic-masked-ops
 13-attrs
 14-reset
+15-resolver
diff --git a/tests/15-resolver.c b/tests/15-resolver.c
new file mode 100644
index 0000000..a76c205
--- /dev/null
+++ b/tests/15-resolver.c
@@ -0,0 +1,36 @@
+/**
+ * Seccomp Library test program
+ *
+ * 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 <seccomp.h>
+
+int main(int argc, char *argv[])
+{
+       if (seccomp_syscall_resolve_name("open") != __NR_open)
+               return 1;
+
+       if (seccomp_syscall_resolve_name("socket") != __NR_socket)
+               return 1;
+
+       if (seccomp_syscall_resolve_name("INVALID") != __NR_SCMP_ERROR)
+               return 1;
+
+       return 0;
+}
diff --git a/tests/15-resolver.tests b/tests/15-resolver.tests
new file mode 100644
index 0000000..8a8f1ad
--- /dev/null
+++ b/tests/15-resolver.tests
@@ -0,0 +1,11 @@
+#
+# libseccomp regression test automation data
+#
+# Copyright (c) 2012 Red Hat <[email protected]>
+# Author: Paul Moore <[email protected]>
+#
+
+test type: basic
+
+# Test command
+15-resolver
diff --git a/tests/Makefile b/tests/Makefile
index ca2a40a..bf62769 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -49,7 +49,8 @@ TESTS = 01-allow \
        11-basic-errors \
        12-basic-masked-ops \
        13-attrs \
-       14-reset
+       14-reset \
+       15-resolver
 
 DEPS_OBJS = $(OBJS:%.o=%.d)
 DEPS_TESTS = $(TESTS:%=%.d)


------------------------------------------------------------------------------
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