Skip to content
  • Michal Sojka's avatar
    utrace: Support non-contiguous syscall numbers · 1c48104f
    Michal Sojka authored
    
    
    ARM architecture does not have its system call numbers contiguous. So
    far, utrace ignored the non-contiguous system calls, but it makes it
    difficult to setup seccomp whitelists. This patch adds support for
    these extra out-of-range syscalls.
    
    It extends the generated file syscall_names.h to include a few
    functions. Now, for ARM this file looks like:
    
        #include <asm/unistd.h>
        static const char *__syscall_names[] = {
         [280] = "waitid",
         [148] = "fdatasync",
        ...
         [252] = "epoll_wait",
         [74] = "sethostname",
        };
        static inline const char *syscall_name(unsigned i) {
          if (i < ARRAY_SIZE(__syscall_names))
            return __syscall_names[i];
          switch (i) {
            case 0x0f0001: return "breakpoint";
            case 0x0f0003: return "usr26";
            case 0x0f0004: return "usr32";
            case 0x0f0005: return "set_tls";
            case 0x0f0002: return "cacheflush";
          default: return (void*)0;
          }
        }
        static inline int syscall_index(unsigned i) {
          if (i < ARRAY_SIZE(__syscall_names))
            return i;
          switch (i) {
          case 0x0f0001: return ARRAY_SIZE(__syscall_names) + 0;
          case 0x0f0003: return ARRAY_SIZE(__syscall_names) + 1;
          case 0x0f0004: return ARRAY_SIZE(__syscall_names) + 2;
          case 0x0f0005: return ARRAY_SIZE(__syscall_names) + 3;
          case 0x0f0002: return ARRAY_SIZE(__syscall_names) + 4;
          default: return -1;
          }
        }
        static inline int syscall_index_to_number(unsigned i) {
          if (i < ARRAY_SIZE(__syscall_names))
            return i;
          switch (i) {
          case ARRAY_SIZE(__syscall_names) + 0: return 0x0f0001;
          case ARRAY_SIZE(__syscall_names) + 1: return 0x0f0003;
          case ARRAY_SIZE(__syscall_names) + 2: return 0x0f0004;
          case ARRAY_SIZE(__syscall_names) + 3: return 0x0f0005;
          case ARRAY_SIZE(__syscall_names) + 4: return 0x0f0002;
          default: return -1;
          }
        }
        #define SYSCALL_COUNT (ARRAY_SIZE(__syscall_names) + 5)
    
    For x86, which does not have extra syscalls, the file looks this way:
    
        #include <asm/unistd.h>
        static const char *__syscall_names[] = {
         [247] = "waitid",
         [75] = "fdatasync",
         ...
         [232] = "epoll_wait",
         [170] = "sethostname",
        };
        static inline const char *syscall_name(unsigned i) {
          if (i < ARRAY_SIZE(__syscall_names))
            return __syscall_names[i];
          switch (i) {
          default: return (void*)0;
          }
        }
        static inline int syscall_index(unsigned i) {
          if (i < ARRAY_SIZE(__syscall_names))
            return i;
          switch (i) {
          default: return -1;
          }
        }
        static inline int syscall_index_to_number(unsigned i) {
          if (i < ARRAY_SIZE(__syscall_names))
            return i;
          switch (i) {
          default: return -1;
          }
        }
        #define SYSCALL_COUNT (ARRAY_SIZE(__syscall_names) + 0)
    
    Signed-off-by: default avatarMichal Sojka <sojkam1@fel.cvut.cz>
    1c48104f