Provide syscall name to syscall number resolution.

Signed-off-by: Paul Moore <[email protected]>
---
 tests/.gitignore        |    1 +
 tests/15-resolver.c     |   36 ++++++++++++++++++++++++++++++++++++
 tests/15-resolver.tests |   11 +++++++++++
 tests/Makefile          |    3 ++-
 4 files changed, 50 insertions(+), 1 deletion(-)
 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)


------------------------------------------------------------------------------
Don't let slow site performance ruin your business. Deploy New Relic APM
Deploy New Relic app performance management and know exactly
what is happening inside your Ruby, Python, PHP, Java, and .NET app
Try New Relic at no cost today and get our sweet Data Nerd shirt too!
http://p.sf.net/sfu/newrelic-dev2dev
_______________________________________________
libseccomp-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libseccomp-discuss

Reply via email to