summaryrefslogtreecommitdiff
path: root/src/closures.c
Commit message (Collapse)AuthorAgeFilesLines
* Add static trampoline support for CygwinAnthony Green2022-09-121-2/+2
|
* dlmmap fix and always check for PaX MPROTECT on linuxAnthony Green2022-09-061-35/+54
| | | | | | Also make EMUTRAMP experimental From Stefan Bühler https://github.com/libffi/libffi/pull/282
* Ensure that VM_PROT_EXECUTE is set on the trampoline page. (#718)Russell Keith-Magee2022-06-021-2/+14
|
* arm64e: Pull in pointer authentication code from Apple's arm64e libffi port ↵Jeremy Huddleston Sequoia2021-03-241-7/+11
| | | | | | | | (#565) NOTES: This changes the ptrauth support from #548 to match what Apple is shipping in its libffi-27 tag. Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
* Search $LIBFFI_TMPDIR also (#605)DJ Delorie2021-03-231-0/+1
| | | | | | | Most temp file directories need to be hardened against execution, but libffi needs execute privileges. Add a libffi-specific temp directory that can be set up by sysadmins as needed with suitable permissions. This both ensures that libffi will have a valid temp directory to use as well as preventing attempts to access other directories.
* Static tramp v5 (#624)Madhavan T. Venkataraman2021-03-051-2/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Static Trampolines Closure Trampoline Security Issue ================================= Currently, the trampoline code used in libffi is not statically defined in a source file (except for MACH). The trampoline is either pre-defined machine code in a data buffer. Or, it is generated at runtime. In order to execute a trampoline, it needs to be placed in a page with executable permissions. Executable data pages are attack surfaces for attackers who may try to inject their own code into the page and contrive to have it executed. The security settings in a system may prevent various tricks used in user land to write code into a page and to have it executed somehow. On such systems, libffi trampolines would not be able to run. Static Trampoline ================= To solve this problem, the trampoline code needs to be defined statically in a source file, compiled and placed in the text segment so it can be mapped and executed naturally without any tricks. However, the trampoline needs to be able to access the closure pointer at runtime. PC-relative data referencing ============================ The solution implemented in this patch set uses PC-relative data references. The trampoline is mapped in a code page. Adjacent to the code page, a data page is mapped that contains the parameters of the trampoline: - the closure pointer - pointer to the ABI handler to jump to The trampoline code uses an offset relative to its current PC to access its data. Some architectures support PC-relative data references in the ISA itself. E.g., X64 supports RIP-relative references. For others, the PC has to somehow be loaded into a general purpose register to do PC-relative data referencing. To do this, we need to define a get_pc() kind of function and call it to load the PC in a desired register. There are two cases: 1. The call instruction pushes the return address on the stack. In this case, get_pc() will extract the return address from the stack and load it in the desired register and return. 2. The call instruction stores the return address in a designated register. In this case, get_pc() will copy the return address to the desired register and return. Either way, the PC next to the call instruction is obtained. Scratch register ================ In order to do its job, the trampoline code would need to use a scratch register. Depending on the ABI, there may not be a register available for scratch. This problem needs to be solved so that all ABIs will work. The trampoline will save two values on the stack: - the closure pointer - the original value of the scratch register This is what the stack will look like: sp before trampoline ------> -------------------- | closure pointer | -------------------- | scratch register | sp after trampoline -------> -------------------- The ABI handler can do the following as needed by the ABI: - the closure pointer can be loaded in a desired register - the scratch register can be restored to its original value - the stack pointer can be restored to its original value (the value when the trampoline was invoked) To do this, I have defined prolog code for each ABI handler. The legacy trampoline jumps to the ABI handler directly. But the static trampoline defined in this patch jumps tp the prolog code which performs the above actions before jumping to the ABI handler. Trampoline Table ================ In order to reduce the trampoline memory footprint, the trampoline code would be defined as a code array in the text segment. This array would be mapped into the address space of the caller. The mapping would, therefore, contain a trampoline table. Adjacent to the trampoline table mapping, there will be a data mapping that contains a parameter table, one parameter block for each trampoline. The parameter block will contain: - a pointer to the closure - a pointer to the ABI handler The static trampoline code would finally look like this: - Make space on the stack for the closure and the scratch register by moving the stack pointer down - Store the original value of the scratch register on the stack - Using PC-relative reference, get the closure pointer - Store the closure pointer on the stack - Using PC-relative reference, get the ABI handler pointer - Jump to the ABI handler Mapping size ============ The size of the code mapping that contains the trampoline table needs to be determined on a per architecture basis. If a particular architecture supports multiple base page sizes, then the largest supported base page size needs to be chosen. E.g., we choose 16K for ARM64. Trampoline allocation and free ============================== Static trampolines are allocated in ffi_closure_alloc() and freed in ffi_closure_free(). Normally, applications use these functions. But there are some cases out there where the user of libffi allocates and manages its own closure memory. In such cases, static trampolines cannot be used. These will fall back to using legacy trampolines. The user has to make sure that the memory is executable. ffi_closure structure ===================== I did not want to make any changes to the size of the closure structure for this feature to guarantee compatibility. But the opaque static trampoline handle needs to be stored in the closure. I have defined it as follows: - char tramp[FFI_TRAMPOLINE_SIZE]; + union { + char tramp[FFI_TRAMPOLINE_SIZE]; + void *ftramp; + }; If static trampolines are used, then tramp[] is not needed to store a dynamic trampoline. That space can be reused to store the handle. Hence, the union. Architecture Support ==================== Support has been added for x64, i386, aarch64 and arm. Support for other architectures can be added very easily in the future. OS Support ========== Support has been added for Linux. Support for other OSes can be added very easily. Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com> * x86: Support for Static Trampolines - Define the arch-specific initialization function ffi_tramp_arch () that returns trampoline size information to common code. - Define the trampoline code mapping and data mapping sizes. - Define the trampoline code table statically. Define two tables, actually, one with CET and one without. - Introduce a tiny prolog for each ABI handling function. The ABI handlers addressed are: - ffi_closure_unix64 - ffi_closure_unix64_sse - ffi_closure_win64 The prolog functions are called: - ffi_closure_unix64_alt - ffi_closure_unix64_sse_alt - ffi_closure_win64_alt The legacy trampoline jumps to the ABI handler. The static trampoline jumps to the prolog function. The prolog function uses the information provided by the static trampoline, sets things up for the ABI handler and then jumps to the ABI handler. - Call ffi_tramp_set_parms () in ffi_prep_closure_loc () to initialize static trampoline parameters. Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com> * i386: Support for Static Trampolines - Define the arch-specific initialization function ffi_tramp_arch () that returns trampoline size information to common code. - Define the trampoline code table statically. Define two tables, actually, one with CET and one without. - Define the trampoline code table statically. - Introduce a tiny prolog for each ABI handling function. The ABI handlers addressed are: - ffi_closure_i386 - ffi_closure_STDCALL - ffi_closure_REGISTER The prolog functions are called: - ffi_closure_i386_alt - ffi_closure_STDCALL_alt - ffi_closure_REGISTER_alt The legacy trampoline jumps to the ABI handler. The static trampoline jumps to the prolog function. The prolog function uses the information provided by the static trampoline, sets things up for the ABI handler and then jumps to the ABI handler. - Call ffi_tramp_set_parms () in ffi_prep_closure_loc () to initialize static trampoline parameters. Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com> * arm64: Support for Static Trampolines - Define the arch-specific initialization function ffi_tramp_arch () that returns trampoline size information to common code. - Define the trampoline code mapping and data mapping sizes. - Define the trampoline code table statically. - Introduce a tiny prolog for each ABI handling function. The ABI handlers addressed are: - ffi_closure_SYSV - ffi_closure_SYSV_V The prolog functions are called: - ffi_closure_SYSV_alt - ffi_closure_SYSV_V_alt The legacy trampoline jumps to the ABI handler. The static trampoline jumps to the prolog function. The prolog function uses the information provided by the static trampoline, sets things up for the ABI handler and then jumps to the ABI handler. - Call ffi_tramp_set_parms () in ffi_prep_closure_loc () to initialize static trampoline parameters. Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com> * arm: Support for Static Trampolines - Define the arch-specific initialization function ffi_tramp_arch () that returns trampoline size information to common code. - Define the trampoline code mapping and data mapping sizes. - Define the trampoline code table statically. - Introduce a tiny prolog for each ABI handling function. The ABI handlers addressed are: - ffi_closure_SYSV - ffi_closure_VFP The prolog functions are called: - ffi_closure_SYSV_alt - ffi_closure_VFP_alt The legacy trampoline jumps to the ABI handler. The static trampoline jumps to the prolog function. The prolog function uses the information provided by the static trampoline, sets things up for the ABI handler and then jumps to the ABI handler. - Call ffi_tramp_set_parms () in ffi_prep_closure_loc () to initialize static trampoline parameters. Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com>
* Use memfd_create() (#604)DJ Delorie2020-12-021-0/+17
| | | | | memfd_create creates a file in a memory-only filesystem that may bypass strict security protocols in filesystem-based temporary files.
* Fix building for aarch64 windows with mingw toolchains (#555)Martin Storsjö2020-04-251-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | * aarch64: Check _WIN32 instead of _M_ARM64 for detecting windows This fixes building for aarch64 with mingw toolchains. _M_ARM64 is predefined by MSVC, while mingw compilers predefine __aarch64__. In aarch64 specific code, change checks for _M_ARM64 into checks for _WIN32. In arch independent code, check for (defined(_M_ARM64) || defined(__aarch64__)) && defined(_WIN32) instead of just _M_ARM64. In src/closures.c, coalesce checks like defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) into plain defined(_WIN32). Technically, this enables code for ARM32 windows where it wasn't, but as far as I can see it, those codepaths should be fine for that architecture variant as well. * aarch64: Only use armasm source when building with MSVC When building for windows/arm64 with clang, the normal gas style .S source works fine. sysv.S and win64_armasm.S seem to be functionally equivalent, with only differences being due to assembler syntax.
* Port to iOS/arm64e (#548)Ole André Vadla Ravnås2020-03-091-0/+6
|
* Revamp PA_LINUX and PA_HPUX target closures to use function descriptors.Moxie Bot2020-02-241-4/+4
| | | | | | | | | | | | | | | | | | | | 2020-02-23 John David Anglin <danglin@gcc.gnu.org> * include/ffi.h.in (FFI_CLOSURE_PTR, FFI_RESTORE_PTR): Define. * src/closures.c (ffi_closure_alloc): Convert closure pointer return by malloc to function pointer. (ffi_closure_free): Convert function pointer back to malloc pointer. * src/pa/ffi.c (ffi_closure_inner_pa32): Use union to double word align return address on stack. Adjust statements referencing return address. Convert closure argument from function pointer to standard closure pointer. (ffi_prep_closure_loc): Likewise convert closure argument back to closure pointer. Remove assembler trampolines. Setup simulated function descriptor as on ia64. src/pa/ffitarget.h (FFI_TRAMPOLINE_SIZE): Reduce to 12. src/pa/hpux32.S (ffi_closure_pa32): Retrieve closure pointer and real gp from fake gp value in register %r19. src/pa/linux.S (ffi_closure_pa32): Likewise.
* Add work-around for users who manage their own closure memoryAnthony Green2019-11-201-2/+10
| | | | As suggested by DJ
* handle compilation warnings with ftruncate API (#508)pnallan2019-10-081-2/+13
| | | | | | | | * fix me: avoid warning while handle ftruncate API Signed-off-by: Prasad Nallani <prasad.nallani@intel.com> * Update closures.c
* libffi: added ARM64 support for Windows (#486)ossdev072019-06-251-5/+5
| | | | | | | | | | | | | | | | | | * libffi: added ARM64 support for Windows 1. ported sysv.S to win64_armasm.S for armasm64 assembler 2. added msvc_build folder for visual studio solution 3. updated README.md for the same 4. MSVC solution created with the changes, and below test suites are tested with test script written in python. libffi.bhaible libffi.call 5. Basic functionality of above test suites are getting passed Signed-off-by: ossdev07 <ossdev@puresoftware.com> * Update README.md
* Cleanup symbol exports on darwin and add architecture preprocessor checks to ↵Jeremy Huddleston Sequoia2019-02-191-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | assist in building fat binaries (eg: i386+x86_64 on macOS or arm+aarch64 on iOS) (#450) * x86: Ensure _efi64 suffixed symbols are not exported * x86: Ensure we do not export ffi_prep_cif_machdep Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com> * x86: Ensure we don't export ffi_call_win64, ffi_closure_win64, or ffi_go_closure_win64 Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com> * closures: Silence a semantic warning libffi/src/closures.c:175:23: This function declaration is not a prototype Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com> * aarch64: Ensure we don't export ffi_prep_cif_machdep Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com> * arm: Ensure we don't export ffi_prep_cif_machdep Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com> * aarch64, arm, x86: Add architecture preprocessor checks to support easier fat builds (eg: iOS) Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com> * x86: Silence some static analysis warnings libffi/src/x86/ffi64.c:286:21: The left operand of '!=' is a garbage value due to array index out of bounds libffi/src/x86/ffi64.c:297:22: The left operand of '!=' is a garbage value due to array index out of bounds Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com> * aarch: Use FFI_HIDDEN rather than .hidden Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com> * ffi.h: Don't advertise ffi_java_rvalue_to_raw, ffi_prep_java_raw_closure, and ffi_prep_java_raw_closure_loc when FFI_NATIVE_RAW_API is 0 Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
* aarch64: Flush code mapping in addition to data mapping (#471)Florian Weimer2019-02-191-0/+13
| | | | | | This needs a new function, ffi_data_to_code_pointer, to translate from data pointers to code pointers. Fixes issue #470.
* Fully allocate file backing writable maps (#389)Ryan C. Underwood2018-03-181-1/+31
| | | | | | | When ftruncate() is used on a filesystem supporting sparse files, space in the file is not actually allocated. Then, when the file is mmap'd and libffi writes to the mapping, SIGBUS is thrown to the calling application. Instead, always fully allocate the file that will back writable maps.
* Merge pull request #320 from 0-wiz-0/masterAnthony Green2017-11-031-0/+78
|\ | | | | Support NetBSD with mprotect.
| * Support NetBSD with mprotect.Joerg Sonnenberger2017-10-021-0/+78
| | | | | | | | Signed-off-by: Thomas Klausner <wiz@NetBSD.org>
* | Merge branch 'master' based on ksjogo/libffiJean-Luc Jumpertz2017-10-231-1/+1
|\ \ | |/ |/| | | | | | | | | | | | | Added a tvOS target in Xcode project. Misc Xcode project cleanup. Fix macOS build target in Xcode project. # Conflicts: # src/aarch64/ffi.c # src/x86/ffi64.c
| * Fix macOS build target in Xcode project.Jean-Luc Jumpertz2017-09-041-1/+1
| | | | | | | | | | | | - Add missing files for desktop platforms in generate-darwin-source-and-headers.py, and in the Xcode project. - Add a static library target for macOS. - Fix "implicit conversion loses integer precision" warnings for iOS mad macOS targets.
* | Fix #265Anthony Green2017-09-271-1/+1
|/
* Simplify iOS trampoline table allocationOle André Vadla Ravnås2017-03-301-95/+63
| | | | | | By using VM_FLAGS_OVERWRITE there is no need for speculatively allocating on a page we just deallocated. This approach eliminates the race-condition and gets rid of the retry logic.
* Fix error path so mutex is unlocked before returningOle André Vadla Ravnås2017-03-151-0/+1
| | | | In the unusual case where ffi_trampoline_table_alloc() fails.
* Remove unused FFI_CLOSURE_TESTBerker Peksag2016-05-191-36/+0
| | | | | | It was here since the first commit c6dddbd (warning: huge diff) and it wasn't defined by the configure script. It was probably used manually during development.
* Fix usage on musl libcKylie McClain2016-04-291-1/+1
| | | | | | | | | A gcc compiled on musl does not define __gnu_linux__, it defines __linux__. Only on glibc does __gnu_linux__ get defined, but both define __linux__, so we should check for that instead. With this patch, libffi works perfectly, and passes its testsuite entirely on musl libc systems.
* Fixed #181 -- Corrected problems with ARMv7 build under iOS.Russell Keith-Magee2015-12-211-2/+239
| | | | | Based on a patch from @fealebenpae, with input from @SolaWing and @rth7680, and testing from @superdump.
* Remove compiler warningAnthony Green2014-06-121-1/+4
|
* closures: Check for mkostemp(3)Mickaël Salaün2014-05-191-1/+7
|
* closures: Create temporary file with O_TMPFILE and O_CLOEXEC when availableMickaël Salaün2014-05-191-5/+24
| | | | | | | | | | | | | | | | | The open_temp_exec_file_dir function can create a temporary file without file system accessible link. If the O_TMPFILE flag is not defined (old Linux kernel or libc) the behavior is unchanged. The open_temp_exec_file_name function now need a new argument "flags" (like O_CLOEXEC) used for temporary file creation. The O_TMPFILE flag allow temporary file creation without race condition. This feature/fix prevent another process to access the (future) executable file from the file system. The O_CLOEXEC flag automatically close the temporary file for any execve. This avoid transmitting (executable) file descriptor to a child process.
* Check /proc/self/status for PaX status.Magnus Granberg2014-05-111-3/+19
|
* Merge pull request #46 from makotokato/android-clangAnthony Green2014-02-281-1/+1
|\ | | | | | | Fix build failure when using clang for Android
| * Fix build failure when using clang for AndroidMakoto Kato2013-07-101-1/+1
| | | | | | | | clang for Android generates __gnu_linux__ define, but gcc for Android doesn't. So we should add check it for Android
* | Darwin/x86_64: Fix 64-bit type shortening warningsZachary Waldowski2014-02-051-1/+1
| |
* | Undo iOS ARM64 changes.Anthony Green2013-12-051-1/+1
| |
* | Darwin: Misc size_t warningsZachary Waldowski2013-11-301-1/+1
| |
* | Fix spelling errorsAnthony Green2013-10-081-1/+1
|/
* cygwin fix & updates for 3.0.13Anthony Green2013-03-171-2/+4
|
* Add PaX work-aroundAnthony Green2012-10-301-0/+27
|
* Fix kfreebsdAnthony Green2011-11-121-1/+1
|
* Fix ax_enable_builddir macro on BSD systemsAnthony Green2011-11-121-1/+1
|
* Many new patchesAnthony Green2011-08-221-1/+1
|
* Add Interix supportAnthony Green2011-02-091-4/+4
|
* Add ChangeLog entry. Fix copyright headers.Anthony Green2011-02-091-2/+3
|
* Add iOS supportAnthony Green2011-02-081-2/+6
|\
| * Implement FFI_EXEC_TRAMPOLINE_TABLE allocator for iOS/ARM.Landon Fuller2010-09-191-79/+1
| | | | | | | | | | | | This provides working closure support on iOS/ARM devices where PROT_WRITE|PROT_EXEC is not permitted. The code passes basic smoke tests, but requires further review.
| * Add a hard-coded FFI_EXEC_TRAMPOLINE_TABLE arm implementation.Landon Fuller2010-09-191-2/+84
| | | | | | | | | | | | | | | | | | | | | | This implements support for re-mapping a shared table of executable trampolines directly in front of a writable configuration page, working around PROT_WRITE restrictions for sandboxed applications on Apple's iOS. This implementation is for testing purposes; a proper allocator is still necessary, and ARM-specific code needs to be moved out of src/closures.c.
* | Refresh from GCCAnthony Green2011-02-081-1/+1
| |
* | RebaseAnthony Green2010-11-211-1/+1
|/
* Fix selinux testAnthony Green2010-07-101-1/+1
|
* Remove warnings and add OS/2 supportAnthony Green2010-04-131-5/+5
|