diff --git a/debian/changelog b/debian/changelog index e10a806fe8c08a2961ac1befba9333396d8f63a6..feb78d0a68935120bbb369cc056940f38ddc1b92 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +syscall-intercept (0~git20190129.33ac1e7-0+steamrt1.1) UNRELEASED; urgency=medium + + * New upstream snapshot + * d/patches/i386/*: Add i386-port-rc1 patchset from Gabriel Krisman + Bertazi. This makes syscall-intercept support 32-bit x86 platforms. + * d/control: Build for both amd64 and i386. + * d/watch: Add uscan details to download newer snapshots + * d/p/i386/Enable-PIC-before-descending-into-src-arch-CMAKE_SYSTEM_P.patch: + Fix build failure on x86_64 with older Ubuntu toolchains + + -- Simon McVittie Tue, 28 May 2019 15:40:37 +0100 + syscall-intercept (0~git20180514-0+steamrt1.1) scout; urgency=medium [ Arnaud Rebillout, Simon McVittie ] diff --git a/debian/control b/debian/control index a90ff1c87e1a0a53008d669454c943d73b78e6f1..803770b5e0a96b6fee79e19f2ff86a4babf78491 100644 --- a/debian/control +++ b/debian/control @@ -16,7 +16,7 @@ Vcs-Git: https://gitlab.collabora.com/steam/syscall-intercept.git Package: libsyscall-intercept-dev Section: libdevel -Architecture: amd64 +Architecture: amd64 i386 Depends: libsyscall-intercept0 (=${binary:Version}), ${misc:Depends}, @@ -24,7 +24,7 @@ Description: Development files for libsyscall_intercept Development files for libsyscall_intercept library. Package: libsyscall-intercept0 -Architecture: amd64 +Architecture: amd64 i386 Depends: ${misc:Depends}, ${shlibs:Depends}, diff --git a/debian/patches/Cope-with-missing-AT_SYSINFO_EHDR-in-older-glibc-headers.patch b/debian/patches/Cope-with-missing-AT_SYSINFO_EHDR-in-older-glibc-headers.patch index 4e4f4ada603b9ed57cef16b57c3a403150787db4..7de133a9c243b8540a3f84c1d928736843f2a462 100644 --- a/debian/patches/Cope-with-missing-AT_SYSINFO_EHDR-in-older-glibc-headers.patch +++ b/debian/patches/Cope-with-missing-AT_SYSINFO_EHDR-in-older-glibc-headers.patch @@ -4,23 +4,19 @@ Subject: Cope with missing AT_SYSINFO_EHDR in older glibc headers Signed-off-by: Simon McVittie --- - src/intercept.c | 8 ++++++++ - 1 file changed, 8 insertions(+) + src/intercept.c | 4 ++++ + 1 file changed, 4 insertions(+) diff --git a/src/intercept.c b/src/intercept.c -index a6bc151..a401db9 100644 +index 3386541..d5ba87b 100644 --- a/src/intercept.c +++ b/src/intercept.c -@@ -60,6 +60,14 @@ - #include "disasm_wrapper.h" +@@ -61,6 +61,10 @@ #include "magic_syscalls.h" + #include "arch.h" +#ifndef AT_SYSINFO_EHDR -+#ifdef __x86_64__ +#define AT_SYSINFO_EHDR 33 -+#else -+#error "Please define AT_SYSINFO_EHDR for this platform" -+#endif +#endif + int (*intercept_hook_point)(long syscall_number, diff --git a/debian/patches/Cope-with-missing-FALLOC_FL_PUNCH_HOLE-in-older-kernel-he.patch b/debian/patches/Cope-with-missing-FALLOC_FL_PUNCH_HOLE-in-older-kernel-he.patch index a802d825a1337c75520bff1ce2a3fb1abbc1fe47..eff60c57092800576a5fec8d8356104dab1942bd 100644 --- a/debian/patches/Cope-with-missing-FALLOC_FL_PUNCH_HOLE-in-older-kernel-he.patch +++ b/debian/patches/Cope-with-missing-FALLOC_FL_PUNCH_HOLE-in-older-kernel-he.patch @@ -8,10 +8,10 @@ Signed-off-by: Simon McVittie 1 file changed, 4 insertions(+) diff --git a/test/syscall_format.c b/test/syscall_format.c -index 53d083b..95a26b8 100644 +index 1157774..e79116a 100644 --- a/test/syscall_format.c +++ b/test/syscall_format.c -@@ -121,6 +121,10 @@ +@@ -120,6 +120,10 @@ #include "libsyscall_intercept_hook_point.h" #include "magic_syscalls.h" diff --git a/debian/patches/Cope-with-missing-R_X86_64_RELATIVE64-in-older-glibc-head.patch b/debian/patches/Cope-with-missing-R_X86_64_RELATIVE64-in-older-glibc-head.patch index 0ab08ba22a243e390860bc4a75ef272feed47e43..eecbc64d797ac2d7c2a9c0d54f02606e9442abdc 100644 --- a/debian/patches/Cope-with-missing-R_X86_64_RELATIVE64-in-older-glibc-head.patch +++ b/debian/patches/Cope-with-missing-R_X86_64_RELATIVE64-in-older-glibc-head.patch @@ -4,25 +4,20 @@ Subject: Cope with missing R_X86_64_RELATIVE64 in older glibc headers Signed-off-by: Simon McVittie --- - src/intercept_desc.c | 8 ++++++++ - 1 file changed, 8 insertions(+) + src/arch/x86_64/symbols.c | 4 ++++ + 1 file changed, 4 insertions(+) -diff --git a/src/intercept_desc.c b/src/intercept_desc.c -index 083ccad..7fca4dc 100644 ---- a/src/intercept_desc.c -+++ b/src/intercept_desc.c -@@ -45,6 +45,14 @@ - #include "intercept_util.h" - #include "disasm_wrapper.h" +diff --git a/src/arch/x86_64/symbols.c b/src/arch/x86_64/symbols.c +index ff2fd70..b02124c 100644 +--- a/src/arch/x86_64/symbols.c ++++ b/src/arch/x86_64/symbols.c +@@ -1,5 +1,9 @@ + #include -+#ifdef __x86_64__ +#ifndef R_X86_64_RELATIVE64 +#define R_X86_64_RELATIVE64 38 +#endif -+#else -+#error "Not yet ported to this architecture" -+#endif + /* - * open_orig_file + * sym_get_rel_addr - Find address on a relocation entry. * diff --git a/debian/patches/Cope-with-missing-SYS_finit_module-in-older-glibc-kernel-.patch b/debian/patches/Cope-with-missing-SYS_finit_module-in-older-glibc-kernel-.patch index 45b1d84aaa66afb40cb7679948f800be66fdfd10..8f88d796b7aace72c86cd0e6a51f7b5ec928fd60 100644 --- a/debian/patches/Cope-with-missing-SYS_finit_module-in-older-glibc-kernel-.patch +++ b/debian/patches/Cope-with-missing-SYS_finit_module-in-older-glibc-kernel-.patch @@ -4,10 +4,10 @@ Subject: Cope with missing SYS_finit_module in older glibc/kernel headers Signed-off-by: Simon McVittie --- - examples/syscall_desc.c | 2 ++ - src/syscall_formats.c | 2 ++ - test/syscall_format.c | 2 ++ - test/syscall_format.log.match | 4 ++-- + examples/syscall_desc.c | 2 ++ + src/arch/x86_64/syscall_formats.c | 2 ++ + test/syscall_format.c | 2 ++ + test/syscall_format.log.match | 4 ++-- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/syscall_desc.c b/examples/syscall_desc.c @@ -24,10 +24,10 @@ index cdb31f3..777f2ff 100644 #ifdef SYS_sched_setattr SARGS(sched_setattr, rdec, arg_, arg_, arg_), #endif -diff --git a/src/syscall_formats.c b/src/syscall_formats.c +diff --git a/src/arch/x86_64/syscall_formats.c b/src/arch/x86_64/syscall_formats.c index eba064e..e26e74c 100644 ---- a/src/syscall_formats.c -+++ b/src/syscall_formats.c +--- a/src/arch/x86_64/syscall_formats.c ++++ b/src/arch/x86_64/syscall_formats.c @@ -336,7 +336,9 @@ static const struct syscall_format formats[] = { SARGS(process_vm_readv, rdec, arg_, arg_, arg_, arg_, arg_, arg_), SARGS(process_vm_writev, rdec, arg_, arg_, arg_, arg_, arg_, arg_), @@ -39,10 +39,10 @@ index eba064e..e26e74c 100644 SARGS(sched_setattr, rdec, arg_, arg_, arg_), #endif diff --git a/test/syscall_format.c b/test/syscall_format.c -index 3ce144d..53d083b 100644 +index 8d33be3..1157774 100644 --- a/test/syscall_format.c +++ b/test/syscall_format.c -@@ -634,7 +634,9 @@ main(int argc, char **argv) +@@ -635,7 +635,9 @@ main(int argc, char **argv) ioperm(3, 4, 1); syscall(SYS_init_module, p0, 16, p1); @@ -53,7 +53,7 @@ index 3ce144d..53d083b 100644 quotactl(1, p0, 2, p1); diff --git a/test/syscall_format.log.match b/test/syscall_format.log.match -index 3d8d082..f998718 100644 +index 34fa24b..435f08e 100644 --- a/test/syscall_format.log.match +++ b/test/syscall_format.log.match @@ -572,8 +572,8 @@ $(S) $(XX) -- ioperm(0x3, 0x4, 0x1) = ? diff --git a/debian/patches/Cope-with-missing-SYS_kcmp-in-older-glibc-kernel-headers.patch b/debian/patches/Cope-with-missing-SYS_kcmp-in-older-glibc-kernel-headers.patch index 7b16d252353292987b467ee896ab8fc5146448e3..f3b13f784b6cdc3d19ab0762412d1ad238802bef 100644 --- a/debian/patches/Cope-with-missing-SYS_kcmp-in-older-glibc-kernel-headers.patch +++ b/debian/patches/Cope-with-missing-SYS_kcmp-in-older-glibc-kernel-headers.patch @@ -4,10 +4,10 @@ Subject: Cope with missing SYS_kcmp in older glibc/kernel headers Signed-off-by: Simon McVittie --- - examples/syscall_desc.c | 2 ++ - src/syscall_formats.c | 2 ++ - test/syscall_format.c | 2 ++ - test/syscall_format.log.match | 4 ++-- + examples/syscall_desc.c | 2 ++ + src/arch/x86_64/syscall_formats.c | 2 ++ + test/syscall_format.c | 2 ++ + test/syscall_format.log.match | 4 ++-- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/syscall_desc.c b/examples/syscall_desc.c @@ -24,10 +24,10 @@ index 777f2ff..45e5c1f 100644 #ifdef SYS_finit_module SARGS(finit_module, rdec, arg_fd, arg_, arg_), #endif -diff --git a/src/syscall_formats.c b/src/syscall_formats.c +diff --git a/src/arch/x86_64/syscall_formats.c b/src/arch/x86_64/syscall_formats.c index e26e74c..e41837e 100644 ---- a/src/syscall_formats.c -+++ b/src/syscall_formats.c +--- a/src/arch/x86_64/syscall_formats.c ++++ b/src/arch/x86_64/syscall_formats.c @@ -335,7 +335,9 @@ static const struct syscall_format formats[] = { SARGS(getcpu, rdec, arg_, arg_, arg_), SARGS(process_vm_readv, rdec, arg_, arg_, arg_, arg_, arg_, arg_), @@ -39,10 +39,10 @@ index e26e74c..e41837e 100644 SARGS(finit_module, rdec, arg_fd, arg_, arg_), #endif diff --git a/test/syscall_format.c b/test/syscall_format.c -index 95a26b8..f2a6d17 100644 +index e79116a..7633b5c 100644 --- a/test/syscall_format.c +++ b/test/syscall_format.c -@@ -784,7 +784,9 @@ main(int argc, char **argv) +@@ -785,7 +785,9 @@ main(int argc, char **argv) syscall(SYS_process_vm_readv, 1L, 2L, 3L, 4L, 5L, 6L); syscall(SYS_process_vm_writev, 1L, 2L, 3L, 4L, 5L, 6L); @@ -53,7 +53,7 @@ index 95a26b8..f2a6d17 100644 test_in_progress = false; magic_syscall_stop_log(); diff --git a/test/syscall_format.log.match b/test/syscall_format.log.match -index f998718..dea12f6 100644 +index 435f08e..4195225 100644 --- a/test/syscall_format.log.match +++ b/test/syscall_format.log.match @@ -778,5 +778,5 @@ $(S) $(XX) -- process_vm_readv(0x1, 0x2, 0x3, 0x4, 0x5, 0x6) = ? diff --git a/debian/patches/Cope-with-missing-linux-kexec.h-and-or-KEXEC_PRESERVE_CON.patch b/debian/patches/Cope-with-missing-linux-kexec.h-and-or-KEXEC_PRESERVE_CON.patch index be51851ed8cf1ffefd3d063915f7ce643ff1e864..f19a5ff367e589eccd73d1de8b09806523e73f82 100644 --- a/debian/patches/Cope-with-missing-linux-kexec.h-and-or-KEXEC_PRESERVE_CON.patch +++ b/debian/patches/Cope-with-missing-linux-kexec.h-and-or-KEXEC_PRESERVE_CON.patch @@ -8,7 +8,7 @@ Signed-off-by: Simon McVittie 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/syscall_format.c b/test/syscall_format.c -index f2a6d17..dfcce28 100644 +index 7633b5c..e1f3cc0 100644 --- a/test/syscall_format.c +++ b/test/syscall_format.c @@ -66,7 +66,6 @@ @@ -19,8 +19,8 @@ index f2a6d17..dfcce28 100644 #include #include #include -@@ -118,6 +117,10 @@ - #include +@@ -117,6 +116,10 @@ + #include #include +#ifdef HAS_LINUX_KEXEC_H @@ -30,7 +30,7 @@ index f2a6d17..dfcce28 100644 #include "libsyscall_intercept_hook_point.h" #include "magic_syscalls.h" -@@ -125,6 +128,10 @@ +@@ -124,6 +127,10 @@ #define FALLOC_FL_PUNCH_HOLE 0x02 #endif diff --git a/debian/patches/Disable-some-tests.patch b/debian/patches/Disable-some-tests.patch index 3e195464ab7c55f8a8c13e323f99aec06fbab187..c51ae84cc2c6bcd808188ead7f15af06da519eb7 100644 --- a/debian/patches/Disable-some-tests.patch +++ b/debian/patches/Disable-some-tests.patch @@ -30,10 +30,10 @@ Signed-off-by: Gabriel Krisman Bertazi 1 file changed, 40 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt -index 3525346..6055e1b 100644 +index 7b74fa3..71c9e6c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt -@@ -116,19 +116,6 @@ set(CHECK_LOG_COMMON_ARGS +@@ -117,19 +117,6 @@ set(CHECK_LOG_COMMON_ARGS -DEXPECT_SPURIOUS_SYSCALLS=${EXPECT_SPURIOUS_SYSCALLS} -P ${CMAKE_CURRENT_SOURCE_DIR}/check_log.cmake) @@ -53,7 +53,7 @@ index 3525346..6055e1b 100644 add_library(hook_test_preload_o OBJECT hook_test_preload.c) add_executable(hook_test hook_test.c) -@@ -159,21 +146,6 @@ add_test(NAME "hook_with_static" +@@ -160,21 +147,6 @@ add_test(NAME "hook_with_static" -DMATCH_FILE=${CMAKE_CURRENT_SOURCE_DIR}/libcintercept1.log.match ${CHECK_LOG_COMMON_ARGS}) @@ -75,7 +75,7 @@ index 3525346..6055e1b 100644 add_executable(filter_test filter_test.c) target_link_libraries(filter_test PRIVATE syscall_intercept_shared) -@@ -320,15 +292,3 @@ add_test(NAME "vfork_logging" +@@ -321,15 +293,3 @@ add_test(NAME "vfork_logging" ${CHECK_LOG_COMMON_ARGS}) set_tests_properties("vfork_logging" PROPERTIES PASS_REGULAR_EXPRESSION "in_child_created_using_vfork") diff --git a/debian/patches/Disable-write-protection-before-the-trampoline-gener.patch b/debian/patches/Disable-write-protection-before-the-trampoline-gener.patch index a59c580d58e77976a5f5a1408a4c371ee73fe197..09e05dc4ae2a77c9cfb47e26053efa46077bf0f8 100644 --- a/debian/patches/Disable-write-protection-before-the-trampoline-gener.patch +++ b/debian/patches/Disable-write-protection-before-the-trampoline-gener.patch @@ -17,10 +17,10 @@ Signed-off-by: Simon McVittie 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/patcher.c b/src/patcher.c -index addf319..d8bb9f9 100644 +index 42e3a92..853967a 100644 --- a/src/patcher.c +++ b/src/patcher.c -@@ -674,7 +674,7 @@ mprotect_no_intercept(void *addr, size_t len, int prot, +@@ -703,7 +703,7 @@ mprotect_no_intercept(void *addr, size_t len, int prot, void activate_patches(struct intercept_desc *desc) { @@ -29,7 +29,7 @@ index addf319..d8bb9f9 100644 size_t size; if (desc->count == 0) -@@ -715,10 +715,19 @@ activate_patches(struct intercept_desc *desc) +@@ -750,10 +750,19 @@ activate_patches(struct intercept_desc *desc) create_jump(JMP_OPCODE, patch->dst_jmp_patch, desc->next_trampoline); diff --git a/debian/patches/Reimplement-getauxval-AT_SYSINFO_EHDR-using-proc-self-aux.patch b/debian/patches/Reimplement-getauxval-AT_SYSINFO_EHDR-using-proc-self-aux.patch index 70d193eafd1a830043d57e2364b006088d9bae29..0c653715378db9f44992d38405ffbb3be8c12b4f 100644 --- a/debian/patches/Reimplement-getauxval-AT_SYSINFO_EHDR-using-proc-self-aux.patch +++ b/debian/patches/Reimplement-getauxval-AT_SYSINFO_EHDR-using-proc-self-aux.patch @@ -33,7 +33,7 @@ index aefa950..ef9bfae 100644 + add_definitions(-DHAS_GETAUXVAL) +endif() diff --git a/src/intercept.c b/src/intercept.c -index a401db9..d913d6d 100644 +index d5ba87b..cc3a8c6 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -51,7 +51,11 @@ @@ -48,7 +48,7 @@ index a401db9..d913d6d 100644 #include "intercept.h" #include "intercept_log.h" -@@ -443,6 +447,42 @@ analyze_object(struct dl_phdr_info *info, size_t size, void *data) +@@ -417,6 +421,42 @@ analyze_object(struct dl_phdr_info *info, size_t size, void *data) const char *cmdline; @@ -91,7 +91,7 @@ index a401db9..d913d6d 100644 /* * intercept - This is where the highest level logic of hotpatching * is described. Upon startup, this routine looks for libc, and libpthread. -@@ -463,7 +503,14 @@ intercept(int argc, char **argv) +@@ -437,7 +477,14 @@ intercept(int argc, char **argv) if (!syscall_hook_in_process_allowed()) return; diff --git a/debian/patches/i386/Disable-64bit-specific-build-options-for-32bit-compilatio.patch b/debian/patches/i386/Disable-64bit-specific-build-options-for-32bit-compilatio.patch new file mode 100644 index 0000000000000000000000000000000000000000..4c971f015833144240c9e12ded3cc0bfbf4d6f4d --- /dev/null +++ b/debian/patches/i386/Disable-64bit-specific-build-options-for-32bit-compilatio.patch @@ -0,0 +1,51 @@ +From: Gabriel Krisman Bertazi +Date: Sun, 12 May 2019 00:00:47 -0400 +Subject: Disable 64bit specific build options for 32bit compilation + +Disable 64 specific configuration options, examples and tests. +--- + CMakeLists.txt | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 3c01524..d173d5d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -40,10 +40,18 @@ if(",${CMAKE_SOURCE_DIR}," STREQUAL ",${CMAKE_BINARY_DIR},") + message(FATAL_ERROR "In-source builds are not supported.") + endif() + ++if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "i686") ++ set(DEFAULT_BUILD_TESTS OFF) ++ set(DEFAULT_BUILD_EXAMPLES OFF) ++else() ++ set(DEFAULT_BUILD_TESTS ON) ++ set(DEFAULT_BUILD_EXAMPLES ON) ++endif() ++ + option(PERFORM_STYLE_CHECKS +- "check coding style, license headers (requires perl)" ON) +-option(BUILD_TESTS "build and enable tests" ON) +-option(BUILD_EXAMPLES "build examples" ON) ++ "check coding style, license headers (requires perl)" OFF) ++option(BUILD_TESTS "build and enable tests" ${DEFAULT_BUILD_TESTS}) ++option(BUILD_EXAMPLES "build examples" ${DEFAULT_BUILD_EXAMPLES}) + option(TREAT_WARNINGS_AS_ERRORS + "make the build fail on any warnings during compilation, or linking" ON) + option(EXPECT_SPURIOUS_SYSCALLS +@@ -112,10 +120,14 @@ add_custom_command( + -o syscall_intercept_unscoped.o + DEPENDS syscall_intercept_unscoped) + ++if (NOT ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "i686")) ++ SET(LOCALIZE_HIDDEN "--localize-hidden") ++endif() ++ + add_custom_command( + OUTPUT syscall_intercept_scoped.o + COMMAND ${CMAKE_OBJCOPY} +- --localize-hidden ++ ${LOCALIZE_HIDDEN} + syscall_intercept_unscoped.o + syscall_intercept_scoped.o + DEPENDS syscall_intercept_unscoped.o) diff --git a/debian/patches/i386/Disable-trampoline_table-for-i686.patch b/debian/patches/i386/Disable-trampoline_table-for-i686.patch new file mode 100644 index 0000000000000000000000000000000000000000..25c7f4e7671d941a451ec02cee9c5722a0c68ed3 --- /dev/null +++ b/debian/patches/i386/Disable-trampoline_table-for-i686.patch @@ -0,0 +1,27 @@ +From: Gabriel Krisman Bertazi +Date: Fri, 10 May 2019 22:39:10 -0400 +Subject: Disable trampoline_table for i686 + +--- + src/intercept_desc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/intercept_desc.c b/src/intercept_desc.c +index 5925368..11a59e2 100644 +--- a/src/intercept_desc.c ++++ b/src/intercept_desc.c +@@ -613,10 +613,14 @@ get_min_address(void) + void + allocate_trampoline_table(struct intercept_desc *desc) + { ++#ifdef __x86_64__ + char *e = getenv("INTERCEPT_NO_TRAMPOLINE"); + + /* Use the extra trampoline table by default */ + desc->uses_trampoline_table = (e == NULL) || (e[0] == '0'); ++#else ++ desc->uses_trampoline_table = 0; ++#endif + + if (!desc->uses_trampoline_table) { + desc->trampoline_table = NULL; diff --git a/debian/patches/i386/Enable-PIC-before-descending-into-src-arch-CMAKE_SYSTEM_P.patch b/debian/patches/i386/Enable-PIC-before-descending-into-src-arch-CMAKE_SYSTEM_P.patch new file mode 100644 index 0000000000000000000000000000000000000000..02250fb3678baa6097d0b0c605c2dabe1ea4d77b --- /dev/null +++ b/debian/patches/i386/Enable-PIC-before-descending-into-src-arch-CMAKE_SYSTEM_P.patch @@ -0,0 +1,43 @@ +From: Simon McVittie +Date: Tue, 28 May 2019 18:59:52 +0100 +Subject: Enable PIC before descending into src/arch/${CMAKE_SYSTEM_PROCESSOR} + +We're relying on having set CMAKE_POSITION_INDEPENDENT_CODE to ON +before adding any libraries, but +src/arch/${CMAKE_SYSTEM_PROCESSOR}/CMakeLists.txt adds a library, so +we had better not descend into that subdirectory until after we have +selected PIC. + +Otherwise the x86_64 build will fail with: + + /usr/bin/ld: syscall_intercept_scoped.o: relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC + syscall_intercept_scoped.o: could not read symbols: Bad value + +on systems that do not already default to PIC or PIE. + +Signed-off-by: Simon McVittie +Fixes: 4ea95df6 "Move syscall_formats to arch specific directory" +--- + CMakeLists.txt | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ad091ce..ffad0d3 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -82,13 +82,13 @@ set(SOURCES_C + src/patcher.c + src/magic_syscalls.c) + +-add_subdirectory(src/arch/${CMAKE_SYSTEM_PROCESSOR}) +- + include_directories(include) + link_directories(${capstone_LIBRARY_DIRS}) + + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + ++add_subdirectory(src/arch/${CMAKE_SYSTEM_PROCESSOR}) ++ + # Main object files of the library, the entry point in entry.c + # is only built into the final libraries. This way, testing code + # can use the internal interface of the libraries (linking diff --git a/debian/patches/i386/Fix-casts-for-architectures-with-pointer-smaller-than-64-.patch b/debian/patches/i386/Fix-casts-for-architectures-with-pointer-smaller-than-64-.patch new file mode 100644 index 0000000000000000000000000000000000000000..c2569e698319894a1fb9eef5a6a699030a28497b --- /dev/null +++ b/debian/patches/i386/Fix-casts-for-architectures-with-pointer-smaller-than-64-.patch @@ -0,0 +1,35 @@ +From: Gabriel Krisman Bertazi +Date: Tue, 23 Apr 2019 14:34:41 -0400 +Subject: Fix casts for architectures with pointer smaller than 64 bit + +--- + src/disasm_wrapper.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/disasm_wrapper.c b/src/disasm_wrapper.c +index c8bdc1b..f04f9b5 100644 +--- a/src/disasm_wrapper.c ++++ b/src/disasm_wrapper.c +@@ -190,10 +190,11 @@ check_op(struct intercept_disasm_result *result, cs_x86_op *op, + assert(!result->is_indirect_jump); + result->has_ip_relative_opr = true; + result->is_rel_jump = true; +- result->rip_ref_addr = (void *)op->imm; ++ result->rip_ref_addr = ++ (unsigned char *)((uintptr_t)op->imm); + + result->rip_disp = +- (int32_t)((unsigned char *)op->imm - rip); ++ (int32_t)((uintptr_t)op->imm - (uintptr_t)rip); + } + } + } +@@ -210,7 +211,7 @@ intercept_disasm_next_instruction(struct intercept_disasm_context *context, + struct intercept_disasm_result result = {0, }; + const unsigned char *start = code; + size_t size = (size_t)(context->end - code + 1); +- uint64_t address = (uint64_t)code; ++ uint64_t address = (uintptr_t)code; + + if (!cs_disasm_iter(context->handle, &start, &size, + &address, context->insn)) { diff --git a/debian/patches/i386/Fix-error_code-display-on-error.patch b/debian/patches/i386/Fix-error_code-display-on-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..af9e3661d517315e7de7a7fd394bb01b81347808 --- /dev/null +++ b/debian/patches/i386/Fix-error_code-display-on-error.patch @@ -0,0 +1,21 @@ +From: Gabriel Krisman Bertazi +Date: Tue, 23 Apr 2019 17:51:22 -0400 +Subject: Fix error_code display on error + +--- + src/intercept.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/intercept.c b/src/intercept.c +index b93e513..7624a0c 100644 +--- a/src/intercept.c ++++ b/src/intercept.c +@@ -517,7 +517,7 @@ xabort_errno(int error_code, const char *msg) + + /* not using libc - inline sprintf */ + do { +- *c-- = error_code % 10; ++ *c-- = (error_code % 10) + '0'; + ++len; + error_code /= 10; + } while (error_code != 0); diff --git a/debian/patches/i386/Implement-R_386_RELATIVE-relocation-support.patch b/debian/patches/i386/Implement-R_386_RELATIVE-relocation-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..ccbe468fd644f363b8e267a71a00771b77353f68 --- /dev/null +++ b/debian/patches/i386/Implement-R_386_RELATIVE-relocation-support.patch @@ -0,0 +1,93 @@ +From: Gabriel Krisman Bertazi +Date: Tue, 7 May 2019 16:08:46 -0400 +Subject: Implement R_386_RELATIVE relocation support + +--- + src/arch/i686/CMakeLists.txt | 3 ++- + src/arch/i686/symbols.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 65 insertions(+), 1 deletion(-) + create mode 100644 src/arch/i686/symbols.c + +diff --git a/src/arch/i686/CMakeLists.txt b/src/arch/i686/CMakeLists.txt +index e492860..3360805 100644 +--- a/src/arch/i686/CMakeLists.txt ++++ b/src/arch/i686/CMakeLists.txt +@@ -31,7 +31,8 @@ + + set(SOURCES_ARCH + syscall_formats.c +- intercept_util.c) ++ intercept_util.c ++ symbols.c) + + set(SOURCES_ASM util.S) + +diff --git a/src/arch/i686/symbols.c b/src/arch/i686/symbols.c +new file mode 100644 +index 0000000..e9d9d23 +--- /dev/null ++++ b/src/arch/i686/symbols.c +@@ -0,0 +1,63 @@ ++/* ++ * Copyright 2018, Collabora Ltd. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++ ++#include ++#include ++ ++/* ++ * sym_get_rel_addr - Find address on a relocation entry. ++ * ++ * The constant SHT_REL refers to "Relocation entries with addends" -- see the ++ * elf.h header file. ++ * ++ */ ++ ++#include ++ ++unsigned char * ++sym_get_rel_addr(struct intercept_desc *desc, const void *sym) ++{ ++ const Elf32_Rel *rel = (Elf32_Rel *) sym; ++ uintptr_t offset; ++ ++ switch (ELF32_R_TYPE(rel->r_info)) { ++ case R_386_RELATIVE: ++ offset = *((unsigned int*) (((uintptr_t) desc->base_addr) + rel->r_offset)); ++ ++ debug_dump("jump target: %lx\n", ++ (unsigned long) offset - (unsigned long)desc->base_addr); ++ ++ return (unsigned char *) offset; ++ } ++ return NULL; ++} diff --git a/debian/patches/i386/Make-Elf-parsing-types-generic.patch b/debian/patches/i386/Make-Elf-parsing-types-generic.patch new file mode 100644 index 0000000000000000000000000000000000000000..6d24a8be0a012a53ae25264e0acd7d4d1a0a21a7 --- /dev/null +++ b/debian/patches/i386/Make-Elf-parsing-types-generic.patch @@ -0,0 +1,169 @@ +From: Gabriel Krisman Bertazi +Date: Tue, 23 Apr 2019 13:17:39 -0400 +Subject: Make Elf parsing types generic + +Signed-off-by: Gabriel Krisman Bertazi +--- + src/intercept.c | 4 ++-- + src/intercept.h | 8 ++++---- + src/intercept_desc.c | 34 +++++++++++++++++----------------- + 3 files changed, 23 insertions(+), 23 deletions(-) + +diff --git a/src/intercept.c b/src/intercept.c +index a6bc151..b93e513 100644 +--- a/src/intercept.c ++++ b/src/intercept.c +@@ -283,9 +283,9 @@ get_name_from_proc_maps(uintptr_t addr) + static uintptr_t + get_any_used_vaddr(const struct dl_phdr_info *info) + { +- const Elf64_Phdr *pheaders = info->dlpi_phdr; ++ const ElfW(Phdr) *pheaders = info->dlpi_phdr; + +- for (Elf64_Word i = 0; i < info->dlpi_phnum; ++i) { ++ for (ElfW(Word) i = 0; i < info->dlpi_phnum; ++i) { + if (pheaders[i].p_type == PT_LOAD && pheaders[i].p_memsz != 0) + return info->dlpi_addr + pheaders[i].p_vaddr; + } +diff --git a/src/intercept.h b/src/intercept.h +index 3c40795..fe4ea04 100644 +--- a/src/intercept.h ++++ b/src/intercept.h +@@ -138,8 +138,8 @@ void patch_apply(struct patch_desc *patch); + * file. + */ + struct section_list { +- Elf64_Half count; +- Elf64_Shdr headers[0x10]; ++ ElfW(Half) count; ++ ElfW(Shdr) headers[0x10]; + }; + + struct intercept_desc { +@@ -170,8 +170,8 @@ struct intercept_desc { + * the whereabouts of symbols, whose address in the text + * section. + */ +- Elf64_Half text_section_index; +- Elf64_Shdr sh_text_section; ++ ElfW(Half) text_section_index; ++ ElfW(Shdr) sh_text_section; + + struct section_list symbol_tables; + struct section_list rela_tables; +diff --git a/src/intercept_desc.c b/src/intercept_desc.c +index 083ccad..aeb813f 100644 +--- a/src/intercept_desc.c ++++ b/src/intercept_desc.c +@@ -70,7 +70,7 @@ open_orig_file(const struct intercept_desc *desc) + } + + static void +-add_table_info(struct section_list *list, const Elf64_Shdr *header) ++add_table_info(struct section_list *list, const ElfW(Shdr) *header) + { + size_t max = sizeof(list->headers) / sizeof(list->headers[0]); + +@@ -87,8 +87,8 @@ add_table_info(struct section_list *list, const Elf64_Shdr *header) + * about the corresponding code text. + */ + static void +-add_text_info(struct intercept_desc *desc, const Elf64_Shdr *header, +- Elf64_Half index) ++add_text_info(struct intercept_desc *desc, const ElfW(Shdr) *header, ++ ElfW(Half) index) + { + desc->text_offset = header->sh_offset; + desc->text_start = desc->base_addr + header->sh_addr; +@@ -104,17 +104,17 @@ add_text_info(struct intercept_desc *desc, const Elf64_Shdr *header, + static void + find_sections(struct intercept_desc *desc, int fd) + { +- Elf64_Ehdr elf_header; ++ ElfW(Ehdr) elf_header; + + desc->symbol_tables.count = 0; + desc->rela_tables.count = 0; + + xread(fd, &elf_header, sizeof(elf_header)); + +- Elf64_Shdr sec_headers[elf_header.e_shnum]; ++ ElfW(Shdr) sec_headers[elf_header.e_shnum]; + + xlseek(fd, elf_header.e_shoff, SEEK_SET); +- xread(fd, sec_headers, elf_header.e_shnum * sizeof(Elf64_Shdr)); ++ xread(fd, sec_headers, elf_header.e_shnum * sizeof(ElfW(Shdr))); + + char sec_string_table[sec_headers[elf_header.e_shstrndx].sh_size]; + +@@ -124,8 +124,8 @@ find_sections(struct intercept_desc *desc, int fd) + + bool text_section_found = false; + +- for (Elf64_Half i = 0; i < elf_header.e_shnum; ++i) { +- const Elf64_Shdr *section = &sec_headers[i]; ++ for (ElfW(Half) i = 0; i < elf_header.e_shnum; ++i) { ++ const ElfW(Shdr) *section = &sec_headers[i]; + char *name = sec_string_table + section->sh_name; + + debug_dump("looking at section: \"%s\" type: %ld\n", +@@ -266,7 +266,7 @@ mark_jump(const struct intercept_desc *desc, const unsigned char *addr) + /* + * find_jumps_in_section_syms + * +- * Read the .symtab or .dynsym section, which stores an array of Elf64_Sym ++ * Read the .symtab or .dynsym section, which stores an array of ElfW(Sym) + * structs. Some of these symbols are functions in the .text section, + * thus their entry points are jump destinations. + * +@@ -288,15 +288,15 @@ mark_jump(const struct intercept_desc *desc, const unsigned char *addr) + * The field st_value is offset of the symbol in the object file. + */ + static void +-find_jumps_in_section_syms(struct intercept_desc *desc, Elf64_Shdr *section, ++find_jumps_in_section_syms(struct intercept_desc *desc, ElfW(Shdr) *section, + int fd) + { + assert(section->sh_type == SHT_SYMTAB || + section->sh_type == SHT_DYNSYM); + +- size_t sym_count = section->sh_size / sizeof(Elf64_Sym); ++ size_t sym_count = section->sh_size / sizeof(ElfW(Sym)); + +- Elf64_Sym syms[sym_count]; ++ ElfW(Sym) syms[sym_count]; + + xlseek(fd, section->sh_offset, SEEK_SET); + xread(fd, &syms, section->sh_size); +@@ -339,14 +339,14 @@ find_jumps_in_section_syms(struct intercept_desc *desc, Elf64_Shdr *section, + * + */ + static void +-find_jumps_in_section_rela(struct intercept_desc *desc, Elf64_Shdr *section, ++find_jumps_in_section_rela(struct intercept_desc *desc, ElfW(Shdr) *section, + int fd) + { + assert(section->sh_type == SHT_RELA); + +- size_t sym_count = section->sh_size / sizeof(Elf64_Rela); ++ size_t sym_count = section->sh_size / sizeof(ElfW(Rela)); + +- Elf64_Rela syms[sym_count]; ++ ElfW(Rela) syms[sym_count]; + + xlseek(fd, section->sh_offset, SEEK_SET); + xread(fd, &syms, section->sh_size); +@@ -704,11 +704,11 @@ find_syscalls(struct intercept_desc *desc) + allocate_jump_table(desc); + allocate_nop_table(desc); + +- for (Elf64_Half i = 0; i < desc->symbol_tables.count; ++i) ++ for (ElfW(Half) i = 0; i < desc->symbol_tables.count; ++i) + find_jumps_in_section_syms(desc, + desc->symbol_tables.headers + i, fd); + +- for (Elf64_Half i = 0; i < desc->rela_tables.count; ++i) ++ for (ElfW(Half) i = 0; i < desc->rela_tables.count; ++i) + find_jumps_in_section_rela(desc, + desc->rela_tables.headers + i, fd); + diff --git a/debian/patches/i386/Make-address-calculation-during-relocation-arch-specific.patch b/debian/patches/i386/Make-address-calculation-during-relocation-arch-specific.patch new file mode 100644 index 0000000000000000000000000000000000000000..ea23c4a5349419867a63f685da6e0f2b9c27d2ab --- /dev/null +++ b/debian/patches/i386/Make-address-calculation-during-relocation-arch-specific.patch @@ -0,0 +1,171 @@ +From: Gabriel Krisman Bertazi +Date: Tue, 7 May 2019 16:07:50 -0400 +Subject: Make address calculation during relocation arch specific + +--- + src/arch/x86_64/CMakeLists.txt | 3 ++- + src/arch/x86_64/symbols.c | 26 +++++++++++++++++++ + src/intercept.h | 4 +++ + src/intercept_desc.c | 59 ++++++++++++++---------------------------- + 4 files changed, 52 insertions(+), 40 deletions(-) + create mode 100644 src/arch/x86_64/symbols.c + +diff --git a/src/arch/x86_64/CMakeLists.txt b/src/arch/x86_64/CMakeLists.txt +index 71909c3..771afe2 100644 +--- a/src/arch/x86_64/CMakeLists.txt ++++ b/src/arch/x86_64/CMakeLists.txt +@@ -30,7 +30,8 @@ + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + set(SOURCES_ARCH +- syscall_formats.c) ++ syscall_formats.c ++ symbols.c) + + set(SOURCES_ASM + intercept_template.S +diff --git a/src/arch/x86_64/symbols.c b/src/arch/x86_64/symbols.c +new file mode 100644 +index 0000000..ff2fd70 +--- /dev/null ++++ b/src/arch/x86_64/symbols.c +@@ -0,0 +1,26 @@ ++#include ++ ++/* ++ * sym_get_rel_addr - Find address on a relocation entry. ++ * ++ * The constant SHT_RELA refers to "Relocation entries with addends" -- see the ++ * elf.h header file. ++ * ++ */ ++unsigned char * ++sym_get_rel_addr(struct intercept_desc *desc, const void *sym) ++{ ++ const Elf64_Rela *rela = (Elf64_Rela *) sym; ++ ++ switch (ELF64_R_TYPE(rela->r_info)) { ++ case R_X86_64_RELATIVE: ++ case R_X86_64_RELATIVE64: ++ /* Relocation type: "Adjust by program base" */ ++ ++ debug_dump("jump target: %lx\n", ++ (unsigned long)rela->r_addend); ++ ++ return desc->base_addr + rela->r_addend; ++ } ++ return NULL; ++} +diff --git a/src/intercept.h b/src/intercept.h +index fe4ea04..b8c1dbe 100644 +--- a/src/intercept.h ++++ b/src/intercept.h +@@ -231,4 +231,8 @@ void create_jump(unsigned char opcode, unsigned char *from, void *to); + + const char *cmdline; + ++/* Arch specific symbol handling */ ++unsigned char *sym_get_rel_addr(struct intercept_desc *desc, ++ const void *rel); ++ + #endif +diff --git a/src/intercept_desc.c b/src/intercept_desc.c +index aeb813f..bef77ee 100644 +--- a/src/intercept_desc.c ++++ b/src/intercept_desc.c +@@ -140,6 +140,9 @@ find_sections(struct intercept_desc *desc, int fd) + } else if (section->sh_type == SHT_RELA) { + debug_dump("found relocation table: %s\n", name); + add_table_info(&desc->rela_tables, section); ++ } else if (section->sh_type == SHT_REL) { ++ debug_dump("found relocation table: %s\n", name); ++ add_table_info(&desc->rela_tables, section); + } + } + +@@ -308,8 +311,6 @@ find_jumps_in_section_syms(struct intercept_desc *desc, ElfW(Shdr) *section, + if (syms[i].st_shndx != desc->text_section_index) + continue; /* it is not in the text section */ + +- debug_dump("jump target: %lx\n", +- (unsigned long)syms[i].st_value); + + unsigned char *address = desc->base_addr + syms[i].st_value; + +@@ -322,51 +323,31 @@ find_jumps_in_section_syms(struct intercept_desc *desc, ElfW(Shdr) *section, + } + } + +-/* +- * find_jumps_in_section_rela - look for offsets in relocation entries +- * +- * The constant SHT_RELA refers to "Relocation entries with addends" -- see the +- * elf.h header file. +- * +- * The format of the entries: +- * +- * typedef struct +- * { +- * Elf64_Addr r_offset; Address +- * Elf64_Xword r_info; Relocation type and symbol index +- * Elf64_Sxword r_addend; Addend +- * } Elf64_Rela; +- * +- */ + static void +-find_jumps_in_section_rela(struct intercept_desc *desc, ElfW(Shdr) *section, +- int fd) ++find_jumps_in_section_rel(struct intercept_desc *desc, ElfW(Shdr) *section, ++ int fd) + { +- assert(section->sh_type == SHT_RELA); ++ size_t entry_size; ++ unsigned off; ++ unsigned char *buff; ++ unsigned char *address; + +- size_t sym_count = section->sh_size / sizeof(ElfW(Rela)); ++ assert(section->sh_type == SHT_RELA || ++ section->sh_type == SHT_REL); + +- ElfW(Rela) syms[sym_count]; ++ entry_size = ((section->sh_type == SHT_RELA) ? ++ sizeof(ElfW(Rela)) : sizeof(ElfW(Rel))); ++ buff = xmmap_anon(section->sh_offset); + + xlseek(fd, section->sh_offset, SEEK_SET); +- xread(fd, &syms, section->sh_size); ++ xread(fd, buff, section->sh_size); + +- for (size_t i = 0; i < sym_count; ++i) { +- switch (ELF64_R_TYPE(syms[i].r_info)) { +- case R_X86_64_RELATIVE: +- case R_X86_64_RELATIVE64: +- /* Relocation type: "Adjust by program base" */ +- +- debug_dump("jump target: %lx\n", +- (unsigned long)syms[i].r_addend); ++ for (off = 0; off < section->sh_offset; off += entry_size) { ++ address = sym_get_rel_addr(desc, &buff[off]); + +- unsigned char *address = +- desc->base_addr + syms[i].r_addend; ++ if (address) ++ mark_jump(desc, address); + +- mark_jump(desc, address); +- +- break; +- } + } + } + +@@ -709,7 +690,7 @@ find_syscalls(struct intercept_desc *desc) + desc->symbol_tables.headers + i, fd); + + for (ElfW(Half) i = 0; i < desc->rela_tables.count; ++i) +- find_jumps_in_section_rela(desc, ++ find_jumps_in_section_rel(desc, + desc->rela_tables.headers + i, fd); + + syscall_no_intercept(SYS_close, fd); diff --git a/debian/patches/i386/Make-syscall-context-specific-to-the-architecture.patch b/debian/patches/i386/Make-syscall-context-specific-to-the-architecture.patch new file mode 100644 index 0000000000000000000000000000000000000000..26df89fd004cb4b77dcf9b7057a30cb7287c4a65 --- /dev/null +++ b/debian/patches/i386/Make-syscall-context-specific-to-the-architecture.patch @@ -0,0 +1,300 @@ +From: Gabriel Krisman Bertazi +Date: Sun, 12 May 2019 00:15:26 -0400 +Subject: Make syscall context specific to the architecture + +--- + CMakeLists.txt | 3 ++ + src/arch.h | 6 ++++ + src/arch/x86_64/CMakeLists.txt | 4 ++- + src/arch/x86_64/arch-base.h | 31 ++++++++++++++++++++ + src/arch/x86_64/intercept.c | 58 +++++++++++++++++++++++++++++++++++++ + src/intercept.c | 66 ++++++++++++------------------------------ + 6 files changed, 119 insertions(+), 49 deletions(-) + create mode 100644 src/arch/x86_64/arch-base.h + create mode 100644 src/arch/x86_64/intercept.c + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d173d5d..ad091ce 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -105,6 +105,9 @@ endif() + set_property(TARGET syscall_intercept_base_c + APPEND PROPERTY COMPILE_FLAGS ${capstone_CFLAGS}) + ++include_directories(syscall_intercept_base_c ++ src/arch/${CMAKE_SYSTEM_PROCESSOR}) ++ + add_library(syscall_intercept_unscoped STATIC + $ + $ +diff --git a/src/arch.h b/src/arch.h +index b13a268..0529f85 100644 +--- a/src/arch.h ++++ b/src/arch.h +@@ -34,11 +34,17 @@ + #define INTERCEPT_ARCH_H + + #include ++#include + ++struct syscall_desc; + struct cs_insn; + + bool arch_insn_is_syscall(struct cs_insn *insn); + + unsigned arch_trampoline_entry_size(); + ++void arch_get_syscall_in_context(struct sys_ctx *ctx, ++ struct syscall_desc *sys); ++unsigned long arch_get_syscall_return(struct sys_ctx *context); ++ + #endif /* INTERCEPT_ARCH_H */ +diff --git a/src/arch/x86_64/CMakeLists.txt b/src/arch/x86_64/CMakeLists.txt +index cf2209c..9bdf453 100644 +--- a/src/arch/x86_64/CMakeLists.txt ++++ b/src/arch/x86_64/CMakeLists.txt +@@ -32,7 +32,8 @@ + set(SOURCES_ARCH + syscall_formats.c + symbols.c +- parser.c) ++ parser.c ++ intercept.c) + + set(SOURCES_ASM + intercept_template.S +@@ -41,6 +42,7 @@ set(SOURCES_ASM + + add_library(syscall_intercept_base_arch OBJECT ${SOURCES_ARCH}) + include_directories(syscall_intercept_base_arch ${CMAKE_SOURCE_DIR}/src) ++include_directories(syscall_intercept_base_arch .) + add_library(syscall_intercept_base_asm OBJECT ${SOURCES_ASM}) + + set_property(TARGET syscall_intercept_base_arch +diff --git a/src/arch/x86_64/arch-base.h b/src/arch/x86_64/arch-base.h +new file mode 100644 +index 0000000..28bc0ef +--- /dev/null ++++ b/src/arch/x86_64/arch-base.h +@@ -0,0 +1,31 @@ ++#ifndef _ARCH_SPECIFIC_H ++#define _ARCH_SPECIFIC_H ++ ++/* ++ * Kernel can clobber rcx and r11 while serving a syscall, those are ignored ++ * The layout of this struct depends on the way the assembly wrapper saves ++ * register on the stack. ++ * Note: don't expect the SIMD array to be aligned for efficient use with ++ * AVX instructions. ++ */ ++struct sys_ctx { ++ long rip; ++ long r15; ++ long r14; ++ long r13; ++ long r12; ++ long r10; ++ long r9; ++ long r8; ++ long rsp; ++ long rbp; ++ long rdi; ++ long rsi; ++ long rbx; ++ long rdx; ++ long rax; ++ char padd[0x200 - 0x168]; /* see: stack layout in intercept_wrapper.s */ ++ long SIMD[16][8]; /* 8 SSE, 8 AVX, or 16 AVX512 registers */ ++}; ++ ++#endif +diff --git a/src/arch/x86_64/intercept.c b/src/arch/x86_64/intercept.c +new file mode 100644 +index 0000000..5136bdd +--- /dev/null ++++ b/src/arch/x86_64/intercept.c +@@ -0,0 +1,58 @@ ++/* ++ * Copyright 2018, Intel, Inc. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "arch.h" ++#include "intercept.h" ++ ++/* ++ * get_syscall_in_context -- describe syscall arguments, and syscall number ++ * based on the contents of the relevant registers righ before the syscall ++ * is meant to be executed. On Linux, all syscall arguments are passed to ++ * a syscall in registers. ++ */ ++void ++arch_get_syscall_in_context(struct sys_ctx *ctx, ++ struct syscall_desc *sys) ++{ ++ sys->nr = (int)ctx->rax; /* ignore higher 32 bits */ ++ sys->args[0] = ctx->rdi; ++ sys->args[1] = ctx->rsi; ++ sys->args[2] = ctx->rdx; ++ sys->args[3] = ctx->r10; ++ sys->args[4] = ctx->r8; ++ sys->args[5] = ctx->r9; ++} ++ ++unsigned long arch_get_syscall_return(struct sys_ctx *ctx) ++{ ++ return ctx->rax; ++} +diff --git a/src/intercept.c b/src/intercept.c +index 7624a0c..3386541 100644 +--- a/src/intercept.c ++++ b/src/intercept.c +@@ -59,6 +59,7 @@ + #include "libsyscall_intercept_hook_point.h" + #include "disasm_wrapper.h" + #include "magic_syscalls.h" ++#include "arch.h" + + int (*intercept_hook_point)(long syscall_number, + long arg0, long arg1, +@@ -103,32 +104,9 @@ static void log_header(void); + + void __attribute__((noreturn)) xlongjmp(long rip, long rsp, long rax); + +-/* +- * Kernel can clobber rcx and r11 while serving a syscall, those are ignored +- * The layout of this struct depends on the way the assembly wrapper saves +- * register on the stack. +- * Note: don't expect the SIMD array to be aligned for efficient use with +- * AVX instructions. +- */ + struct context { + struct patch_desc *patch_desc; +- long rip; +- long r15; +- long r14; +- long r13; +- long r12; +- long r10; +- long r9; +- long r8; +- long rsp; +- long rbp; +- long rdi; +- long rsi; +- long rbx; +- long rdx; +- long rax; +- char padd[0x200 - 0x168]; /* see: stack layout in intercept_wrapper.s */ +- long SIMD[16][8]; /* 8 SSE, 8 AVX, or 16 AVX512 registers */ ++ struct sys_ctx sys_ctx; + }; + + struct wrapper_ret { +@@ -552,23 +530,6 @@ xabort_on_syserror(long syscall_result, const char *msg) + xabort_errno(syscall_error_code(syscall_result), msg); + } + +-/* +- * get_syscall_in_context -- describe syscall arguments, and syscall number +- * based on the contents of the relevant registers righ before the syscall +- * is meant to be executed. On Linux, all syscall arguments are passed to +- * a syscall in registers. +- */ +-static void +-get_syscall_in_context(struct context *context, struct syscall_desc *sys) +-{ +- sys->nr = (int)context->rax; /* ignore higher 32 bits */ +- sys->args[0] = context->rdi; +- sys->args[1] = context->rsi; +- sys->args[2] = context->rdx; +- sys->args[3] = context->r10; +- sys->args[4] = context->r8; +- sys->args[5] = context->r9; +-} + + /* + * intercept_routine(...) +@@ -608,8 +569,9 @@ intercept_routine(struct context *context) + int forward_to_kernel = true; + struct syscall_desc desc; + struct patch_desc *patch = context->patch_desc; ++ struct sys_ctx *sctx = &context->sys_ctx; + +- get_syscall_in_context(context, &desc); ++ arch_get_syscall_in_context(sctx, &desc); + + if (handle_magic_syscalls(&desc, &result) == 0) + return (struct wrapper_ret){.rax = result, .rdx = 1 }; +@@ -628,7 +590,10 @@ intercept_routine(struct context *context) + + if (desc.nr == SYS_vfork || desc.nr == SYS_rt_sigreturn) { + /* can't handle these syscalls the normal way */ +- return (struct wrapper_ret){.rax = context->rax, .rdx = 0 }; ++ return (struct wrapper_ret) { ++ .rax = arch_get_syscall_return(sctx), ++ .rdx = 0 ++ }; + } + + if (forward_to_kernel) { +@@ -645,8 +610,10 @@ intercept_routine(struct context *context) + * it on the new child threads stack, then returns to libc. + */ + if (desc.nr == SYS_clone && desc.args[1] != 0) +- return (struct wrapper_ret){ +- .rax = context->rax, .rdx = 2 }; ++ return (struct wrapper_ret) { ++ .rax = arch_get_syscall_return(sctx), ++ .rdx = 2 ++ }; + else + result = syscall_no_intercept(desc.nr, + desc.args[0], +@@ -670,13 +637,16 @@ intercept_routine(struct context *context) + struct wrapper_ret + intercept_routine_post_clone(struct context *context) + { +- if (context->rax == 0) { ++ unsigned long rax= arch_get_syscall_return(&context->sys_ctx); ++ if (rax == 0) { + if (intercept_hook_point_clone_child != NULL) + intercept_hook_point_clone_child(); + } else { + if (intercept_hook_point_clone_parent != NULL) +- intercept_hook_point_clone_parent(context->rax); ++ intercept_hook_point_clone_parent(rax); + } + +- return (struct wrapper_ret){.rax = context->rax, .rdx = 1 }; ++ return (struct wrapper_ret){ ++ .rax = rax, ++ .rdx = 1 }; + } diff --git a/debian/patches/i386/Make-syscall-detection-arch-specific.patch b/debian/patches/i386/Make-syscall-detection-arch-specific.patch new file mode 100644 index 0000000000000000000000000000000000000000..8c7e6390f22442fc6c083c869e1558fb5dbcb51f --- /dev/null +++ b/debian/patches/i386/Make-syscall-detection-arch-specific.patch @@ -0,0 +1,149 @@ +From: Gabriel Krisman Bertazi +Date: Wed, 8 May 2019 13:24:18 -0400 +Subject: Make syscall detection arch specific + +--- + src/arch.h | 42 ++++++++++++++++++++++++++++++++++++++++++ + src/arch/x86_64/CMakeLists.txt | 6 +++++- + src/arch/x86_64/parser.c | 40 ++++++++++++++++++++++++++++++++++++++++ + src/disasm_wrapper.c | 3 ++- + 4 files changed, 89 insertions(+), 2 deletions(-) + create mode 100644 src/arch.h + create mode 100644 src/arch/x86_64/parser.c + +diff --git a/src/arch.h b/src/arch.h +new file mode 100644 +index 0000000..2dbd006 +--- /dev/null ++++ b/src/arch.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright 2018, Collabora Ltd. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef INTERCEPT_ARCH_H ++#define INTERCEPT_ARCH_H ++ ++#include ++ ++struct cs_insn; ++ ++bool arch_insn_is_syscall(struct cs_insn *insn); ++ ++#endif /* INTERCEPT_ARCH_H */ +diff --git a/src/arch/x86_64/CMakeLists.txt b/src/arch/x86_64/CMakeLists.txt +index 771afe2..cf2209c 100644 +--- a/src/arch/x86_64/CMakeLists.txt ++++ b/src/arch/x86_64/CMakeLists.txt +@@ -31,7 +31,8 @@ + + set(SOURCES_ARCH + syscall_formats.c +- symbols.c) ++ symbols.c ++ parser.c) + + set(SOURCES_ASM + intercept_template.S +@@ -41,3 +42,6 @@ set(SOURCES_ASM + add_library(syscall_intercept_base_arch OBJECT ${SOURCES_ARCH}) + include_directories(syscall_intercept_base_arch ${CMAKE_SOURCE_DIR}/src) + add_library(syscall_intercept_base_asm OBJECT ${SOURCES_ASM}) ++ ++set_property(TARGET syscall_intercept_base_arch ++ APPEND PROPERTY COMPILE_FLAGS ${capstone_CFLAGS}) +diff --git a/src/arch/x86_64/parser.c b/src/arch/x86_64/parser.c +new file mode 100644 +index 0000000..428653a +--- /dev/null ++++ b/src/arch/x86_64/parser.c +@@ -0,0 +1,40 @@ ++/* ++ * Copyright 2018, Intel, Inc. ++ * Copyright 2018, Collabora Ltd. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "capstone_wrapper.h" ++#include "arch.h" ++ ++bool arch_insn_is_syscall(struct cs_insn *insn) ++{ ++ return (insn->id == X86_INS_SYSCALL); ++} +diff --git a/src/disasm_wrapper.c b/src/disasm_wrapper.c +index f04f9b5..87ea980 100644 +--- a/src/disasm_wrapper.c ++++ b/src/disasm_wrapper.c +@@ -39,6 +39,7 @@ + */ + + #include "intercept.h" ++#include "arch.h" + #include "intercept_util.h" + #include "disasm_wrapper.h" + +@@ -224,7 +225,7 @@ intercept_disasm_next_instruction(struct intercept_disasm_context *context, + + assert(result.length != 0); + +- result.is_syscall = (context->insn->id == X86_INS_SYSCALL); ++ result.is_syscall = arch_insn_is_syscall(context->insn); + result.is_call = (context->insn->id == X86_INS_CALL); + result.is_ret = (context->insn->id == X86_INS_RET); + result.is_rel_jump = false; diff --git a/debian/patches/i386/Move-assembly-files-to-arch-specific-directory.patch b/debian/patches/i386/Move-assembly-files-to-arch-specific-directory.patch new file mode 100644 index 0000000000000000000000000000000000000000..1969eb2a632fffeafd4230a80ce8b1f02b78e9ed --- /dev/null +++ b/debian/patches/i386/Move-assembly-files-to-arch-specific-directory.patch @@ -0,0 +1,927 @@ +From: Gabriel Krisman Bertazi +Date: Tue, 23 Apr 2019 15:34:44 -0400 +Subject: Move assembly files to arch specific directory + +--- + CMakeLists.txt | 6 - + src/arch/x86_64/CMakeLists.txt | 6 + + src/arch/x86_64/intercept_template.S | 116 ++++++++++++++++++ + src/arch/x86_64/intercept_wrapper.S | 232 +++++++++++++++++++++++++++++++++++ + src/arch/x86_64/util.S | 67 ++++++++++ + src/intercept_template.S | 116 ------------------ + src/intercept_wrapper.S | 232 ----------------------------------- + src/util.S | 67 ---------- + 8 files changed, 421 insertions(+), 421 deletions(-) + create mode 100644 src/arch/x86_64/intercept_template.S + create mode 100644 src/arch/x86_64/intercept_wrapper.S + create mode 100644 src/arch/x86_64/util.S + delete mode 100644 src/intercept_template.S + delete mode 100644 src/intercept_wrapper.S + delete mode 100644 src/util.S + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index fdd2b08..3c01524 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -74,11 +74,6 @@ set(SOURCES_C + src/patcher.c + src/magic_syscalls.c) + +-set(SOURCES_ASM +- src/intercept_template.S +- src/util.S +- src/intercept_wrapper.S) +- + add_subdirectory(src/arch/${CMAKE_SYSTEM_PROCESSOR}) + + include_directories(include) +@@ -92,7 +87,6 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) + # with syscall_intercept_base instead of the actual lib ), without + # the library trying to hotpatch libc every time. + add_library(syscall_intercept_base_c OBJECT ${SOURCES_C}) +-add_library(syscall_intercept_base_asm OBJECT ${SOURCES_ASM}) + add_library(syscall_intercept_base_clf OBJECT src/cmdline_filter.c) + + if(HAS_NOUNUSEDARG) +diff --git a/src/arch/x86_64/CMakeLists.txt b/src/arch/x86_64/CMakeLists.txt +index 665152a..71909c3 100644 +--- a/src/arch/x86_64/CMakeLists.txt ++++ b/src/arch/x86_64/CMakeLists.txt +@@ -32,5 +32,11 @@ + set(SOURCES_ARCH + syscall_formats.c) + ++set(SOURCES_ASM ++ intercept_template.S ++ util.S ++ intercept_wrapper.S) ++ + add_library(syscall_intercept_base_arch OBJECT ${SOURCES_ARCH}) + include_directories(syscall_intercept_base_arch ${CMAKE_SOURCE_DIR}/src) ++add_library(syscall_intercept_base_asm OBJECT ${SOURCES_ASM}) +diff --git a/src/arch/x86_64/intercept_template.S b/src/arch/x86_64/intercept_template.S +new file mode 100644 +index 0000000..70f60d8 +--- /dev/null ++++ b/src/arch/x86_64/intercept_template.S +@@ -0,0 +1,116 @@ ++/* ++ * Copyright 2016-2017, Intel Corporation ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * intercept_template.s -- see asm_wrapper.md ++ */ ++ ++.global intercept_asm_wrapper_tmpl; ++.hidden intercept_asm_wrapper_tmpl; ++.global intercept_asm_wrapper_patch_desc_addr; ++.hidden intercept_asm_wrapper_patch_desc_addr; ++.global intercept_asm_wrapper_wrapper_level1_addr; ++.hidden intercept_asm_wrapper_wrapper_level1_addr; ++.global intercept_asm_wrapper_tmpl_end; ++.hidden intercept_asm_wrapper_tmpl_end; ++ ++.text ++ ++/* ++ * Locals on the stack: ++ * 0(%rsp) the original value of %rsp, in the code around the syscall ++ * 8(%rsp) the pointer to the struct patch_desc instance ++ * ++ * The %rcx register controls which C function to call in intercept.c: ++ * ++ * if %rcx == 0 then call intercept_routine ++ * if %rcx == 1 then intercept_routine_post_clone ++ * ++ * This value in %rcx is passed to the function intercep_wrapper. ++ * ++ * ++ * Note: the subq instruction allocating stack for locals must not ++ * ruin the stack alignment. It must round up the number of bytes ++ * needed for locals. ++ */ ++intercept_asm_wrapper_tmpl: ++ movq $0x0, %rcx /* choose intercept_routine */ ++ ++0: movq %rsp, %r11 /* remember original rsp */ ++ subq $0x80, %rsp /* avoid the red zone */ ++ andq $-16, %rsp /* align the stack */ ++ subq $0x20, %rsp /* allocate stack for some locals */ ++ movq %r11, (%rsp) /* orignal rsp on stack */ ++intercept_asm_wrapper_patch_desc_addr: ++ movabsq $0x000000000000, %r11 ++ movq %r11, 0x8 (%rsp) /* patch_desc pointer on stack */ ++intercept_asm_wrapper_wrapper_level1_addr: ++ movabsq $0x000000000000, %r11 ++ callq *%r11 /* call intercept_wrapper */ ++ movq (%rsp), %rsp /* restore original rsp */ ++ /* ++ * The intercept_wrapper function did restore all registers to their ++ * original state, except for rax, rsp, rip, and r11. ++ * ++ * If r11 is zero, rax contains a syscall number, and that syscall ++ * is executed here. ++ * If r11 is 1, rax contains the return value of the hooked syscall. ++ * If r11 is 2, a clone syscall is executed here. ++ */ ++ cmp $0x0, %r11 ++ je 2f ++ cmp $0x1, %r11 ++ je 3f ++ cmp $0x2, %r11 ++ je 1f ++ ++ hlt /* r11 value is invalid? */ ++ ++1: ++ /* execute the clone syscall in its original context */ ++ syscall ++ movq $0x1, %rcx /* choose intercept_routine_post_clone */ ++ /* ++ * Now goto 0, and call the C function named ++ * intercept_routine_post_clone both in the parent thread, adn the ++ * child thread. ++ */ ++ jmp 0b ++ ++2: ++ syscall ++3: ++intercept_asm_wrapper_tmpl_end: ++ /* ++ * This template must be appended here with a ++ * jump back to the intercepted code. ++ */ +diff --git a/src/arch/x86_64/intercept_wrapper.S b/src/arch/x86_64/intercept_wrapper.S +new file mode 100644 +index 0000000..7291a17 +--- /dev/null ++++ b/src/arch/x86_64/intercept_wrapper.S +@@ -0,0 +1,232 @@ ++/* ++ * Copyright 2016-2017, Intel Corporation ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * intercept_wrapper.s -- see asm_wrapper.md ++ */ ++ ++/* the function in this file */ ++.global intercept_wrapper ++.hidden intercept_wrapper ++.type intercept_wrapper, @function ++ ++/* the C function in intercept.c */ ++.global intercept_routine ++.hidden intercept_routine ++.type intercept_routine, @function ++ ++/* the other C function in intercept.c, called right after cloning a thread */ ++.global intercept_routine_post_clone ++.hidden intercept_routine_post_clone ++.type intercept_routine_post_clone, @function ++ ++/* The boolean indicating whether YMM registers must saved */ ++.global intercept_routine_must_save_ymm ++.hidden intercept_routine_must_save_ymm ++ ++.text ++ ++/* ++ * Local stack layout: ++ * ++ * 0x448(%rsp) -- return address, to the generated asm wrapper ++ * Arguments recieved on stack: ++ * 0x450(%rsp) -- original value of rsp ++ * 0x458(%rsp) -- pointer to a struct patch_desc instance ++ * Locals on stack: ++ * 0xe8(%rsp) - 0x168(%rsp) -- saved GPRs ++ * 0x200(%rsp) - 0x400(%rsp) -- saved SIMD registers ++ * ++ * A pointer to these saved register is passed to intercept_routine, so the ++ * layout of `struct context` must match this part of the stack layout. ++ * ++ * Other arguments: ++ * %rcx -- which C function to call ++ */ ++intercept_wrapper: ++ .cfi_startproc ++ ++ /* ++ * Stack size used locally: 0x448 bytes. ++ * ++ * This size assumes the stack pointer was correctly aligned before ++ * executing the call instruction calling this function. The return ++ * address pushed to the stack uses 8 bytes. This gives the equation: ++ * ++ * new_rsp = original_rsp - 8 - 0x448 == original_rsp - 0x450 ++ * The number 0x450 is a multiple of 16, so the stack is still correctly ++ * aligned. It is very easy to forget about this when making changes to this ++ * code. ++ */ ++ subq $0x448, %rsp ++ .cfi_def_cfa_offset 0x0 ++ ++ /* Save all GPRs on the stack */ ++ movq %rax, 0x160 (%rsp) ++ .cfi_offset 0, 0x160 ++ movq %rdx, 0x158 (%rsp) ++ .cfi_offset 1, 0x158 ++ /* rcx is already clobbered, no reason to save it */ ++ movq %rbx, 0x150 (%rsp) ++ .cfi_offset 3, 0x150 ++ movq %rsi, 0x148 (%rsp) ++ .cfi_offset 4, 0x148 ++ movq %rdi, 0x140 (%rsp) ++ .cfi_offset 5, 0x140 ++ movq %rbp, 0x138 (%rsp) ++ .cfi_offset 6, 0x138 ++ movq 0x450 (%rsp), %r11 /* fetch original value of rsp */ ++ movq %r11, 0x130 (%rsp) ++ .cfi_offset 7, 0x130 ++ movq %r8, 0x128 (%rsp) ++ .cfi_offset 8, 0x128 ++ movq %r9, 0x120 (%rsp) ++ .cfi_offset 9, 0x120 ++ movq %r10, 0x118 (%rsp) ++ .cfi_offset 10, -0x118 ++ /* r11 is already clobbered, no reason to save it */ ++ movq %r12, 0x110 (%rsp) ++ .cfi_offset 12, 0x110 ++ movq %r13, 0x108 (%rsp) ++ .cfi_offset 13, 0x108 ++ movq %r14, 0x100 (%rsp) ++ .cfi_offset 14, 0x100 ++ movq %r15, 0xf8 (%rsp) ++ .cfi_offset 15, 0xf8 ++ movq 0x458 (%rsp), %r11 /* fetch pointer to patch_desc */ ++ movq %r11, 0xe8 (%rsp) ++ movq (%r11), %r11 /* fetch original value of rip */ ++ movq %r11, 0xf0 (%rsp) ++ .cfi_offset 16, 0xf0 ++ ++ movb intercept_routine_must_save_ymm (%rip), %al ++ test %al, %al ++ jz 0f ++ ++ /* ++ * Save the YMM registers. ++ * Use vmovups. Must not use vmovaps, since 32 byte alignment is not ++ * guaranteed. ++ * One could just align the stack for this, but that would need ++ * more explanation in comments in other places about why overaligned ++ * stack is needed. ++ */ ++ vmovups %ymm0, 0x3c0 (%rsp) ++ vmovups %ymm1, 0x380 (%rsp) ++ vmovups %ymm2, 0x340 (%rsp) ++ vmovups %ymm3, 0x300 (%rsp) ++ vmovups %ymm4, 0x2c0 (%rsp) ++ vmovups %ymm5, 0x280 (%rsp) ++ vmovups %ymm6, 0x240 (%rsp) ++ vmovups %ymm7, 0x200 (%rsp) ++ jmp 1f ++ ++0: ++ /* Save the XMM registers. */ ++ movaps %xmm0, 0x3c0 (%rsp) ++ movaps %xmm1, 0x380 (%rsp) ++ movaps %xmm2, 0x340 (%rsp) ++ movaps %xmm3, 0x300 (%rsp) ++ movaps %xmm4, 0x2c0 (%rsp) ++ movaps %xmm5, 0x280 (%rsp) ++ movaps %xmm6, 0x240 (%rsp) ++ movaps %xmm7, 0x200 (%rsp) ++ ++1: ++ /* argument passed to intercept_routine */ ++ leaq 0xe8 (%rsp), %rdi ++ ++ cmp $0x1, %rcx /* which function should be called? */ ++ je 0f ++ call intercept_routine ++ jmp 1f ++0: call intercept_routine_post_clone ++1: ++ /* ++ * At this point, the return value of the C ++ * function (a struct wrapper_ret instance) is in rax, rdx. ++ * ++ * This function doesn't use these values for anything, just ++ * forwards them to the higher level wrapper function, generated ++ * from the template. ++ */ ++ ++ movq %rdx, %r11 ++ /* ++ * At this point, the return values of this asm function ++ * are in rax, r11. ++ * ++ * Restore the other registers, and return. ++ */ ++ ++ movb intercept_routine_must_save_ymm (%rip), %dl ++ test %dl, %dl ++ jz 0f ++ ++ vmovups 0x3c0 (%rsp), %ymm0 ++ vmovups 0x380 (%rsp), %ymm1 ++ vmovups 0x340 (%rsp), %ymm2 ++ vmovups 0x300 (%rsp), %ymm3 ++ vmovups 0x2c0 (%rsp), %ymm4 ++ vmovups 0x280 (%rsp), %ymm5 ++ vmovups 0x240 (%rsp), %ymm6 ++ vmovups 0x200 (%rsp), %ymm7 ++ jmp 1f ++ ++0: ++ movaps 0x3c0 (%rsp), %xmm0 ++ movaps 0x380 (%rsp), %xmm1 ++ movaps 0x340 (%rsp), %xmm2 ++ movaps 0x300 (%rsp), %xmm3 ++ movaps 0x2c0 (%rsp), %xmm4 ++ movaps 0x280 (%rsp), %xmm5 ++ movaps 0x240 (%rsp), %xmm6 ++ movaps 0x200 (%rsp), %xmm7 ++ ++1: ++ movq 0x158 (%rsp), %rdx ++ movq 0x150 (%rsp), %rbx ++ movq 0x148 (%rsp), %rsi ++ movq 0x140 (%rsp), %rdi ++ movq 0x138 (%rsp), %rbp ++ movq 0x128 (%rsp), %r8 ++ movq 0x120 (%rsp), %r9 ++ movq 0x118 (%rsp), %r10 ++ movq 0x110 (%rsp), %r12 ++ movq 0x108 (%rsp), %r13 ++ movq 0x100 (%rsp), %r14 ++ movq 0xf8 (%rsp), %r15 ++ ++ addq $0x448, %rsp ++ ++ retq ++ .cfi_endproc +diff --git a/src/arch/x86_64/util.S b/src/arch/x86_64/util.S +new file mode 100644 +index 0000000..4b375c8 +--- /dev/null ++++ b/src/arch/x86_64/util.S +@@ -0,0 +1,67 @@ ++/* ++ * Copyright 2016-2017, Intel Corporation ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++.global has_ymm_registers; ++.hidden has_ymm_registers; ++.type has_ymm_registers, @function ++ ++.global syscall_no_intercept; ++.type syscall_no_intercept, @function ++ ++.text ++ ++has_ymm_registers: ++ .cfi_startproc ++ pushq %rbx ++ movq $0x1, %rax ++ cpuid ++ movq %rcx, %rax ++ shrq $28, %rax ++ andq $1, %rax ++ popq %rbx ++ retq ++ .cfi_endproc ++ ++.size has_ymm_registers, .-has_ymm_registers ++ ++syscall_no_intercept: ++ movq %rdi, %rax /* convert from linux ABI calling */ ++ movq %rsi, %rdi /* convention to syscall calling convention */ ++ movq %rdx, %rsi ++ movq %rcx, %rdx ++ movq %r8, %r10 ++ movq %r9, %r8 ++ movq 8(%rsp), %r9 ++ syscall ++ ret ++ ++.size syscall_no_intercept, .-syscall_no_intercept +diff --git a/src/intercept_template.S b/src/intercept_template.S +deleted file mode 100644 +index 70f60d8..0000000 +--- a/src/intercept_template.S ++++ /dev/null +@@ -1,116 +0,0 @@ +-/* +- * Copyright 2016-2017, Intel Corporation +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in +- * the documentation and/or other materials provided with the +- * distribution. +- * +- * * Neither the name of the copyright holder nor the names of its +- * contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- */ +- +-/* +- * intercept_template.s -- see asm_wrapper.md +- */ +- +-.global intercept_asm_wrapper_tmpl; +-.hidden intercept_asm_wrapper_tmpl; +-.global intercept_asm_wrapper_patch_desc_addr; +-.hidden intercept_asm_wrapper_patch_desc_addr; +-.global intercept_asm_wrapper_wrapper_level1_addr; +-.hidden intercept_asm_wrapper_wrapper_level1_addr; +-.global intercept_asm_wrapper_tmpl_end; +-.hidden intercept_asm_wrapper_tmpl_end; +- +-.text +- +-/* +- * Locals on the stack: +- * 0(%rsp) the original value of %rsp, in the code around the syscall +- * 8(%rsp) the pointer to the struct patch_desc instance +- * +- * The %rcx register controls which C function to call in intercept.c: +- * +- * if %rcx == 0 then call intercept_routine +- * if %rcx == 1 then intercept_routine_post_clone +- * +- * This value in %rcx is passed to the function intercep_wrapper. +- * +- * +- * Note: the subq instruction allocating stack for locals must not +- * ruin the stack alignment. It must round up the number of bytes +- * needed for locals. +- */ +-intercept_asm_wrapper_tmpl: +- movq $0x0, %rcx /* choose intercept_routine */ +- +-0: movq %rsp, %r11 /* remember original rsp */ +- subq $0x80, %rsp /* avoid the red zone */ +- andq $-16, %rsp /* align the stack */ +- subq $0x20, %rsp /* allocate stack for some locals */ +- movq %r11, (%rsp) /* orignal rsp on stack */ +-intercept_asm_wrapper_patch_desc_addr: +- movabsq $0x000000000000, %r11 +- movq %r11, 0x8 (%rsp) /* patch_desc pointer on stack */ +-intercept_asm_wrapper_wrapper_level1_addr: +- movabsq $0x000000000000, %r11 +- callq *%r11 /* call intercept_wrapper */ +- movq (%rsp), %rsp /* restore original rsp */ +- /* +- * The intercept_wrapper function did restore all registers to their +- * original state, except for rax, rsp, rip, and r11. +- * +- * If r11 is zero, rax contains a syscall number, and that syscall +- * is executed here. +- * If r11 is 1, rax contains the return value of the hooked syscall. +- * If r11 is 2, a clone syscall is executed here. +- */ +- cmp $0x0, %r11 +- je 2f +- cmp $0x1, %r11 +- je 3f +- cmp $0x2, %r11 +- je 1f +- +- hlt /* r11 value is invalid? */ +- +-1: +- /* execute the clone syscall in its original context */ +- syscall +- movq $0x1, %rcx /* choose intercept_routine_post_clone */ +- /* +- * Now goto 0, and call the C function named +- * intercept_routine_post_clone both in the parent thread, adn the +- * child thread. +- */ +- jmp 0b +- +-2: +- syscall +-3: +-intercept_asm_wrapper_tmpl_end: +- /* +- * This template must be appended here with a +- * jump back to the intercepted code. +- */ +diff --git a/src/intercept_wrapper.S b/src/intercept_wrapper.S +deleted file mode 100644 +index 7291a17..0000000 +--- a/src/intercept_wrapper.S ++++ /dev/null +@@ -1,232 +0,0 @@ +-/* +- * Copyright 2016-2017, Intel Corporation +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in +- * the documentation and/or other materials provided with the +- * distribution. +- * +- * * Neither the name of the copyright holder nor the names of its +- * contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- */ +- +-/* +- * intercept_wrapper.s -- see asm_wrapper.md +- */ +- +-/* the function in this file */ +-.global intercept_wrapper +-.hidden intercept_wrapper +-.type intercept_wrapper, @function +- +-/* the C function in intercept.c */ +-.global intercept_routine +-.hidden intercept_routine +-.type intercept_routine, @function +- +-/* the other C function in intercept.c, called right after cloning a thread */ +-.global intercept_routine_post_clone +-.hidden intercept_routine_post_clone +-.type intercept_routine_post_clone, @function +- +-/* The boolean indicating whether YMM registers must saved */ +-.global intercept_routine_must_save_ymm +-.hidden intercept_routine_must_save_ymm +- +-.text +- +-/* +- * Local stack layout: +- * +- * 0x448(%rsp) -- return address, to the generated asm wrapper +- * Arguments recieved on stack: +- * 0x450(%rsp) -- original value of rsp +- * 0x458(%rsp) -- pointer to a struct patch_desc instance +- * Locals on stack: +- * 0xe8(%rsp) - 0x168(%rsp) -- saved GPRs +- * 0x200(%rsp) - 0x400(%rsp) -- saved SIMD registers +- * +- * A pointer to these saved register is passed to intercept_routine, so the +- * layout of `struct context` must match this part of the stack layout. +- * +- * Other arguments: +- * %rcx -- which C function to call +- */ +-intercept_wrapper: +- .cfi_startproc +- +- /* +- * Stack size used locally: 0x448 bytes. +- * +- * This size assumes the stack pointer was correctly aligned before +- * executing the call instruction calling this function. The return +- * address pushed to the stack uses 8 bytes. This gives the equation: +- * +- * new_rsp = original_rsp - 8 - 0x448 == original_rsp - 0x450 +- * The number 0x450 is a multiple of 16, so the stack is still correctly +- * aligned. It is very easy to forget about this when making changes to this +- * code. +- */ +- subq $0x448, %rsp +- .cfi_def_cfa_offset 0x0 +- +- /* Save all GPRs on the stack */ +- movq %rax, 0x160 (%rsp) +- .cfi_offset 0, 0x160 +- movq %rdx, 0x158 (%rsp) +- .cfi_offset 1, 0x158 +- /* rcx is already clobbered, no reason to save it */ +- movq %rbx, 0x150 (%rsp) +- .cfi_offset 3, 0x150 +- movq %rsi, 0x148 (%rsp) +- .cfi_offset 4, 0x148 +- movq %rdi, 0x140 (%rsp) +- .cfi_offset 5, 0x140 +- movq %rbp, 0x138 (%rsp) +- .cfi_offset 6, 0x138 +- movq 0x450 (%rsp), %r11 /* fetch original value of rsp */ +- movq %r11, 0x130 (%rsp) +- .cfi_offset 7, 0x130 +- movq %r8, 0x128 (%rsp) +- .cfi_offset 8, 0x128 +- movq %r9, 0x120 (%rsp) +- .cfi_offset 9, 0x120 +- movq %r10, 0x118 (%rsp) +- .cfi_offset 10, -0x118 +- /* r11 is already clobbered, no reason to save it */ +- movq %r12, 0x110 (%rsp) +- .cfi_offset 12, 0x110 +- movq %r13, 0x108 (%rsp) +- .cfi_offset 13, 0x108 +- movq %r14, 0x100 (%rsp) +- .cfi_offset 14, 0x100 +- movq %r15, 0xf8 (%rsp) +- .cfi_offset 15, 0xf8 +- movq 0x458 (%rsp), %r11 /* fetch pointer to patch_desc */ +- movq %r11, 0xe8 (%rsp) +- movq (%r11), %r11 /* fetch original value of rip */ +- movq %r11, 0xf0 (%rsp) +- .cfi_offset 16, 0xf0 +- +- movb intercept_routine_must_save_ymm (%rip), %al +- test %al, %al +- jz 0f +- +- /* +- * Save the YMM registers. +- * Use vmovups. Must not use vmovaps, since 32 byte alignment is not +- * guaranteed. +- * One could just align the stack for this, but that would need +- * more explanation in comments in other places about why overaligned +- * stack is needed. +- */ +- vmovups %ymm0, 0x3c0 (%rsp) +- vmovups %ymm1, 0x380 (%rsp) +- vmovups %ymm2, 0x340 (%rsp) +- vmovups %ymm3, 0x300 (%rsp) +- vmovups %ymm4, 0x2c0 (%rsp) +- vmovups %ymm5, 0x280 (%rsp) +- vmovups %ymm6, 0x240 (%rsp) +- vmovups %ymm7, 0x200 (%rsp) +- jmp 1f +- +-0: +- /* Save the XMM registers. */ +- movaps %xmm0, 0x3c0 (%rsp) +- movaps %xmm1, 0x380 (%rsp) +- movaps %xmm2, 0x340 (%rsp) +- movaps %xmm3, 0x300 (%rsp) +- movaps %xmm4, 0x2c0 (%rsp) +- movaps %xmm5, 0x280 (%rsp) +- movaps %xmm6, 0x240 (%rsp) +- movaps %xmm7, 0x200 (%rsp) +- +-1: +- /* argument passed to intercept_routine */ +- leaq 0xe8 (%rsp), %rdi +- +- cmp $0x1, %rcx /* which function should be called? */ +- je 0f +- call intercept_routine +- jmp 1f +-0: call intercept_routine_post_clone +-1: +- /* +- * At this point, the return value of the C +- * function (a struct wrapper_ret instance) is in rax, rdx. +- * +- * This function doesn't use these values for anything, just +- * forwards them to the higher level wrapper function, generated +- * from the template. +- */ +- +- movq %rdx, %r11 +- /* +- * At this point, the return values of this asm function +- * are in rax, r11. +- * +- * Restore the other registers, and return. +- */ +- +- movb intercept_routine_must_save_ymm (%rip), %dl +- test %dl, %dl +- jz 0f +- +- vmovups 0x3c0 (%rsp), %ymm0 +- vmovups 0x380 (%rsp), %ymm1 +- vmovups 0x340 (%rsp), %ymm2 +- vmovups 0x300 (%rsp), %ymm3 +- vmovups 0x2c0 (%rsp), %ymm4 +- vmovups 0x280 (%rsp), %ymm5 +- vmovups 0x240 (%rsp), %ymm6 +- vmovups 0x200 (%rsp), %ymm7 +- jmp 1f +- +-0: +- movaps 0x3c0 (%rsp), %xmm0 +- movaps 0x380 (%rsp), %xmm1 +- movaps 0x340 (%rsp), %xmm2 +- movaps 0x300 (%rsp), %xmm3 +- movaps 0x2c0 (%rsp), %xmm4 +- movaps 0x280 (%rsp), %xmm5 +- movaps 0x240 (%rsp), %xmm6 +- movaps 0x200 (%rsp), %xmm7 +- +-1: +- movq 0x158 (%rsp), %rdx +- movq 0x150 (%rsp), %rbx +- movq 0x148 (%rsp), %rsi +- movq 0x140 (%rsp), %rdi +- movq 0x138 (%rsp), %rbp +- movq 0x128 (%rsp), %r8 +- movq 0x120 (%rsp), %r9 +- movq 0x118 (%rsp), %r10 +- movq 0x110 (%rsp), %r12 +- movq 0x108 (%rsp), %r13 +- movq 0x100 (%rsp), %r14 +- movq 0xf8 (%rsp), %r15 +- +- addq $0x448, %rsp +- +- retq +- .cfi_endproc +diff --git a/src/util.S b/src/util.S +deleted file mode 100644 +index 4b375c8..0000000 +--- a/src/util.S ++++ /dev/null +@@ -1,67 +0,0 @@ +-/* +- * Copyright 2016-2017, Intel Corporation +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in +- * the documentation and/or other materials provided with the +- * distribution. +- * +- * * Neither the name of the copyright holder nor the names of its +- * contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- */ +- +-.global has_ymm_registers; +-.hidden has_ymm_registers; +-.type has_ymm_registers, @function +- +-.global syscall_no_intercept; +-.type syscall_no_intercept, @function +- +-.text +- +-has_ymm_registers: +- .cfi_startproc +- pushq %rbx +- movq $0x1, %rax +- cpuid +- movq %rcx, %rax +- shrq $28, %rax +- andq $1, %rax +- popq %rbx +- retq +- .cfi_endproc +- +-.size has_ymm_registers, .-has_ymm_registers +- +-syscall_no_intercept: +- movq %rdi, %rax /* convert from linux ABI calling */ +- movq %rsi, %rdi /* convention to syscall calling convention */ +- movq %rdx, %rsi +- movq %rcx, %rdx +- movq %r8, %r10 +- movq %r9, %r8 +- movq 8(%rsp), %r9 +- syscall +- ret +- +-.size syscall_no_intercept, .-syscall_no_intercept diff --git a/debian/patches/i386/Move-syscall_formats-to-arch-specific-directory.patch b/debian/patches/i386/Move-syscall_formats-to-arch-specific-directory.patch new file mode 100644 index 0000000000000000000000000000000000000000..41a1f6b0a2b1d8e82b0c4da4fd2426f75b000663 --- /dev/null +++ b/debian/patches/i386/Move-syscall_formats-to-arch-specific-directory.patch @@ -0,0 +1,1036 @@ +From: Gabriel Krisman Bertazi +Date: Tue, 23 Apr 2019 15:18:20 -0400 +Subject: Move syscall_formats to arch specific directory + +--- + CMakeLists.txt | 5 +- + src/arch/x86_64/CMakeLists.txt | 36 +++ + src/arch/x86_64/syscall_formats.c | 463 ++++++++++++++++++++++++++++++++++++++ + src/syscall_formats.c | 463 -------------------------------------- + test/CMakeLists.txt | 1 + + 5 files changed, 503 insertions(+), 465 deletions(-) + create mode 100644 src/arch/x86_64/CMakeLists.txt + create mode 100644 src/arch/x86_64/syscall_formats.c + delete mode 100644 src/syscall_formats.c + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 123a39a..fdd2b08 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -72,14 +72,14 @@ set(SOURCES_C + src/intercept_log.c + src/intercept_util.c + src/patcher.c +- src/magic_syscalls.c +- src/syscall_formats.c) ++ src/magic_syscalls.c) + + set(SOURCES_ASM + src/intercept_template.S + src/util.S + src/intercept_wrapper.S) + ++add_subdirectory(src/arch/${CMAKE_SYSTEM_PROCESSOR}) + + include_directories(include) + link_directories(${capstone_LIBRARY_DIRS}) +@@ -106,6 +106,7 @@ set_property(TARGET syscall_intercept_base_c + add_library(syscall_intercept_unscoped STATIC + $ + $ ++ $ + $) + + set(syscall_intercept_unscoped_a $) +diff --git a/src/arch/x86_64/CMakeLists.txt b/src/arch/x86_64/CMakeLists.txt +new file mode 100644 +index 0000000..665152a +--- /dev/null ++++ b/src/arch/x86_64/CMakeLists.txt +@@ -0,0 +1,36 @@ ++# ++# Copyright 2019, Collabora, ltd. ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions ++# are met: ++# ++# * Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# ++# * Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in ++# the documentation and/or other materials provided with the ++# distribution. ++# ++# * Neither the name of the copyright holder nor the names of its ++# contributors may be used to endorse or promote products derived ++# from this software without specific prior written permission. ++# ++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++set(SOURCES_ARCH ++ syscall_formats.c) ++ ++add_library(syscall_intercept_base_arch OBJECT ${SOURCES_ARCH}) ++include_directories(syscall_intercept_base_arch ${CMAKE_SOURCE_DIR}/src) +diff --git a/src/arch/x86_64/syscall_formats.c b/src/arch/x86_64/syscall_formats.c +new file mode 100644 +index 0000000..eba064e +--- /dev/null ++++ b/src/arch/x86_64/syscall_formats.c +@@ -0,0 +1,463 @@ ++/* ++ * Copyright 2017, Intel Corporation ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "syscall_formats.h" ++#include "intercept_util.h" ++ ++#include ++#include ++ ++#define SARGS(name, r, ...) [SYS_##name] = {#name, r, {__VA_ARGS__}} ++ ++/* Linux syscalls on X86_64 */ ++/* BEGIN CSTYLED */ ++static const struct syscall_format formats[] = { ++ SARGS(read, rdec, arg_fd, arg_buf_out, arg_dec), ++ SARGS(write, rdec, arg_fd, arg_buf_in, arg_dec), ++ SARGS(open, rdec, arg_cstr, arg_open_flags), ++ SARGS(close, rdec, arg_fd), ++ SARGS(stat, rdec, arg_cstr, arg_pointer), ++ SARGS(fstat, rdec, arg_fd, arg_pointer), ++ SARGS(lstat, rdec, arg_cstr, arg_pointer), ++ SARGS(poll, rdec, arg_pointer, arg_, arg_), ++ SARGS(lseek, rdec, arg_fd, arg_dec, arg_seek_whence), ++ SARGS(mmap, rpointer, arg_pointer, arg_, arg_, arg_, arg_fd, arg_), ++ SARGS(mprotect, rdec, arg_pointer, arg_, arg_), ++ SARGS(munmap, rdec, arg_pointer, arg_), ++ SARGS(brk, rdec, arg_dec), ++ SARGS(rt_sigaction, rdec, arg_dec32, arg_pointer, arg_pointer, arg_dec), ++ SARGS(rt_sigprocmask, rdec, arg_, arg_pointer, arg_pointer, arg_dec), ++ SARGS(rt_sigreturn, rnoreturn, arg_none), ++ SARGS(ioctl, rdec, arg_fd, arg_, arg_pointer), ++ SARGS(pread64, rdec, arg_fd, arg_buf_out, arg_dec, arg_dec), ++ SARGS(pwrite64, rdec, arg_fd, arg_buf_in, arg_dec, arg_dec), ++ SARGS(readv, rdec, arg_fd, arg_pointer, arg_dec), ++ SARGS(writev, rdec, arg_fd, arg_pointer, arg_dec), ++ SARGS(access, rdec, arg_cstr, arg_access_mode), ++ SARGS(pipe, rdec, arg_2fds), ++ SARGS(select, rdec, arg_dec32, arg_pointer, arg_pointer, arg_pointer, arg_pointer), ++ SARGS(sched_yield, rdec, arg_none), ++ SARGS(mremap, rpointer, arg_pointer, arg_dec, arg_dec, arg_dec32, arg_), ++ SARGS(msync, rdec, arg_pointer, arg_dec, arg_dec32), ++ SARGS(mincore, rdec, arg_pointer, arg_dec, arg_pointer), ++ SARGS(madvise, rdec, arg_pointer, arg_dec, arg_dec32), ++ SARGS(shmget, rdec, arg_, arg_, arg_), ++ SARGS(shmat, rhex, arg_, arg_, arg_), ++ SARGS(shmctl, rdec, arg_, arg_, arg_), ++ SARGS(dup, rdec, arg_fd), ++ SARGS(dup2, rdec, arg_fd, arg_fd), ++ SARGS(pause, rdec, arg_none), ++ SARGS(nanosleep, rdec, arg_, arg_), ++ SARGS(getitimer, rdec, arg_, arg_), ++ SARGS(alarm, rdec, arg_), ++ SARGS(setitimer, rdec, arg_, arg_, arg_), ++ SARGS(getpid, rdec, arg_none), ++ SARGS(sendfile, rdec, arg_fd, arg_fd, arg_, arg_), ++ SARGS(socket, rdec, arg_, arg_, arg_), ++ SARGS(connect, rdec, arg_fd, arg_, arg_), ++ SARGS(accept, rdec, arg_fd, arg_, arg_), ++ SARGS(sendto, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(recvfrom, rdec, arg_fd, arg_, arg_, arg_, arg_, arg_), ++ SARGS(sendmsg, rdec, arg_fd, arg_, arg_), ++ SARGS(recvmsg, rdec, arg_fd, arg_, arg_), ++ SARGS(shutdown, rdec, arg_fd, arg_), ++ SARGS(bind, rdec, arg_fd, arg_, arg_), ++ SARGS(listen, rdec, arg_fd, arg_), ++ SARGS(getsockname, rdec, arg_fd, arg_, arg_), ++ SARGS(getpeername, rdec, arg_fd, arg_, arg_), ++ SARGS(socketpair, rdec, arg_, arg_, arg_, arg_), ++ SARGS(setsockopt, rdec, arg_fd, arg_, arg_, arg_, arg_), ++ SARGS(getsockopt, rdec, arg_fd, arg_, arg_, arg_, arg_), ++ SARGS(clone, rdec, arg_clone_flags, arg_pointer, arg_pointer, arg_pointer, arg_), ++ SARGS(fork, rdec, arg_none), ++ SARGS(vfork, rdec, arg_none), ++ SARGS(execve, rdec, arg_, arg_, arg_), ++ SARGS(exit, rnoreturn, arg_), ++ SARGS(wait4, rdec, arg_dec, arg_, arg_, arg_), ++ SARGS(kill, rdec, arg_, arg_), ++ SARGS(uname, rdec, arg_), ++ SARGS(semget, rdec, arg_, arg_, arg_), ++ SARGS(semop, rdec, arg_, arg_, arg_), ++ SARGS(semctl, rdec, arg_, arg_, arg_, arg_, arg_, arg_), ++ SARGS(shmdt, rdec, arg_), ++ SARGS(msgget, rdec, arg_, arg_), ++ SARGS(msgsnd, rdec, arg_, arg_, arg_, arg_), ++ SARGS(msgrcv, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(msgctl, rdec, arg_, arg_, arg_), ++ SARGS(fcntl, rdec, arg_fd, arg_fcntl_cmd, arg_), ++ SARGS(flock, rdec, arg_fd, arg_), ++ SARGS(fsync, rdec, arg_fd), ++ SARGS(fdatasync, rdec, arg_fd), ++ SARGS(truncate, rdec, arg_cstr, arg_), ++ SARGS(ftruncate, rdec, arg_fd, arg_), ++ SARGS(getdents, rdec, arg_fd, arg_, arg_), ++ SARGS(getcwd, rdec, arg_, arg_), ++ SARGS(chdir, rdec, arg_cstr), ++ SARGS(fchdir, rdec, arg_fd), ++ SARGS(rename, rdec, arg_cstr, arg_cstr), ++ SARGS(mkdir, rdec, arg_cstr, arg_oct_mode), ++ SARGS(rmdir, rdec, arg_cstr), ++ SARGS(creat, rdec, arg_cstr, arg_oct_mode), ++ SARGS(link, rdec, arg_cstr, arg_cstr), ++ SARGS(unlink, rdec, arg_cstr), ++ SARGS(symlink, rdec, arg_cstr, arg_cstr), ++ SARGS(readlink, rdec, arg_cstr, arg_buf_out, arg_dec), ++ SARGS(chmod, rdec, arg_cstr, arg_oct_mode), ++ SARGS(fchmod, rdec, arg_fd, arg_oct_mode), ++ SARGS(chown, rdec, arg_cstr, arg_, arg_), ++ SARGS(fchown, rdec, arg_fd, arg_, arg_), ++ SARGS(lchown, rdec, arg_cstr, arg_, arg_), ++ SARGS(umask, rmode, arg_oct_mode), ++ SARGS(gettimeofday, rdec, arg_, arg_), ++ SARGS(getrlimit, rdec, arg_, arg_), ++ SARGS(getrusage, rdec, arg_, arg_), ++ SARGS(sysinfo, rdec, arg_, arg_), ++ SARGS(times, rdec, arg_), ++ SARGS(ptrace, rhex, arg_, arg_, arg_, arg_), ++ SARGS(getuid, rdec, arg_none), ++ SARGS(syslog, rdec, arg_, arg_, arg_), ++ SARGS(getgid, rdec, arg_none), ++ SARGS(setuid, rdec, arg_), ++ SARGS(setgid, rdec, arg_), ++ SARGS(geteuid, rdec, arg_none), ++ SARGS(getegid, rdec, arg_none), ++ SARGS(setpgid, rdec, arg_none), ++ SARGS(getpgrp, rdec, arg_none), ++ SARGS(setsid, rdec, arg_none), ++ SARGS(setreuid, rdec, arg_, arg_), ++ SARGS(setregid, rdec, arg_, arg_), ++ SARGS(getgroups, rdec, arg_, arg_), ++ SARGS(setgroups, rdec, arg_, arg_), ++ SARGS(setresuid, rdec, arg_, arg_, arg_), ++ SARGS(getresuid, rdec, arg_, arg_, arg_), ++ SARGS(setresgid, rdec, arg_, arg_, arg_), ++ SARGS(getresgid, rdec, arg_, arg_, arg_), ++ SARGS(getpgid, rdec, arg_), ++ SARGS(setfsuid, rdec, arg_), ++ SARGS(setfsgid, rdec, arg_), ++ SARGS(getsid, rdec, arg_), ++ SARGS(capget, rdec, arg_, arg_), ++ SARGS(capset, rdec, arg_, arg_), ++ SARGS(rt_sigpending, rdec, arg_), ++ SARGS(rt_sigtimedwait, rdec, arg_, arg_, arg_, arg_), ++ SARGS(rt_sigqueueinfo, rdec, arg_, arg_, arg_), ++ SARGS(rt_sigsuspend, rdec, arg_, arg_), ++ SARGS(sigaltstack, rdec, arg_, arg_), ++ SARGS(utime, rdec, arg_cstr, arg_), ++ SARGS(mknod, rdec, arg_cstr, arg_, arg_), ++ SARGS(uselib, rdec, arg_cstr), ++ SARGS(personality, rdec, arg_), ++ SARGS(ustat, rdec, arg_, arg_), ++ SARGS(statfs, rdec, arg_cstr, arg_), ++ SARGS(fstatfs, rdec, arg_fd, arg_), ++ SARGS(sysfs, rdec, arg_, arg_, arg_), ++ SARGS(getpriority, rdec, arg_, arg_), ++ SARGS(setpriority, rdec, arg_, arg_, arg_), ++ SARGS(sched_setparam, rdec, arg_, arg_), ++ SARGS(sched_getparam, rdec, arg_, arg_), ++ SARGS(sched_setscheduler, rdec, arg_, arg_, arg_), ++ SARGS(sched_getscheduler, rdec, arg_), ++ SARGS(sched_get_priority_max, rdec, arg_), ++ SARGS(sched_get_priority_min, rdec, arg_), ++ SARGS(sched_rr_get_interval, rdec, arg_, arg_), ++ SARGS(mlock, rdec, arg_, arg_), ++ SARGS(munlock, rdec, arg_, arg_), ++ SARGS(mlockall, rdec, arg_), ++ SARGS(munlockall, rdec, arg_none), ++ SARGS(vhangup, rdec, arg_none), ++ SARGS(modify_ldt, rdec, arg_, arg_, arg_), ++ SARGS(pivot_root, rdec, arg_cstr, arg_), ++ SARGS(_sysctl, rdec, arg_), ++ SARGS(prctl, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(arch_prctl, rdec, arg_, arg_, arg_), ++ SARGS(adjtimex, rdec, arg_), ++ SARGS(setrlimit, rdec, arg_, arg_), ++ SARGS(chroot, rdec, arg_cstr), ++ SARGS(sync, rdec, arg_none), ++ SARGS(acct, rdec, arg_cstr), ++ SARGS(settimeofday, rdec, arg_, arg_), ++ SARGS(mount, rdec, arg_cstr, arg_cstr, arg_, arg_, arg_), ++ SARGS(umount2, rdec, arg_cstr, arg_), ++ SARGS(swapon, rdec, arg_cstr, arg_), ++ SARGS(swapoff, rdec, arg_cstr), ++ SARGS(reboot, rdec, arg_, arg_, arg_, arg_), ++ SARGS(sethostname, rdec, arg_, arg_), ++ SARGS(setdomainname, rdec, arg_, arg_), ++ SARGS(iopl, rdec, arg_), ++ SARGS(ioperm, rdec, arg_, arg_, arg_), ++ SARGS(gettid, rdec, arg_none), ++ SARGS(readahead, rdec, arg_fd, arg_dec, arg_dec), ++ SARGS(setxattr, rdec, arg_cstr, arg_cstr, arg_buf_in, arg_dec, arg_), ++ SARGS(lsetxattr, rdec, arg_cstr, arg_cstr, arg_buf_in, arg_dec, arg_), ++ SARGS(fsetxattr, rdec, arg_fd, arg_cstr, arg_buf_in, arg_dec, arg_), ++ SARGS(getxattr, rdec, arg_cstr, arg_cstr, arg_dec, arg_), ++ SARGS(lgetxattr, rdec, arg_cstr, arg_cstr, arg_dec, arg_), ++ SARGS(fgetxattr, rdec, arg_fd, arg_cstr, arg_dec, arg_), ++ SARGS(listxattr, rdec, arg_cstr, arg_pointer, arg_dec), ++ SARGS(llistxattr, rdec, arg_cstr, arg_pointer, arg_dec), ++ SARGS(flistxattr, rdec, arg_fd, arg_pointer, arg_dec), ++ SARGS(removexattr, rdec, arg_cstr, arg_cstr), ++ SARGS(lremovexattr, rdec, arg_cstr, arg_cstr), ++ SARGS(fremovexattr, rdec, arg_fd, arg_cstr), ++ SARGS(tkill, rdec, arg_, arg_), ++ SARGS(time, rdec, arg_), ++ SARGS(futex, rdec, arg_, arg_, arg_, arg_, arg_, arg_), ++ SARGS(sched_setaffinity, rdec, arg_, arg_, arg_), ++ SARGS(sched_getaffinity, rdec, arg_, arg_, arg_), ++ SARGS(set_thread_area, rdec, arg_), ++ SARGS(io_setup, rdec, arg_, arg_), ++ SARGS(io_destroy, rdec, arg_), ++ SARGS(io_getevents, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(io_submit, rdec, arg_, arg_, arg_), ++ SARGS(io_cancel, rdec, arg_, arg_, arg_), ++ SARGS(get_thread_area, rdec, arg_), ++ SARGS(lookup_dcookie, rdec, arg_, arg_, arg_), ++ SARGS(epoll_create, rdec, arg_), ++ SARGS(getdents64, rdec, arg_fd, arg_, arg_), ++ SARGS(set_tid_address, rdec, arg_), ++ SARGS(semtimedop, rdec, arg_, arg_, arg_, arg_), ++ SARGS(fadvise64, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(timer_create, rdec, arg_, arg_, arg_), ++ SARGS(timer_settime, rdec, arg_, arg_, arg_, arg_), ++ SARGS(timer_gettime, rdec, arg_, arg_), ++ SARGS(timer_getoverrun, rdec, arg_), ++ SARGS(timer_delete, rdec, arg_), ++ SARGS(clock_settime, rdec, arg_, arg_), ++ SARGS(clock_gettime, rdec, arg_, arg_), ++ SARGS(clock_getres, rdec, arg_, arg_), ++ SARGS(clock_nanosleep, rdec, arg_, arg_, arg_, arg_), ++ SARGS(exit_group, rnoreturn, arg_), ++ SARGS(epoll_wait, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(epoll_ctl, rdec, arg_fd, arg_, arg_fd, arg_), ++ SARGS(tgkill, rdec, arg_, arg_, arg_), ++ SARGS(utimes, rdec, arg_cstr, arg_), ++ SARGS(mbind, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(set_mempolicy, rdec, arg_, arg_, arg_), ++ SARGS(get_mempolicy, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(mq_open, rdec, arg_cstr, arg_, arg_, arg_, arg_), ++ SARGS(mq_unlink, rdec, arg_cstr), ++ SARGS(mq_timedsend, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(mq_timedreceive, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(mq_notify, rdec, arg_, arg_), ++ SARGS(mq_getsetattr, rdec, arg_, arg_, arg_), ++ SARGS(kexec_load, rdec, arg_, arg_, arg_, arg_), ++ SARGS(waitid, rdec, arg_, arg_, arg_, arg_), ++ SARGS(add_key, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(request_key, rdec, arg_, arg_, arg_, arg_), ++ SARGS(keyctl, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(ioprio_set, rdec, arg_, arg_, arg_), ++ SARGS(ioprio_get, rdec, arg_, arg_), ++ SARGS(inotify_init, rdec, arg_none), ++ SARGS(inotify_add_watch, rdec, arg_fd, arg_cstr, arg_), ++ SARGS(inotify_rm_watch, rdec, arg_fd, arg_), ++ SARGS(migrate_pages, rdec, arg_, arg_, arg_, arg_), ++ SARGS(openat, rdec, arg_atfd, arg_cstr, arg_open_flags), ++ SARGS(mkdirat, rdec, arg_atfd, arg_cstr, arg_oct_mode), ++ SARGS(mknodat, rdec, arg_atfd, arg_cstr, arg_oct_mode, arg_), ++ SARGS(fchownat, rdec, arg_atfd, arg_cstr, arg_, arg_, arg_), ++ SARGS(futimesat, rdec, arg_atfd, arg_cstr, arg_), ++ SARGS(newfstatat, rdec, arg_atfd, arg_cstr, arg_, arg_), ++ SARGS(unlinkat, rdec, arg_atfd, arg_cstr, arg_), ++ SARGS(renameat, rdec, arg_atfd, arg_cstr, arg_atfd, arg_cstr), ++ SARGS(linkat, rdec, arg_atfd, arg_cstr, arg_atfd, arg_cstr, arg_), ++ SARGS(symlinkat, rdec, arg_cstr, arg_atfd, arg_cstr), ++ SARGS(readlinkat, rdec, arg_atfd, arg_cstr, arg_buf_out, arg_dec), ++ SARGS(fchmodat, rdec, arg_atfd, arg_cstr, arg_oct_mode), ++ SARGS(faccessat, rdec, arg_atfd, arg_cstr, arg_oct_mode), ++ SARGS(pselect6, rdec, arg_, arg_, arg_, arg_, arg_, arg_), ++ SARGS(ppoll, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(unshare, rdec, arg_), ++ SARGS(set_robust_list, rdec, arg_, arg_), ++ SARGS(get_robust_list, rdec, arg_, arg_, arg_), ++ SARGS(splice, rdec, arg_fd, arg_, arg_fd, arg_, arg_, arg_), ++ SARGS(tee, rdec, arg_fd, arg_fd, arg_, arg_), ++ SARGS(sync_file_range, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(vmsplice, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(move_pages, rdec, arg_, arg_, arg_, arg_, arg_, arg_), ++ SARGS(utimensat, rdec, arg_atfd, arg_cstr, arg_, arg_), ++ SARGS(epoll_pwait, rdec, arg_fd, arg_, arg_, arg_, arg_, arg_), ++ SARGS(signalfd, rdec, arg_fd, arg_, arg_), ++ SARGS(timerfd_create, rdec, arg_, arg_), ++ SARGS(eventfd, rdec, arg_), ++ SARGS(fallocate, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(timerfd_settime, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(timerfd_gettime, rdec, arg_fd, arg_), ++ SARGS(accept4, rdec, arg_fd, arg_, arg_, arg_, arg_), ++ SARGS(signalfd4, rdec, arg_fd, arg_, arg_, arg_, arg_), ++ SARGS(eventfd2, rdec, arg_, arg_), ++ SARGS(epoll_create1, rdec, arg_), ++ SARGS(dup3, rdec, arg_fd, arg_fd, arg_), ++ SARGS(pipe2, rdec, arg_2fds, arg_pipe2_flags), ++ SARGS(inotify_init1, rdec, arg_), ++ SARGS(preadv, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(pwritev, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(rt_tgsigqueueinfo, rdec, arg_, arg_, arg_, arg_), ++ SARGS(perf_event_open, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(recvmmsg, rdec, arg_fd, arg_, arg_, arg_, arg_), ++ SARGS(fanotify_init, rdec, arg_, arg_), ++ SARGS(fanotify_mark, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(prlimit64, rdec, arg_, arg_, arg_, arg_), ++ SARGS(name_to_handle_at, rdec, arg_atfd, arg_cstr, arg_, arg_, arg_), ++ SARGS(open_by_handle_at, rdec, arg_fd, arg_pointer, arg_dec32), ++ SARGS(clock_adjtime, rdec, arg_, arg_), ++ SARGS(syncfs, rdec, arg_fd), ++ SARGS(sendmmsg, rdec, arg_fd, arg_, arg_, arg_), ++ SARGS(setns, rdec, arg_fd, arg_), ++ SARGS(getcpu, rdec, arg_, arg_, arg_), ++ SARGS(process_vm_readv, rdec, arg_, arg_, arg_, arg_, arg_, arg_), ++ SARGS(process_vm_writev, rdec, arg_, arg_, arg_, arg_, arg_, arg_), ++ SARGS(kcmp, rdec, arg_, arg_, arg_, arg_, arg_), ++ SARGS(finit_module, rdec, arg_fd, arg_, arg_), ++#ifdef SYS_sched_setattr ++ SARGS(sched_setattr, rdec, arg_, arg_, arg_), ++#endif ++#ifdef SYS_sched_getattr ++ SARGS(sched_getattr, rdec, arg_, arg_, arg_, arg_), ++#endif ++#ifdef SYS_renameat2 ++ SARGS(renameat2, rdec, arg_atfd, arg_cstr, arg_atfd, arg_cstr, arg_), ++#endif ++#ifdef SYS_seccomp ++ SARGS(seccomp, rdec, arg_, arg_, arg_), ++#endif ++#ifdef SYS_getrandom ++ SARGS(getrandom, rdec, arg_, arg_, arg_), ++#endif ++#ifdef SYS_memfd_create ++ SARGS(memfd_create, rdec, arg_cstr, arg_), ++#endif ++#ifdef SYS_kexec_file_load ++ SARGS(kexec_file_load, rdec, arg_, arg_, arg_, arg_, arg_), ++#endif ++#ifdef SYS_bpf ++ SARGS(bpf, rdec, arg_, arg_, arg_), ++#endif ++#ifdef SYS_execveat ++ SARGS(execveat, rdec, arg_atfd, arg_cstr, arg_, arg_, arg_), ++#endif ++#ifdef SYS_userfaultfd ++ SARGS(userfaultfd, rdec, arg_), ++#endif ++#ifdef SYS_membarrier ++ SARGS(membarrier, rdec, arg_, arg_), ++#endif ++#ifdef SYS_mlock2 ++ SARGS(mlock2, rdec, arg_, arg_, arg_), ++#endif ++#ifdef SYS_copy_file_range ++ SARGS(copy_file_range, rdec, arg_fd, arg_, arg_fd, arg_, arg_, arg_), ++#endif ++#ifdef SYS_preadv2 ++ SARGS(preadv2, rdec, arg_fd, arg_, arg_, arg_, arg_), ++#endif ++#ifdef SYS_pwritev2 ++ SARGS(pwritev2, rdec, arg_fd, arg_, arg_, arg_, arg_), ++#endif ++#ifdef SYS_pkey_mprotect ++ SARGS(pkey_mprotect, rdec, arg_, arg_, arg_, arg_), ++#endif ++#ifdef SYS_pkey_alloc ++ SARGS(pkey_alloc, rdec, arg_, arg_), ++#endif ++#ifdef SYS_pkey_free ++ SARGS(pkey_free, rdec, arg_), ++#endif ++}; ++/* END CSTYLED */ ++ ++#undef SARGS ++ ++static struct syscall_format open_with_o_creat = {.name = "open", rdec, ++ {arg_cstr, arg_open_flags, arg_oct_mode}}; ++ ++static struct syscall_format openat_with_o_creat = {.name = "openat", rdec, ++ {arg_atfd, arg_cstr, arg_open_flags, arg_oct_mode}}; ++ ++static struct syscall_format fcntl_with_flock = {.name = "fcntl", rdec, ++ {arg_fd, arg_fcntl_cmd, arg_flock}}; ++ ++static struct syscall_format unkown = {.name = NULL, rdec, ++ {arg_, arg_, arg_, arg_, arg_, arg_}}; ++ ++static bool ++is_fcntl_with_flock(const struct syscall_desc *desc) ++{ ++ if (desc->nr != SYS_fcntl) ++ return false; ++ ++ switch ((int)desc->args[1]) { ++ case F_GETLK: ++ case F_SETLK: ++ case F_SETLKW: ++#ifdef F_OFD_GETLK ++ case F_OFD_GETLK: ++ case F_OFD_SETLK: ++ case F_OFD_SETLKW: ++#endif ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool ++oflags_refer_mode_arg(int flags) ++{ ++ if ((flags & O_CREAT) == O_CREAT) ++ return true; ++#ifdef O_TMPFILE ++ if ((flags & O_TMPFILE) == O_TMPFILE) ++ return true; ++#endif ++ return false; ++} ++ ++const struct syscall_format * ++get_syscall_format(const struct syscall_desc *desc) ++{ ++ if (desc->nr < 0 || (size_t)desc->nr >= ARRAY_SIZE(formats)) ++ return &unkown; ++ ++ if (formats[desc->nr].name == NULL) ++ return &unkown; ++ ++ if (desc->nr == SYS_open && oflags_refer_mode_arg((int)desc->args[1])) ++ return &open_with_o_creat; ++ ++ if (desc->nr == SYS_openat && oflags_refer_mode_arg((int)desc->args[2])) ++ return &openat_with_o_creat; ++ ++ if (is_fcntl_with_flock(desc)) ++ return &fcntl_with_flock; ++ ++ return formats + desc->nr; ++} +diff --git a/src/syscall_formats.c b/src/syscall_formats.c +deleted file mode 100644 +index eba064e..0000000 +--- a/src/syscall_formats.c ++++ /dev/null +@@ -1,463 +0,0 @@ +-/* +- * Copyright 2017, Intel Corporation +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in +- * the documentation and/or other materials provided with the +- * distribution. +- * +- * * Neither the name of the copyright holder nor the names of its +- * contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- */ +- +-#include "syscall_formats.h" +-#include "intercept_util.h" +- +-#include +-#include +- +-#define SARGS(name, r, ...) [SYS_##name] = {#name, r, {__VA_ARGS__}} +- +-/* Linux syscalls on X86_64 */ +-/* BEGIN CSTYLED */ +-static const struct syscall_format formats[] = { +- SARGS(read, rdec, arg_fd, arg_buf_out, arg_dec), +- SARGS(write, rdec, arg_fd, arg_buf_in, arg_dec), +- SARGS(open, rdec, arg_cstr, arg_open_flags), +- SARGS(close, rdec, arg_fd), +- SARGS(stat, rdec, arg_cstr, arg_pointer), +- SARGS(fstat, rdec, arg_fd, arg_pointer), +- SARGS(lstat, rdec, arg_cstr, arg_pointer), +- SARGS(poll, rdec, arg_pointer, arg_, arg_), +- SARGS(lseek, rdec, arg_fd, arg_dec, arg_seek_whence), +- SARGS(mmap, rpointer, arg_pointer, arg_, arg_, arg_, arg_fd, arg_), +- SARGS(mprotect, rdec, arg_pointer, arg_, arg_), +- SARGS(munmap, rdec, arg_pointer, arg_), +- SARGS(brk, rdec, arg_dec), +- SARGS(rt_sigaction, rdec, arg_dec32, arg_pointer, arg_pointer, arg_dec), +- SARGS(rt_sigprocmask, rdec, arg_, arg_pointer, arg_pointer, arg_dec), +- SARGS(rt_sigreturn, rnoreturn, arg_none), +- SARGS(ioctl, rdec, arg_fd, arg_, arg_pointer), +- SARGS(pread64, rdec, arg_fd, arg_buf_out, arg_dec, arg_dec), +- SARGS(pwrite64, rdec, arg_fd, arg_buf_in, arg_dec, arg_dec), +- SARGS(readv, rdec, arg_fd, arg_pointer, arg_dec), +- SARGS(writev, rdec, arg_fd, arg_pointer, arg_dec), +- SARGS(access, rdec, arg_cstr, arg_access_mode), +- SARGS(pipe, rdec, arg_2fds), +- SARGS(select, rdec, arg_dec32, arg_pointer, arg_pointer, arg_pointer, arg_pointer), +- SARGS(sched_yield, rdec, arg_none), +- SARGS(mremap, rpointer, arg_pointer, arg_dec, arg_dec, arg_dec32, arg_), +- SARGS(msync, rdec, arg_pointer, arg_dec, arg_dec32), +- SARGS(mincore, rdec, arg_pointer, arg_dec, arg_pointer), +- SARGS(madvise, rdec, arg_pointer, arg_dec, arg_dec32), +- SARGS(shmget, rdec, arg_, arg_, arg_), +- SARGS(shmat, rhex, arg_, arg_, arg_), +- SARGS(shmctl, rdec, arg_, arg_, arg_), +- SARGS(dup, rdec, arg_fd), +- SARGS(dup2, rdec, arg_fd, arg_fd), +- SARGS(pause, rdec, arg_none), +- SARGS(nanosleep, rdec, arg_, arg_), +- SARGS(getitimer, rdec, arg_, arg_), +- SARGS(alarm, rdec, arg_), +- SARGS(setitimer, rdec, arg_, arg_, arg_), +- SARGS(getpid, rdec, arg_none), +- SARGS(sendfile, rdec, arg_fd, arg_fd, arg_, arg_), +- SARGS(socket, rdec, arg_, arg_, arg_), +- SARGS(connect, rdec, arg_fd, arg_, arg_), +- SARGS(accept, rdec, arg_fd, arg_, arg_), +- SARGS(sendto, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(recvfrom, rdec, arg_fd, arg_, arg_, arg_, arg_, arg_), +- SARGS(sendmsg, rdec, arg_fd, arg_, arg_), +- SARGS(recvmsg, rdec, arg_fd, arg_, arg_), +- SARGS(shutdown, rdec, arg_fd, arg_), +- SARGS(bind, rdec, arg_fd, arg_, arg_), +- SARGS(listen, rdec, arg_fd, arg_), +- SARGS(getsockname, rdec, arg_fd, arg_, arg_), +- SARGS(getpeername, rdec, arg_fd, arg_, arg_), +- SARGS(socketpair, rdec, arg_, arg_, arg_, arg_), +- SARGS(setsockopt, rdec, arg_fd, arg_, arg_, arg_, arg_), +- SARGS(getsockopt, rdec, arg_fd, arg_, arg_, arg_, arg_), +- SARGS(clone, rdec, arg_clone_flags, arg_pointer, arg_pointer, arg_pointer, arg_), +- SARGS(fork, rdec, arg_none), +- SARGS(vfork, rdec, arg_none), +- SARGS(execve, rdec, arg_, arg_, arg_), +- SARGS(exit, rnoreturn, arg_), +- SARGS(wait4, rdec, arg_dec, arg_, arg_, arg_), +- SARGS(kill, rdec, arg_, arg_), +- SARGS(uname, rdec, arg_), +- SARGS(semget, rdec, arg_, arg_, arg_), +- SARGS(semop, rdec, arg_, arg_, arg_), +- SARGS(semctl, rdec, arg_, arg_, arg_, arg_, arg_, arg_), +- SARGS(shmdt, rdec, arg_), +- SARGS(msgget, rdec, arg_, arg_), +- SARGS(msgsnd, rdec, arg_, arg_, arg_, arg_), +- SARGS(msgrcv, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(msgctl, rdec, arg_, arg_, arg_), +- SARGS(fcntl, rdec, arg_fd, arg_fcntl_cmd, arg_), +- SARGS(flock, rdec, arg_fd, arg_), +- SARGS(fsync, rdec, arg_fd), +- SARGS(fdatasync, rdec, arg_fd), +- SARGS(truncate, rdec, arg_cstr, arg_), +- SARGS(ftruncate, rdec, arg_fd, arg_), +- SARGS(getdents, rdec, arg_fd, arg_, arg_), +- SARGS(getcwd, rdec, arg_, arg_), +- SARGS(chdir, rdec, arg_cstr), +- SARGS(fchdir, rdec, arg_fd), +- SARGS(rename, rdec, arg_cstr, arg_cstr), +- SARGS(mkdir, rdec, arg_cstr, arg_oct_mode), +- SARGS(rmdir, rdec, arg_cstr), +- SARGS(creat, rdec, arg_cstr, arg_oct_mode), +- SARGS(link, rdec, arg_cstr, arg_cstr), +- SARGS(unlink, rdec, arg_cstr), +- SARGS(symlink, rdec, arg_cstr, arg_cstr), +- SARGS(readlink, rdec, arg_cstr, arg_buf_out, arg_dec), +- SARGS(chmod, rdec, arg_cstr, arg_oct_mode), +- SARGS(fchmod, rdec, arg_fd, arg_oct_mode), +- SARGS(chown, rdec, arg_cstr, arg_, arg_), +- SARGS(fchown, rdec, arg_fd, arg_, arg_), +- SARGS(lchown, rdec, arg_cstr, arg_, arg_), +- SARGS(umask, rmode, arg_oct_mode), +- SARGS(gettimeofday, rdec, arg_, arg_), +- SARGS(getrlimit, rdec, arg_, arg_), +- SARGS(getrusage, rdec, arg_, arg_), +- SARGS(sysinfo, rdec, arg_, arg_), +- SARGS(times, rdec, arg_), +- SARGS(ptrace, rhex, arg_, arg_, arg_, arg_), +- SARGS(getuid, rdec, arg_none), +- SARGS(syslog, rdec, arg_, arg_, arg_), +- SARGS(getgid, rdec, arg_none), +- SARGS(setuid, rdec, arg_), +- SARGS(setgid, rdec, arg_), +- SARGS(geteuid, rdec, arg_none), +- SARGS(getegid, rdec, arg_none), +- SARGS(setpgid, rdec, arg_none), +- SARGS(getpgrp, rdec, arg_none), +- SARGS(setsid, rdec, arg_none), +- SARGS(setreuid, rdec, arg_, arg_), +- SARGS(setregid, rdec, arg_, arg_), +- SARGS(getgroups, rdec, arg_, arg_), +- SARGS(setgroups, rdec, arg_, arg_), +- SARGS(setresuid, rdec, arg_, arg_, arg_), +- SARGS(getresuid, rdec, arg_, arg_, arg_), +- SARGS(setresgid, rdec, arg_, arg_, arg_), +- SARGS(getresgid, rdec, arg_, arg_, arg_), +- SARGS(getpgid, rdec, arg_), +- SARGS(setfsuid, rdec, arg_), +- SARGS(setfsgid, rdec, arg_), +- SARGS(getsid, rdec, arg_), +- SARGS(capget, rdec, arg_, arg_), +- SARGS(capset, rdec, arg_, arg_), +- SARGS(rt_sigpending, rdec, arg_), +- SARGS(rt_sigtimedwait, rdec, arg_, arg_, arg_, arg_), +- SARGS(rt_sigqueueinfo, rdec, arg_, arg_, arg_), +- SARGS(rt_sigsuspend, rdec, arg_, arg_), +- SARGS(sigaltstack, rdec, arg_, arg_), +- SARGS(utime, rdec, arg_cstr, arg_), +- SARGS(mknod, rdec, arg_cstr, arg_, arg_), +- SARGS(uselib, rdec, arg_cstr), +- SARGS(personality, rdec, arg_), +- SARGS(ustat, rdec, arg_, arg_), +- SARGS(statfs, rdec, arg_cstr, arg_), +- SARGS(fstatfs, rdec, arg_fd, arg_), +- SARGS(sysfs, rdec, arg_, arg_, arg_), +- SARGS(getpriority, rdec, arg_, arg_), +- SARGS(setpriority, rdec, arg_, arg_, arg_), +- SARGS(sched_setparam, rdec, arg_, arg_), +- SARGS(sched_getparam, rdec, arg_, arg_), +- SARGS(sched_setscheduler, rdec, arg_, arg_, arg_), +- SARGS(sched_getscheduler, rdec, arg_), +- SARGS(sched_get_priority_max, rdec, arg_), +- SARGS(sched_get_priority_min, rdec, arg_), +- SARGS(sched_rr_get_interval, rdec, arg_, arg_), +- SARGS(mlock, rdec, arg_, arg_), +- SARGS(munlock, rdec, arg_, arg_), +- SARGS(mlockall, rdec, arg_), +- SARGS(munlockall, rdec, arg_none), +- SARGS(vhangup, rdec, arg_none), +- SARGS(modify_ldt, rdec, arg_, arg_, arg_), +- SARGS(pivot_root, rdec, arg_cstr, arg_), +- SARGS(_sysctl, rdec, arg_), +- SARGS(prctl, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(arch_prctl, rdec, arg_, arg_, arg_), +- SARGS(adjtimex, rdec, arg_), +- SARGS(setrlimit, rdec, arg_, arg_), +- SARGS(chroot, rdec, arg_cstr), +- SARGS(sync, rdec, arg_none), +- SARGS(acct, rdec, arg_cstr), +- SARGS(settimeofday, rdec, arg_, arg_), +- SARGS(mount, rdec, arg_cstr, arg_cstr, arg_, arg_, arg_), +- SARGS(umount2, rdec, arg_cstr, arg_), +- SARGS(swapon, rdec, arg_cstr, arg_), +- SARGS(swapoff, rdec, arg_cstr), +- SARGS(reboot, rdec, arg_, arg_, arg_, arg_), +- SARGS(sethostname, rdec, arg_, arg_), +- SARGS(setdomainname, rdec, arg_, arg_), +- SARGS(iopl, rdec, arg_), +- SARGS(ioperm, rdec, arg_, arg_, arg_), +- SARGS(gettid, rdec, arg_none), +- SARGS(readahead, rdec, arg_fd, arg_dec, arg_dec), +- SARGS(setxattr, rdec, arg_cstr, arg_cstr, arg_buf_in, arg_dec, arg_), +- SARGS(lsetxattr, rdec, arg_cstr, arg_cstr, arg_buf_in, arg_dec, arg_), +- SARGS(fsetxattr, rdec, arg_fd, arg_cstr, arg_buf_in, arg_dec, arg_), +- SARGS(getxattr, rdec, arg_cstr, arg_cstr, arg_dec, arg_), +- SARGS(lgetxattr, rdec, arg_cstr, arg_cstr, arg_dec, arg_), +- SARGS(fgetxattr, rdec, arg_fd, arg_cstr, arg_dec, arg_), +- SARGS(listxattr, rdec, arg_cstr, arg_pointer, arg_dec), +- SARGS(llistxattr, rdec, arg_cstr, arg_pointer, arg_dec), +- SARGS(flistxattr, rdec, arg_fd, arg_pointer, arg_dec), +- SARGS(removexattr, rdec, arg_cstr, arg_cstr), +- SARGS(lremovexattr, rdec, arg_cstr, arg_cstr), +- SARGS(fremovexattr, rdec, arg_fd, arg_cstr), +- SARGS(tkill, rdec, arg_, arg_), +- SARGS(time, rdec, arg_), +- SARGS(futex, rdec, arg_, arg_, arg_, arg_, arg_, arg_), +- SARGS(sched_setaffinity, rdec, arg_, arg_, arg_), +- SARGS(sched_getaffinity, rdec, arg_, arg_, arg_), +- SARGS(set_thread_area, rdec, arg_), +- SARGS(io_setup, rdec, arg_, arg_), +- SARGS(io_destroy, rdec, arg_), +- SARGS(io_getevents, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(io_submit, rdec, arg_, arg_, arg_), +- SARGS(io_cancel, rdec, arg_, arg_, arg_), +- SARGS(get_thread_area, rdec, arg_), +- SARGS(lookup_dcookie, rdec, arg_, arg_, arg_), +- SARGS(epoll_create, rdec, arg_), +- SARGS(getdents64, rdec, arg_fd, arg_, arg_), +- SARGS(set_tid_address, rdec, arg_), +- SARGS(semtimedop, rdec, arg_, arg_, arg_, arg_), +- SARGS(fadvise64, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(timer_create, rdec, arg_, arg_, arg_), +- SARGS(timer_settime, rdec, arg_, arg_, arg_, arg_), +- SARGS(timer_gettime, rdec, arg_, arg_), +- SARGS(timer_getoverrun, rdec, arg_), +- SARGS(timer_delete, rdec, arg_), +- SARGS(clock_settime, rdec, arg_, arg_), +- SARGS(clock_gettime, rdec, arg_, arg_), +- SARGS(clock_getres, rdec, arg_, arg_), +- SARGS(clock_nanosleep, rdec, arg_, arg_, arg_, arg_), +- SARGS(exit_group, rnoreturn, arg_), +- SARGS(epoll_wait, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(epoll_ctl, rdec, arg_fd, arg_, arg_fd, arg_), +- SARGS(tgkill, rdec, arg_, arg_, arg_), +- SARGS(utimes, rdec, arg_cstr, arg_), +- SARGS(mbind, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(set_mempolicy, rdec, arg_, arg_, arg_), +- SARGS(get_mempolicy, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(mq_open, rdec, arg_cstr, arg_, arg_, arg_, arg_), +- SARGS(mq_unlink, rdec, arg_cstr), +- SARGS(mq_timedsend, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(mq_timedreceive, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(mq_notify, rdec, arg_, arg_), +- SARGS(mq_getsetattr, rdec, arg_, arg_, arg_), +- SARGS(kexec_load, rdec, arg_, arg_, arg_, arg_), +- SARGS(waitid, rdec, arg_, arg_, arg_, arg_), +- SARGS(add_key, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(request_key, rdec, arg_, arg_, arg_, arg_), +- SARGS(keyctl, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(ioprio_set, rdec, arg_, arg_, arg_), +- SARGS(ioprio_get, rdec, arg_, arg_), +- SARGS(inotify_init, rdec, arg_none), +- SARGS(inotify_add_watch, rdec, arg_fd, arg_cstr, arg_), +- SARGS(inotify_rm_watch, rdec, arg_fd, arg_), +- SARGS(migrate_pages, rdec, arg_, arg_, arg_, arg_), +- SARGS(openat, rdec, arg_atfd, arg_cstr, arg_open_flags), +- SARGS(mkdirat, rdec, arg_atfd, arg_cstr, arg_oct_mode), +- SARGS(mknodat, rdec, arg_atfd, arg_cstr, arg_oct_mode, arg_), +- SARGS(fchownat, rdec, arg_atfd, arg_cstr, arg_, arg_, arg_), +- SARGS(futimesat, rdec, arg_atfd, arg_cstr, arg_), +- SARGS(newfstatat, rdec, arg_atfd, arg_cstr, arg_, arg_), +- SARGS(unlinkat, rdec, arg_atfd, arg_cstr, arg_), +- SARGS(renameat, rdec, arg_atfd, arg_cstr, arg_atfd, arg_cstr), +- SARGS(linkat, rdec, arg_atfd, arg_cstr, arg_atfd, arg_cstr, arg_), +- SARGS(symlinkat, rdec, arg_cstr, arg_atfd, arg_cstr), +- SARGS(readlinkat, rdec, arg_atfd, arg_cstr, arg_buf_out, arg_dec), +- SARGS(fchmodat, rdec, arg_atfd, arg_cstr, arg_oct_mode), +- SARGS(faccessat, rdec, arg_atfd, arg_cstr, arg_oct_mode), +- SARGS(pselect6, rdec, arg_, arg_, arg_, arg_, arg_, arg_), +- SARGS(ppoll, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(unshare, rdec, arg_), +- SARGS(set_robust_list, rdec, arg_, arg_), +- SARGS(get_robust_list, rdec, arg_, arg_, arg_), +- SARGS(splice, rdec, arg_fd, arg_, arg_fd, arg_, arg_, arg_), +- SARGS(tee, rdec, arg_fd, arg_fd, arg_, arg_), +- SARGS(sync_file_range, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(vmsplice, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(move_pages, rdec, arg_, arg_, arg_, arg_, arg_, arg_), +- SARGS(utimensat, rdec, arg_atfd, arg_cstr, arg_, arg_), +- SARGS(epoll_pwait, rdec, arg_fd, arg_, arg_, arg_, arg_, arg_), +- SARGS(signalfd, rdec, arg_fd, arg_, arg_), +- SARGS(timerfd_create, rdec, arg_, arg_), +- SARGS(eventfd, rdec, arg_), +- SARGS(fallocate, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(timerfd_settime, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(timerfd_gettime, rdec, arg_fd, arg_), +- SARGS(accept4, rdec, arg_fd, arg_, arg_, arg_, arg_), +- SARGS(signalfd4, rdec, arg_fd, arg_, arg_, arg_, arg_), +- SARGS(eventfd2, rdec, arg_, arg_), +- SARGS(epoll_create1, rdec, arg_), +- SARGS(dup3, rdec, arg_fd, arg_fd, arg_), +- SARGS(pipe2, rdec, arg_2fds, arg_pipe2_flags), +- SARGS(inotify_init1, rdec, arg_), +- SARGS(preadv, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(pwritev, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(rt_tgsigqueueinfo, rdec, arg_, arg_, arg_, arg_), +- SARGS(perf_event_open, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(recvmmsg, rdec, arg_fd, arg_, arg_, arg_, arg_), +- SARGS(fanotify_init, rdec, arg_, arg_), +- SARGS(fanotify_mark, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(prlimit64, rdec, arg_, arg_, arg_, arg_), +- SARGS(name_to_handle_at, rdec, arg_atfd, arg_cstr, arg_, arg_, arg_), +- SARGS(open_by_handle_at, rdec, arg_fd, arg_pointer, arg_dec32), +- SARGS(clock_adjtime, rdec, arg_, arg_), +- SARGS(syncfs, rdec, arg_fd), +- SARGS(sendmmsg, rdec, arg_fd, arg_, arg_, arg_), +- SARGS(setns, rdec, arg_fd, arg_), +- SARGS(getcpu, rdec, arg_, arg_, arg_), +- SARGS(process_vm_readv, rdec, arg_, arg_, arg_, arg_, arg_, arg_), +- SARGS(process_vm_writev, rdec, arg_, arg_, arg_, arg_, arg_, arg_), +- SARGS(kcmp, rdec, arg_, arg_, arg_, arg_, arg_), +- SARGS(finit_module, rdec, arg_fd, arg_, arg_), +-#ifdef SYS_sched_setattr +- SARGS(sched_setattr, rdec, arg_, arg_, arg_), +-#endif +-#ifdef SYS_sched_getattr +- SARGS(sched_getattr, rdec, arg_, arg_, arg_, arg_), +-#endif +-#ifdef SYS_renameat2 +- SARGS(renameat2, rdec, arg_atfd, arg_cstr, arg_atfd, arg_cstr, arg_), +-#endif +-#ifdef SYS_seccomp +- SARGS(seccomp, rdec, arg_, arg_, arg_), +-#endif +-#ifdef SYS_getrandom +- SARGS(getrandom, rdec, arg_, arg_, arg_), +-#endif +-#ifdef SYS_memfd_create +- SARGS(memfd_create, rdec, arg_cstr, arg_), +-#endif +-#ifdef SYS_kexec_file_load +- SARGS(kexec_file_load, rdec, arg_, arg_, arg_, arg_, arg_), +-#endif +-#ifdef SYS_bpf +- SARGS(bpf, rdec, arg_, arg_, arg_), +-#endif +-#ifdef SYS_execveat +- SARGS(execveat, rdec, arg_atfd, arg_cstr, arg_, arg_, arg_), +-#endif +-#ifdef SYS_userfaultfd +- SARGS(userfaultfd, rdec, arg_), +-#endif +-#ifdef SYS_membarrier +- SARGS(membarrier, rdec, arg_, arg_), +-#endif +-#ifdef SYS_mlock2 +- SARGS(mlock2, rdec, arg_, arg_, arg_), +-#endif +-#ifdef SYS_copy_file_range +- SARGS(copy_file_range, rdec, arg_fd, arg_, arg_fd, arg_, arg_, arg_), +-#endif +-#ifdef SYS_preadv2 +- SARGS(preadv2, rdec, arg_fd, arg_, arg_, arg_, arg_), +-#endif +-#ifdef SYS_pwritev2 +- SARGS(pwritev2, rdec, arg_fd, arg_, arg_, arg_, arg_), +-#endif +-#ifdef SYS_pkey_mprotect +- SARGS(pkey_mprotect, rdec, arg_, arg_, arg_, arg_), +-#endif +-#ifdef SYS_pkey_alloc +- SARGS(pkey_alloc, rdec, arg_, arg_), +-#endif +-#ifdef SYS_pkey_free +- SARGS(pkey_free, rdec, arg_), +-#endif +-}; +-/* END CSTYLED */ +- +-#undef SARGS +- +-static struct syscall_format open_with_o_creat = {.name = "open", rdec, +- {arg_cstr, arg_open_flags, arg_oct_mode}}; +- +-static struct syscall_format openat_with_o_creat = {.name = "openat", rdec, +- {arg_atfd, arg_cstr, arg_open_flags, arg_oct_mode}}; +- +-static struct syscall_format fcntl_with_flock = {.name = "fcntl", rdec, +- {arg_fd, arg_fcntl_cmd, arg_flock}}; +- +-static struct syscall_format unkown = {.name = NULL, rdec, +- {arg_, arg_, arg_, arg_, arg_, arg_}}; +- +-static bool +-is_fcntl_with_flock(const struct syscall_desc *desc) +-{ +- if (desc->nr != SYS_fcntl) +- return false; +- +- switch ((int)desc->args[1]) { +- case F_GETLK: +- case F_SETLK: +- case F_SETLKW: +-#ifdef F_OFD_GETLK +- case F_OFD_GETLK: +- case F_OFD_SETLK: +- case F_OFD_SETLKW: +-#endif +- return true; +- default: +- return false; +- } +-} +- +-static bool +-oflags_refer_mode_arg(int flags) +-{ +- if ((flags & O_CREAT) == O_CREAT) +- return true; +-#ifdef O_TMPFILE +- if ((flags & O_TMPFILE) == O_TMPFILE) +- return true; +-#endif +- return false; +-} +- +-const struct syscall_format * +-get_syscall_format(const struct syscall_desc *desc) +-{ +- if (desc->nr < 0 || (size_t)desc->nr >= ARRAY_SIZE(formats)) +- return &unkown; +- +- if (formats[desc->nr].name == NULL) +- return &unkown; +- +- if (desc->nr == SYS_open && oflags_refer_mode_arg((int)desc->args[1])) +- return &open_with_o_creat; +- +- if (desc->nr == SYS_openat && oflags_refer_mode_arg((int)desc->args[2])) +- return &openat_with_o_creat; +- +- if (is_fcntl_with_flock(desc)) +- return &fcntl_with_flock; +- +- return formats + desc->nr; +-} +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index 3525346..7b74fa3 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -43,6 +43,7 @@ set(CMAKE_ASM_CREATE_SHARED_LIBRARY ${CMAKE_C_CREATE_SHARED_LIBRARY}) + + add_executable(asm_pattern asm_pattern.c + $ ++ $ + $) + + target_link_libraries(asm_pattern diff --git a/debian/patches/i386/Support-i686-compilation.patch b/debian/patches/i386/Support-i686-compilation.patch new file mode 100644 index 0000000000000000000000000000000000000000..17f6fb3ba700877ed01dfed995eb460908bf440f --- /dev/null +++ b/debian/patches/i386/Support-i686-compilation.patch @@ -0,0 +1,135 @@ +From: Gabriel Krisman Bertazi +Date: Thu, 25 Apr 2019 15:07:45 -0400 +Subject: Support i686 compilation + +Implement the minimum required to succesfully compile syscall_intercept +for a 32-bit platform. +--- + src/arch/i686/CMakeLists.txt | 39 +++++++++++++++++++++++++++++++++++++++ + src/arch/i686/syscall_formats.c | 41 +++++++++++++++++++++++++++++++++++++++++ + src/arch/i686/util.S | 22 ++++++++++++++++++++++ + 3 files changed, 102 insertions(+) + create mode 100644 src/arch/i686/CMakeLists.txt + create mode 100644 src/arch/i686/syscall_formats.c + create mode 100644 src/arch/i686/util.S + +diff --git a/src/arch/i686/CMakeLists.txt b/src/arch/i686/CMakeLists.txt +new file mode 100644 +index 0000000..5e18575 +--- /dev/null ++++ b/src/arch/i686/CMakeLists.txt +@@ -0,0 +1,39 @@ ++# ++# Copyright 2019, Collabora, ltd. ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions ++# are met: ++# ++# * Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# ++# * Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in ++# the documentation and/or other materials provided with the ++# distribution. ++# ++# * Neither the name of the copyright holder nor the names of its ++# contributors may be used to endorse or promote products derived ++# from this software without specific prior written permission. ++# ++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++set(SOURCES_ARCH ++ syscall_formats.c) ++ ++set(SOURCES_ASM util.S) ++ ++add_library(syscall_intercept_base_arch OBJECT ${SOURCES_ARCH}) ++include_directories(syscall_intercept_base_arch ${CMAKE_SOURCE_DIR}/src) ++add_library(syscall_intercept_base_asm OBJECT ${SOURCES_ASM}) +diff --git a/src/arch/i686/syscall_formats.c b/src/arch/i686/syscall_formats.c +new file mode 100644 +index 0000000..5380e23 +--- /dev/null ++++ b/src/arch/i686/syscall_formats.c +@@ -0,0 +1,41 @@ ++/* ++ * Copyright 2019, Collabora, Ltd. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "syscall_formats.h" ++#include "intercept_util.h" ++ ++const struct syscall_format * ++get_syscall_format(const struct syscall_desc *desc) ++{ ++ (void)desc; ++ return NULL; ++} +diff --git a/src/arch/i686/util.S b/src/arch/i686/util.S +new file mode 100644 +index 0000000..5c8f6c2 +--- /dev/null ++++ b/src/arch/i686/util.S +@@ -0,0 +1,22 @@ ++.globl intercept_asm_wrapper_tmpl ++.globl intercept_asm_wrapper_tmpl_end ++.globl intercept_asm_wrapper_wrapper_level1_addr ++.globl intercept_asm_wrapper_patch_desc_addr ++.globl intercept_wrapper ++.globl has_ymm_registers ++.globl syscall_no_intercept ++intercept_asm_wrapper_tmpl: ++ .word 0x100 ++intercept_asm_wrapper_patch_desc_addr: ++intercept_asm_wrapper_wrapper_level1_addr: ++ .word 0x100 ++intercept_asm_wrapper_tmpl_end: ++intercept_wrapper: ++syscall_no_intercept: ++ .word 0x100 ++ ++has_ymm_registers: ++ mov $0x0, %eax ++ ret ++ ++ diff --git a/debian/patches/i386/Support-merging-of-sequential-nops.patch b/debian/patches/i386/Support-merging-of-sequential-nops.patch new file mode 100644 index 0000000000000000000000000000000000000000..5ac42e80cf40c1ffea069a93c4118bf2a2f0d8e0 --- /dev/null +++ b/debian/patches/i386/Support-merging-of-sequential-nops.patch @@ -0,0 +1,132 @@ +From: Gabriel Krisman Bertazi +Date: Fri, 10 May 2019 21:40:02 -0400 +Subject: Support merging of sequential nops + +--- + src/arch.h | 2 ++ + src/arch/i686/parser.c | 7 +++++-- + src/arch/x86_64/parser.c | 5 +++++ + src/intercept_desc.c | 50 +++++++++++++++++++++++++++++++++++++++++++++--- + 4 files changed, 59 insertions(+), 5 deletions(-) + +diff --git a/src/arch.h b/src/arch.h +index 2dbd006..b13a268 100644 +--- a/src/arch.h ++++ b/src/arch.h +@@ -39,4 +39,6 @@ struct cs_insn; + + bool arch_insn_is_syscall(struct cs_insn *insn); + ++unsigned arch_trampoline_entry_size(); ++ + #endif /* INTERCEPT_ARCH_H */ +diff --git a/src/arch/i686/parser.c b/src/arch/i686/parser.c +index ae1585d..90735f9 100644 +--- a/src/arch/i686/parser.c ++++ b/src/arch/i686/parser.c +@@ -34,6 +34,11 @@ + #include "arch.h" + #include "capstone_wrapper.h" + ++unsigned arch_trampoline_entry_size() ++{ ++ return 7; ++} ++ + bool arch_insn_is_syscall(struct cs_insn *insn) + { + if (insn->id == X86_INS_INT && +@@ -41,5 +46,3 @@ bool arch_insn_is_syscall(struct cs_insn *insn) + return true; + return false; + } +- +- +diff --git a/src/arch/x86_64/parser.c b/src/arch/x86_64/parser.c +index 428653a..e9c6c68 100644 +--- a/src/arch/x86_64/parser.c ++++ b/src/arch/x86_64/parser.c +@@ -38,3 +38,8 @@ bool arch_insn_is_syscall(struct cs_insn *insn) + { + return (insn->id == X86_INS_SYSCALL); + } ++ ++unsigned arch_trampoline_entry_size() ++{ ++ return 7; ++} +diff --git a/src/intercept_desc.c b/src/intercept_desc.c +index bef77ee..5925368 100644 +--- a/src/intercept_desc.c ++++ b/src/intercept_desc.c +@@ -44,6 +44,7 @@ + #include "intercept.h" + #include "intercept_util.h" + #include "disasm_wrapper.h" ++#include "arch.h" + + /* + * open_orig_file +@@ -412,7 +413,43 @@ add_new_patch(struct intercept_desc *desc) + bool + is_overwritable_nop(const struct intercept_disasm_result *ins) + { +- return ins->is_nop && ins->length >= 2 + 5; ++ return ins->is_nop && ins->length >= arch_trampoline_entry_size(); ++} ++ ++ ++/* ++ * merge_multiple_nops Speculatively merge sequences of NOP ++ * instructions, into a single larger pseudo-instruction, up to the ++ * minimum space required for a long jump. This increases the number of ++ * available trampolines for architectures that don't have a large nopl ++ * instruction. ++ * ++ * It is speculative, because it assumes that none of the merged nops ++ * (except for the first one) is a jump target. This is a weak ++ * assumption, so it should be verified later on, once the code is ++ * completely crawled and every basic block entry is known. ++ */ ++unsigned merge_nops(struct intercept_disasm_context *context, ++ struct intercept_disasm_result first, ++ const unsigned char *code, ++ const unsigned char *code_end) ++{ ++ unsigned max_length = arch_trampoline_entry_size(); ++ unsigned acc_length = first.length; ++ struct intercept_disasm_result cur; ++ ++ /* skip first instruction */ ++ code += first.length; ++ ++ while (acc_length < max_length && code <= code_end) { ++ cur = intercept_disasm_next_instruction(context, code); ++ if (cur.length == 0 || !cur.is_nop) ++ break; ++ ++ acc_length += cur.length; ++ code += cur.length; ++ } ++ return acc_length; + } + + /* +@@ -467,8 +504,15 @@ crawl_text(struct intercept_desc *desc) + if (result.has_ip_relative_opr) + mark_jump(desc, result.rip_ref_addr); + +- if (is_overwritable_nop(&result)) +- mark_nop(desc, code, result.length); ++ if (result.is_nop) { ++ if (!is_overwritable_nop(&result)) ++ result.length = merge_nops(context, result, ++ code, desc->text_end); ++ ++ if (is_overwritable_nop(&result)) { ++ mark_nop(desc, code, result.length); ++ } ++ } + + /* + * Generate a new patch description, if: diff --git a/debian/patches/i386/i686-Implement-custom-xmmap_anon.patch b/debian/patches/i386/i686-Implement-custom-xmmap_anon.patch new file mode 100644 index 0000000000000000000000000000000000000000..a88cb09d4fc6d70581fe84e0144085e0b9686fa5 --- /dev/null +++ b/debian/patches/i386/i686-Implement-custom-xmmap_anon.patch @@ -0,0 +1,99 @@ +From: Gabriel Krisman Bertazi +Date: Thu, 25 Apr 2019 15:11:50 -0400 +Subject: i686: Implement custom xmmap_anon + +In i686, SYS_mmap invokes the old_mmap syscall, which has a different +signature. Instead, we can use SYS_mmap2, which is more recent, and +only differs in the handling of the offset parameter, which doesn't +matter in this case. +--- + src/arch/i686/CMakeLists.txt | 3 ++- + src/arch/i686/intercept_util.c | 51 ++++++++++++++++++++++++++++++++++++++++++ + src/intercept_util.c | 2 +- + 3 files changed, 54 insertions(+), 2 deletions(-) + create mode 100644 src/arch/i686/intercept_util.c + +diff --git a/src/arch/i686/CMakeLists.txt b/src/arch/i686/CMakeLists.txt +index 5e18575..e492860 100644 +--- a/src/arch/i686/CMakeLists.txt ++++ b/src/arch/i686/CMakeLists.txt +@@ -30,7 +30,8 @@ + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + set(SOURCES_ARCH +- syscall_formats.c) ++ syscall_formats.c ++ intercept_util.c) + + set(SOURCES_ASM util.S) + +diff --git a/src/arch/i686/intercept_util.c b/src/arch/i686/intercept_util.c +new file mode 100644 +index 0000000..de8c8a5 +--- /dev/null ++++ b/src/arch/i686/intercept_util.c +@@ -0,0 +1,51 @@ ++/* ++ * Copyright 2019, Collabora, ltd. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* Override with arch specific implementation */ ++ ++#include ++#include ++#include ++#include ++ ++void * ++xmmap_anon(size_t size) ++{ ++ long addr = syscall_no_intercept(SYS_mmap2, ++ NULL, size, ++ PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANON, -1, (off_t)0); ++ ++ xabort_on_syserror(addr, __func__); ++ ++ return (void *) addr; ++} +diff --git a/src/intercept_util.c b/src/intercept_util.c +index 4472e52..55f0200 100644 +--- a/src/intercept_util.c ++++ b/src/intercept_util.c +@@ -51,7 +51,7 @@ + #include + + void * +-xmmap_anon(size_t size) ++__attribute__((weak)) xmmap_anon(size_t size) + { + long addr = syscall_no_intercept(SYS_mmap, + NULL, size, diff --git a/debian/patches/i386/i686-Implement-get_syscall_in_context.patch b/debian/patches/i386/i686-Implement-get_syscall_in_context.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b176da5c3825b4ded7a05a5b898ad665b64d470 --- /dev/null +++ b/debian/patches/i386/i686-Implement-get_syscall_in_context.patch @@ -0,0 +1,132 @@ +From: Gabriel Krisman Bertazi +Date: Mon, 13 May 2019 13:24:18 -0400 +Subject: i686: Implement get_syscall_in_context + +--- + src/arch/i686/CMakeLists.txt | 5 +++- + src/arch/i686/arch-base.h | 25 ++++++++++++++++++ + src/arch/i686/intercept.c | 60 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 89 insertions(+), 1 deletion(-) + create mode 100644 src/arch/i686/arch-base.h + create mode 100644 src/arch/i686/intercept.c + +diff --git a/src/arch/i686/CMakeLists.txt b/src/arch/i686/CMakeLists.txt +index 93088d4..d56dbf4 100644 +--- a/src/arch/i686/CMakeLists.txt ++++ b/src/arch/i686/CMakeLists.txt +@@ -33,14 +33,17 @@ set(SOURCES_ARCH + syscall_formats.c + intercept_util.c + symbols.c +- parser.c) ++ parser.c ++ intercept.c) + + set(SOURCES_ASM util.S + intercept_template.S) + + add_library(syscall_intercept_base_arch OBJECT ${SOURCES_ARCH}) + include_directories(syscall_intercept_base_arch ${CMAKE_SOURCE_DIR}/src) ++include_directories(syscall_intercept_base_arch .) + add_library(syscall_intercept_base_asm OBJECT ${SOURCES_ASM}) + + set_property(TARGET syscall_intercept_base_arch + APPEND PROPERTY COMPILE_FLAGS ${capstone_CFLAGS}) ++ +diff --git a/src/arch/i686/arch-base.h b/src/arch/i686/arch-base.h +new file mode 100644 +index 0000000..e0a2481 +--- /dev/null ++++ b/src/arch/i686/arch-base.h +@@ -0,0 +1,25 @@ ++#ifndef _ARCH_SPECIFIC_H ++#define _ARCH_SPECIFIC_H ++ ++#include ++ ++/* ++ * Kernel can clobber rcx and r11 while serving a syscall, those are ignored ++ * The layout of this struct depends on the way the assembly wrapper saves ++ * register on the stack. ++ * Note: don't expect the SIMD array to be aligned for efficient use with ++ * AVX instructions. ++ */ ++struct sys_ctx { ++ uint32_t eax; ++ uint32_t ecx; ++ uint32_t edx; ++ uint32_t ebx; ++ uint32_t esp; ++ uint32_t ebp; ++ ++ uint32_t esi; ++ uint32_t edi; ++}; ++ ++#endif +diff --git a/src/arch/i686/intercept.c b/src/arch/i686/intercept.c +new file mode 100644 +index 0000000..295173f +--- /dev/null ++++ b/src/arch/i686/intercept.c +@@ -0,0 +1,60 @@ ++/* ++ * Copyright 2019, Collabora, Inc. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * get_syscall_in_context -- describe syscall arguments, and syscall number ++ * based on the contents of the relevant registers righ before the syscall ++ * is meant to be executed. On Linux, all syscall arguments are passed to ++ * a syscall in registers. ++ */ ++#include "arch.h" ++#include "intercept.h" ++ ++void ++arch_get_syscall_in_context(struct sys_ctx *sctx, ++ struct syscall_desc *sys) ++{ ++ sys->nr = sctx->eax; ++ ++ sys->args[0] = sctx->ebx; ++ sys->args[1] = sctx->ecx; ++ sys->args[2] = sctx->edx; ++ sys->args[3] = sctx->esi; ++ sys->args[4] = sctx->edi; ++ sys->args[5] = sctx->ebp; ++ ++} ++ ++unsigned long arch_get_syscall_return(struct sys_ctx *ctx) ++{ ++ return ctx->eax; ++} diff --git a/debian/patches/i386/i686-Implement-patching-of-vDSO-syscall-wrapper.patch b/debian/patches/i386/i686-Implement-patching-of-vDSO-syscall-wrapper.patch new file mode 100644 index 0000000000000000000000000000000000000000..fb3064df6fac7ae068791a7536a5454311ce9e06 --- /dev/null +++ b/debian/patches/i386/i686-Implement-patching-of-vDSO-syscall-wrapper.patch @@ -0,0 +1,317 @@ +From: Gabriel Krisman Bertazi +Date: Fri, 10 May 2019 22:02:08 -0400 +Subject: i686: Implement patching of vDSO syscall wrapper + +--- + src/arch.h | 1 + + src/arch/i686/CMakeLists.txt | 3 +- + src/arch/i686/intercept_wrapper.S | 76 +++++++++++++++++++++++++++++++++++++++ + src/arch/i686/parser.c | 9 +++++ + src/arch/i686/util.S | 3 -- + src/arch/x86_64/parser.c | 6 ++++ + src/disasm_wrapper.c | 1 + + src/disasm_wrapper.h | 1 + + src/intercept.h | 4 +++ + src/intercept_desc.c | 13 +++++++ + src/patcher.c | 41 +++++++++++++++++++-- + 11 files changed, 151 insertions(+), 7 deletions(-) + create mode 100644 src/arch/i686/intercept_wrapper.S + +diff --git a/src/arch.h b/src/arch.h +index 0529f85..e677b91 100644 +--- a/src/arch.h ++++ b/src/arch.h +@@ -40,6 +40,7 @@ struct syscall_desc; + struct cs_insn; + + bool arch_insn_is_syscall(struct cs_insn *insn); ++bool arch_insn_is_vsyscall(struct cs_insn *insn); + + unsigned arch_trampoline_entry_size(); + +diff --git a/src/arch/i686/CMakeLists.txt b/src/arch/i686/CMakeLists.txt +index d56dbf4..d3fa46a 100644 +--- a/src/arch/i686/CMakeLists.txt ++++ b/src/arch/i686/CMakeLists.txt +@@ -37,7 +37,8 @@ set(SOURCES_ARCH + intercept.c) + + set(SOURCES_ASM util.S +- intercept_template.S) ++ intercept_template.S ++ intercept_wrapper.S) + + add_library(syscall_intercept_base_arch OBJECT ${SOURCES_ARCH}) + include_directories(syscall_intercept_base_arch ${CMAKE_SOURCE_DIR}/src) +diff --git a/src/arch/i686/intercept_wrapper.S b/src/arch/i686/intercept_wrapper.S +new file mode 100644 +index 0000000..bae32a9 +--- /dev/null ++++ b/src/arch/i686/intercept_wrapper.S +@@ -0,0 +1,76 @@ ++.global intercept_wrapper ++ ++/* intercept_wrapper ++ * ++ * The fast syscall intercept ++ * ++ * %rax - Syscall number ++ * %ebx - syscall argument 1 ++ * %ecx - syscall argument 2 ++ * %edx - syscall argument 3 ++ * %esi - syscall argument 4 ++ * %edi - syscall argument 5 ++ * %ebp - syscall argument 6 ++ * ++ * This is invoked from a call instruction in the fast syscall path or ++ * from a call instructiorn in the wrapper template. Therefore, we can ++ * trust the return address to be on the stack. ++*/ ++intercept_wrapper: ++ push %ebp ++ movl %esp, %ebp ++ push %ebx ++ sub $0x2c, %esp ++ ++ /* Save base registers */ ++ mov %esp, %ebx ++ ++ /* Set patch_desc */ ++ movl $0x0, (%ebx) ++ ++ movl %eax, 4(%ebx) ++ movl %ecx, 8(%ebx) ++ movl %edx, 12(%ebx) ++ ++ movl -4(%ebp), %eax ++ movl %eax, 16(%ebx) /* original ebx */ ++ ++ movl %ebp, %eax ++ addl $4, %eax ++ movl %eax, 20(%ebx) /* original esp */ ++ ++ movl (%ebp), %eax ++ movl %eax, 24(%ebx) /* original ebp */ ++ ++ movl %esi, 28(%ebx) ++ movl %edi, 32(%ebx) ++ ++ mov %ebp, %eax ++ sub $0x8, %eax ++ ++ push %ebx ++ push %eax ++ call intercept_routine ++ mov (%eax), %eax ++ ++ /* callee has already pop'ed the stacked %eax in this case, ++ since the return value is a complex type returned in memory. So ++ esp already points to the real first function argument. Ain't ++ this ABI fun? */ ++ add $4, %esp ++ ++ /* restore registers from struct sys_ctx. ++ * ++ * Notes: esp and ebp are recovered from the stack. ++ */ ++ ++ movl 32(%esp), %edi ++ movl 28(%esp), %esi ++ movl 16(%esp), %ebx ++ movl 12(%esp), %edx ++ movl 8(%esp), %ecx ++ ++ mov %ebp, %esp ++ pop %ebp ++ ret ++ +diff --git a/src/arch/i686/parser.c b/src/arch/i686/parser.c +index 90735f9..f12ef22 100644 +--- a/src/arch/i686/parser.c ++++ b/src/arch/i686/parser.c +@@ -46,3 +46,12 @@ bool arch_insn_is_syscall(struct cs_insn *insn) + return true; + return false; + } ++ ++bool arch_insn_is_vsyscall(struct cs_insn *insn) ++{ ++ if (insn->id == X86_INS_CALL && ++ insn->detail->x86.prefix[1] == 0x65) { ++ return true; ++ } ++ return false; ++} +diff --git a/src/arch/i686/util.S b/src/arch/i686/util.S +index b7ba71c..932b8be 100644 +--- a/src/arch/i686/util.S ++++ b/src/arch/i686/util.S +@@ -1,8 +1,5 @@ +-.globl intercept_wrapper + .globl has_ymm_registers + .globl syscall_no_intercept +-intercept_wrapper: +- .word 0x100 + + has_ymm_registers: + mov $0x0, %eax +diff --git a/src/arch/x86_64/parser.c b/src/arch/x86_64/parser.c +index e9c6c68..e7de1b0 100644 +--- a/src/arch/x86_64/parser.c ++++ b/src/arch/x86_64/parser.c +@@ -43,3 +43,9 @@ unsigned arch_trampoline_entry_size() + { + return 7; + } ++ ++bool arch_insn_is_vsyscall(struct cs_insn *insn) ++{ ++ (void) insn; ++ return false; ++} +diff --git a/src/disasm_wrapper.c b/src/disasm_wrapper.c +index 87ea980..a8cfa8d 100644 +--- a/src/disasm_wrapper.c ++++ b/src/disasm_wrapper.c +@@ -226,6 +226,7 @@ intercept_disasm_next_instruction(struct intercept_disasm_context *context, + assert(result.length != 0); + + result.is_syscall = arch_insn_is_syscall(context->insn); ++ result.is_vsyscall = arch_insn_is_vsyscall(context->insn); + result.is_call = (context->insn->id == X86_INS_CALL); + result.is_ret = (context->insn->id == X86_INS_RET); + result.is_rel_jump = false; +diff --git a/src/disasm_wrapper.h b/src/disasm_wrapper.h +index 93246d1..883a40a 100644 +--- a/src/disasm_wrapper.h ++++ b/src/disasm_wrapper.h +@@ -53,6 +53,7 @@ struct intercept_disasm_result { + bool is_set; + + bool is_syscall; ++ bool is_vsyscall; + + /* Length in bytes, zero if disasm was not successful. */ + unsigned length; +diff --git a/src/intercept.h b/src/intercept.h +index b8c1dbe..ac9c1ef 100644 +--- a/src/intercept.h ++++ b/src/intercept.h +@@ -124,6 +124,8 @@ struct patch_desc { + bool uses_nop_trampoline; + + struct range nop_trampoline; ++ ++ bool vsyscall; + }; + + void patch_apply(struct patch_desc *patch); +@@ -217,8 +219,10 @@ void mprotect_asm_wrappers(void); + void activate_patches(struct intercept_desc *desc); + + #define SYSCALL_INS_SIZE 2 ++#define VSYSCALL_INS_SIZE 7 + #define JUMP_INS_SIZE 5 + #define CALL_OPCODE 0xe8 ++#define CALL_INS_SIZE 5 + #define JMP_OPCODE 0xe9 + #define SHORT_JMP_OPCODE 0xeb + #define PUSH_IMM_OPCODE 0x68 +diff --git a/src/intercept_desc.c b/src/intercept_desc.c +index 11a59e2..e179de5 100644 +--- a/src/intercept_desc.c ++++ b/src/intercept_desc.c +@@ -556,6 +556,19 @@ crawl_text(struct intercept_desc *desc) + assert(syscall_offset >= 0); + + patch->syscall_offset = (unsigned long)syscall_offset; ++ patch->vsyscall = false; ++ } else if (result.is_vsyscall) { ++ struct patch_desc *patch = add_new_patch(desc); ++ ++ patch->containing_lib_path = desc->path; ++ patch->syscall_addr = code; ++ ++ ptrdiff_t syscall_offset = patch->syscall_addr - ++ (desc->text_start - desc->text_offset); ++ ++ assert(syscall_offset >= 0); ++ patch->syscall_offset = (unsigned long)syscall_offset; ++ patch->vsyscall = true; + } + + prevs[0] = prevs[1]; +diff --git a/src/patcher.c b/src/patcher.c +index addf319..42e3a92 100644 +--- a/src/patcher.c ++++ b/src/patcher.c +@@ -160,6 +160,21 @@ create_jump(unsigned char opcode, unsigned char *from, void *to) + from[4] = d[3]; + } + ++void ++create_nop(unsigned char *from, int length) ++{ ++ /* Prefer large nops */ ++ while(length > 1) { ++ from[0] = 0x66; ++ from[1] = 0x90; ++ length -= 2; ++ from += 2; ++ } ++ ++ if (length) ++ from[0] = 0x90; ++} ++ + /* + * check_trampoline_usage - + * Make sure the trampoline table allocated at the beginning of patching has +@@ -364,9 +379,18 @@ create_patch_wrappers(struct intercept_desc *desc) + for (unsigned patch_i = 0; patch_i < desc->count; ++patch_i) { + struct patch_desc *patch = desc->items + patch_i; + +- assign_nop_trampoline(desc, patch, &next_nop_i); ++ if (!patch->vsyscall) ++ assign_nop_trampoline(desc, patch, &next_nop_i); + +- if (patch->uses_nop_trampoline) { ++ if (patch->vsyscall) { ++ patch->uses_prev_ins = false; ++ patch->uses_prev_ins_2 = false; ++ patch->uses_next_ins = false; ++ patch->dst_jmp_patch = patch->syscall_addr; ++ patch->uses_nop_trampoline = false; ++ patch->return_address = ++ patch->syscall_addr + VSYSCALL_INS_SIZE; ++ } else if (patch->uses_nop_trampoline) { + /* + * The preferred option it to use a 5 byte relative + * jump in a padding space between symbols in libc. +@@ -596,6 +620,11 @@ create_wrapper(struct patch_desc *patch) + { + unsigned char *dst; + ++ if (patch->vsyscall) { ++ patch->asm_wrapper = (unsigned char*)&intercept_wrapper; ++ return; ++ } ++ + if (is_asm_wrapper_space_full()) + xabort("not enough space in asm_wrapper_space"); + +@@ -703,7 +732,13 @@ activate_patches(struct intercept_desc *desc) + * it (an overwritable NOP instruction). + */ + +- if (desc->uses_trampoline_table) { ++ if (patch->vsyscall) { ++ create_jump(CALL_OPCODE, ++ patch->dst_jmp_patch, patch->asm_wrapper); ++ create_nop(patch->dst_jmp_patch + CALL_INS_SIZE, ++ VSYSCALL_INS_SIZE - CALL_INS_SIZE); ++ continue; ++ } else if (desc->uses_trampoline_table) { + /* + * First jump to the trampoline table, which + * should be in a 2 gigabyte range. From there, diff --git a/debian/patches/i386/i686-Implement-syscall_no_intercept.patch b/debian/patches/i386/i686-Implement-syscall_no_intercept.patch new file mode 100644 index 0000000000000000000000000000000000000000..e61f1b7c77d6b43f4b98a12ad0c4a985575cb9f5 --- /dev/null +++ b/debian/patches/i386/i686-Implement-syscall_no_intercept.patch @@ -0,0 +1,44 @@ +From: Gabriel Krisman Bertazi +Date: Thu, 25 Apr 2019 15:09:23 -0400 +Subject: i686: Implement syscall_no_intercept + +--- + src/arch/i686/util.S | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/arch/i686/util.S b/src/arch/i686/util.S +index 5c8f6c2..436d87c 100644 +--- a/src/arch/i686/util.S ++++ b/src/arch/i686/util.S +@@ -12,11 +12,30 @@ intercept_asm_wrapper_wrapper_level1_addr: + .word 0x100 + intercept_asm_wrapper_tmpl_end: + intercept_wrapper: +-syscall_no_intercept: + .word 0x100 + + has_ymm_registers: + mov $0x0, %eax + ret + ++syscall_no_intercept: ++ push %ebp ++ movl %esp, %ebp ++ push %edi ++ push %esi ++ push %ebx ++ ++ movl 8(%ebp), %eax ++ movl 12(%ebp), %ebx ++ movl 16(%ebp), %ecx ++ movl 20(%ebp), %edx ++ movl 24(%ebp), %esi ++ movl 28(%ebp), %edi ++ movl 32(%ebp), %ebp ++ int $0x80 + ++ pop %ebx ++ pop %esi ++ pop %edi ++ pop %ebp ++ ret diff --git a/debian/patches/i386/i686-Intercept-int-0x80-system-calls.patch b/debian/patches/i386/i686-Intercept-int-0x80-system-calls.patch new file mode 100644 index 0000000000000000000000000000000000000000..8dc2f365d01fb7cde712d0daa90daf54fe881eec --- /dev/null +++ b/debian/patches/i386/i686-Intercept-int-0x80-system-calls.patch @@ -0,0 +1,134 @@ +From: Gabriel Krisman Bertazi +Date: Wed, 8 May 2019 13:25:25 -0400 +Subject: i686: Intercept int 0x80 system calls + +--- + src/arch/i686/CMakeLists.txt | 9 ++++++-- + src/arch/i686/intercept_template.S | 21 ++++++++++++++++++ + src/arch/i686/parser.c | 45 ++++++++++++++++++++++++++++++++++++++ + src/arch/i686/util.S | 10 --------- + 4 files changed, 73 insertions(+), 12 deletions(-) + create mode 100644 src/arch/i686/intercept_template.S + create mode 100644 src/arch/i686/parser.c + +diff --git a/src/arch/i686/CMakeLists.txt b/src/arch/i686/CMakeLists.txt +index 3360805..93088d4 100644 +--- a/src/arch/i686/CMakeLists.txt ++++ b/src/arch/i686/CMakeLists.txt +@@ -32,10 +32,15 @@ + set(SOURCES_ARCH + syscall_formats.c + intercept_util.c +- symbols.c) ++ symbols.c ++ parser.c) + +-set(SOURCES_ASM util.S) ++set(SOURCES_ASM util.S ++ intercept_template.S) + + add_library(syscall_intercept_base_arch OBJECT ${SOURCES_ARCH}) + include_directories(syscall_intercept_base_arch ${CMAKE_SOURCE_DIR}/src) + add_library(syscall_intercept_base_asm OBJECT ${SOURCES_ASM}) ++ ++set_property(TARGET syscall_intercept_base_arch ++ APPEND PROPERTY COMPILE_FLAGS ${capstone_CFLAGS}) +diff --git a/src/arch/i686/intercept_template.S b/src/arch/i686/intercept_template.S +new file mode 100644 +index 0000000..82bad49 +--- /dev/null ++++ b/src/arch/i686/intercept_template.S +@@ -0,0 +1,21 @@ ++.globl intercept_asm_wrapper_tmpl ++.globl intercept_asm_wrapper_tmpl_end ++.globl intercept_asm_wrapper_wrapper_level1_addr ++.globl intercept_asm_wrapper_patch_desc_addr ++ ++intercept_asm_wrapper_tmpl: ++ mov $4, %eax ++ mov $2, %ebx ++ mov $hello_world, %ecx ++ mov $25, %edx ++ int $0x80 ++infinite: ++ jmp infinite ++intercept_asm_wrapper_patch_desc_addr: ++intercept_asm_wrapper_wrapper_level1_addr: ++ .word 1 ++intercept_asm_wrapper_tmpl_end: ++ ++.data ++hello_world: ++.string "entered wrapper looping\n" +diff --git a/src/arch/i686/parser.c b/src/arch/i686/parser.c +new file mode 100644 +index 0000000..ae1585d +--- /dev/null ++++ b/src/arch/i686/parser.c +@@ -0,0 +1,45 @@ ++/* ++ * Copyright 2018, Intel, Inc. ++ * Copyright 2018, Collabora Ltd. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * * Neither the name of the copyright holder nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "arch.h" ++#include "capstone_wrapper.h" ++ ++bool arch_insn_is_syscall(struct cs_insn *insn) ++{ ++ if (insn->id == X86_INS_INT && ++ insn->detail->x86.operands[0].imm == 0x80) ++ return true; ++ return false; ++} ++ ++ +diff --git a/src/arch/i686/util.S b/src/arch/i686/util.S +index 436d87c..b7ba71c 100644 +--- a/src/arch/i686/util.S ++++ b/src/arch/i686/util.S +@@ -1,16 +1,6 @@ +-.globl intercept_asm_wrapper_tmpl +-.globl intercept_asm_wrapper_tmpl_end +-.globl intercept_asm_wrapper_wrapper_level1_addr +-.globl intercept_asm_wrapper_patch_desc_addr + .globl intercept_wrapper + .globl has_ymm_registers + .globl syscall_no_intercept +-intercept_asm_wrapper_tmpl: +- .word 0x100 +-intercept_asm_wrapper_patch_desc_addr: +-intercept_asm_wrapper_wrapper_level1_addr: +- .word 0x100 +-intercept_asm_wrapper_tmpl_end: + intercept_wrapper: + .word 0x100 + diff --git a/debian/patches/series b/debian/patches/series index dac2988287fa0b346f695db953899e20ed22bc78..e0893e0ffbe5b48d4879396e67d101039ca6318e 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,3 +1,22 @@ +i386/Make-Elf-parsing-types-generic.patch +i386/Fix-casts-for-architectures-with-pointer-smaller-than-64-.patch +i386/Move-syscall_formats-to-arch-specific-directory.patch +i386/Move-assembly-files-to-arch-specific-directory.patch +i386/Fix-error_code-display-on-error.patch +i386/Disable-64bit-specific-build-options-for-32bit-compilatio.patch +i386/Support-i686-compilation.patch +i386/i686-Implement-syscall_no_intercept.patch +i386/i686-Implement-custom-xmmap_anon.patch +i386/Make-address-calculation-during-relocation-arch-specific.patch +i386/Implement-R_386_RELATIVE-relocation-support.patch +i386/Make-syscall-detection-arch-specific.patch +i386/i686-Intercept-int-0x80-system-calls.patch +i386/Support-merging-of-sequential-nops.patch +i386/Disable-trampoline_table-for-i686.patch +i386/Make-syscall-context-specific-to-the-architecture.patch +i386/i686-Implement-get_syscall_in_context.patch +i386/i686-Implement-patching-of-vDSO-syscall-wrapper.patch +i386/Enable-PIC-before-descending-into-src-arch-CMAKE_SYSTEM_P.patch Cope-with-missing-SYS_finit_module-in-older-glibc-kernel-.patch Cope-with-missing-FALLOC_FL_PUNCH_HOLE-in-older-kernel-he.patch Cope-with-missing-SYS_kcmp-in-older-glibc-kernel-headers.patch diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000000000000000000000000000000000000..293e7c2b43dafbded7a0efa2e89948b7adf5996b --- /dev/null +++ b/debian/watch @@ -0,0 +1,5 @@ +version=4 +opts="mode=git,compression=xz,pretty=0~git%cd.%h" \ +https://github.com/pmem/syscall_intercept \ +HEAD \ +debian diff --git a/src/intercept_util.c b/src/intercept_util.c index 559ca5e45e53d7d35ef65bbb7b731cee3f6cfbec..4472e52c246b4809314f899cf39a6d863677e6d0 100644 --- a/src/intercept_util.c +++ b/src/intercept_util.c @@ -502,7 +502,7 @@ static const char *const error_strings[] = { const char * strerror_no_intercept(long errnum) { - static const char unkown[] = "Uknown error"; + static const char unkown[] = "Unknown error"; if (errnum < 0 || (size_t)errnum >= ARRAY_SIZE(error_strings)) return unkown; diff --git a/test/libcintercept0.log.match b/test/libcintercept0.log.match index d9adc50763bd3fb21bc7dd80866d1d53aa6037b1..1191f10e50180e825f976f1fe7acdd7405b1a99b 100644 --- a/test/libcintercept0.log.match +++ b/test/libcintercept0.log.match @@ -2,11 +2,11 @@ $(S) $(XX) -- clone(CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | 0x11, (null), (n $(OPT)$(S) $(XX) -- clone(CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | 0x11, (null), (null), $(XX), $(XX)) = 0 $(S) $(XX) -- clone(CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | 0x11, (null), (null), $(XX), $(XX)) = $(N) $(OPT)$(S) $(XX) -- clone(CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | 0x11, (null), (null), $(XX), $(XX)) = 0 -$(S) $(XX) -- wait4(-1, 0x0, 0x0, 0x0) = ? +$(S) $(XX) -- wait4($(N), 0x0, 0x0, 0x0) = ? $(OPT)$(S) $(XX) -- clone(CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | 0x11, (null), (null), $(XX), $(XX)) = 0 $(OPT)$(S) $(XX) -- set_robust_list($(XX), $(N)) = ? $(OPT)$(S) $(XX) -- set_robust_list($(XX), $(N)) = $(N) -$(S) $(XX) -- wait4(-1, 0x0, 0x0, 0x0) = $(N) +$(S) $(XX) -- wait4($(N), 0x0, 0x0, 0x0) = $(N) $(OPT)$(S) $(XX) -- open($(S), O_RDONLY) = ? $(OPT)$(S) $(XX) -- open($(S), O_RDONLY) = $(N) $(OPT)$(S) $(XX) -- openat(AT_FDCWD, $(S), O_RDONLY) = ? diff --git a/test/syscall_format.c b/test/syscall_format.c index 3ce144d4841ffdf25cb654e937e9c546d0c406ca..8d33be3c2dd243f01c24170053d04710ad79e3ca 100644 --- a/test/syscall_format.c +++ b/test/syscall_format.c @@ -115,7 +115,6 @@ #include #include #include -#include #include #include "libsyscall_intercept_hook_point.h" @@ -240,6 +239,8 @@ main(int argc, char **argv) void *p0 = (void *)0x123000; void *p1 = (void *)0x234000; + void *p2 = (void *)0x456000; + void *p3 = (void *)0x567000; socklen_t sl[2] = {1, 1}; @@ -387,7 +388,7 @@ main(int argc, char **argv) pipe(fd2); pipe2(fd2, 0); - select(2, p0, p1, p1, p0); + select(2, p0, p1, p2, p3); syscall(SYS_pselect6, 2, p0, p1, p0, p1, p0); sched_yield(); @@ -583,7 +584,7 @@ main(int argc, char **argv) mknodat(1, input[0], 1, 2); mknodat(AT_FDCWD, input[0], 1, 2); - ustat(2, p0); + syscall(SYS_ustat, 2, p0); statfs(input[0], p0); fstatfs(4, p0); diff --git a/test/syscall_format.log.match b/test/syscall_format.log.match index 3d8d082754ac2ce9924b5d7e20e1797abf46c345..34fa24b88dc11f3c4f3ff4ebd428a9c29e11188a 100644 --- a/test/syscall_format.log.match +++ b/test/syscall_format.log.match @@ -206,8 +206,8 @@ $(S) $(XX) -- pipe($(XX)) = ? $(S) $(XX) -- pipe([123, 234]) = 22 $(S) $(XX) -- pipe2($(XX), 0) = ? $(S) $(XX) -- pipe2([123, 234], 0) = 22 -$(S) $(XX) -- select(2, 0x0000000000123000, 0x0000000000234000, 0x0000000000234000, 0x0000000000123000) = ? -$(S) $(XX) -- select(2, 0x0000000000123000, 0x0000000000234000, 0x0000000000234000, 0x0000000000123000) = 22 +$(S) $(XX) -- select(2, 0x0000000000123000, 0x0000000000234000, 0x0000000000456000, 0x0000000000567000) = ? +$(S) $(XX) -- select(2, 0x0000000000123000, 0x0000000000234000, 0x0000000000456000, 0x0000000000567000) = 22 $(S) $(XX) -- pselect6(0x2, 0x123000, 0x234000, 0x123000, 0x234000, 0x123000) = ? $(S) $(XX) -- pselect6(0x2, 0x123000, 0x234000, 0x123000, 0x234000, 0x123000) = 22 $(S) $(XX) -- sched_yield() = ?