/** * Enhanced Seccomp x86 Specific Code * * Copyright (c) 2012 Red Hat * Author: Paul Moore */ /* * 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 . */ #include #include #include #include "arch.h" #include "arch-x86.h" /* x86 syscall numbers */ #define __x86_NR_socketcall 102 #define __x86_NR_ipc 117 const struct arch_def arch_def_x86 = { .token = SCMP_ARCH_X86, .token_bpf = AUDIT_ARCH_I386, .size = ARCH_SIZE_32, .endian = ARCH_ENDIAN_LITTLE, }; /** * Rewrite a syscall value to match the architecture * @param arch the architecture definition * @param syscall the syscall number * * Syscalls can vary across different architectures so this function rewrites * the syscall into the correct value for the specified architecture. Returns * zero on success, negative values on failure. * */ int x86_syscall_rewrite(const struct arch_def *arch, int *syscall) { int sys = *syscall; if (sys <= -100 && sys >= -117) *syscall = __x86_NR_socketcall; else if (sys <= -200 && sys >= -211) *syscall = __x86_NR_ipc; else if (sys < 0) return -EDOM; return 0; } /** * Rewrite a filter rule to match the architecture specifics * @param arch the architecture definition * @param strict strict flag * @param syscall the syscall number * @param chain the argument filter chain * * Syscalls can vary across different architectures so this function handles * the necessary seccomp rule rewrites to ensure the right thing is done * regardless of the rule or architecture. If @strict is true then the * function will fail if the entire filter can not be preservered, however, * if @strict is false the function will do a "best effort" rewrite and not * fail. Returns zero on success, negative values on failure. * */ int x86_filter_rewrite(const struct arch_def *arch, bool strict, int *syscall, struct db_api_arg *chain) { int sys = *syscall; unsigned int iter; int arg_max; arg_max = arch_arg_count_max(arch); if (arg_max < 0) return arg_max; if (sys <= -100 && sys >= -117) { for (iter = 0; iter < arg_max; iter++) { if ((chain[iter].valid != 0) && (strict)) return -EINVAL; } chain[0].arg = 0; chain[0].op = SCMP_CMP_EQ; chain[0].mask = DATUM_MAX; chain[0].datum = abs(sys) % 100; chain[0].valid = 1; *syscall = __x86_NR_socketcall; } else if (sys <= -200 && sys >= -211) { for (iter = 0; iter < arg_max; iter++) { if ((chain[iter].valid != 0) && (strict)) return -EINVAL; } chain[0].arg = 0; chain[0].op = SCMP_CMP_EQ; chain[0].mask = DATUM_MAX; chain[0].datum = abs(sys) % 200; chain[0].valid = 1; *syscall = __x86_NR_ipc; } else if (sys < 0) return -EDOM; return 0; }