SafeFetch is a patch that provides a caching mechanism to user syscalls to prevent time-of-check to time-of-use bugs in the kernel. SafeFetch was originally created by Victor Duta, Mitchel Josephus Aloserij, and Cristiano Giuffrida. Their original research publication and appendix can be found here [1]. Their patch for v5.11 can be found here [2]. The testing scripts can be found here [3].
This patchset is not currently intended for production but rather for use in testing. I have been forward porting this patchset for about one year now, from v5.11 to v6.16-rc6. I branched and merged in my own fork the kernel to keep track of my progress [4]. I have been able to test the patchset with the same CVE used by the original paper authors for each new version I ported the patchset to confirm its functionality. I have not tested the performance of the patchset in different versions in order to verify the original claims of minimal overheads. I have done limited testing with different compiler versions to confirm it can compile across clang and gcc versions. I have not tested recommended kernel configuration variations. I would love some help testing this patchset more rigorously in addition to cleaning up any checkpatch warnings or errors that I was unsure of. Specifically I was hesitant to try to fix macro warnings as some seemed wrong to me in my limited knowledge. I also need help fixing up or formatting the dmesg output to be more consistent with other messages. [1] https://www.usenix.org/conference/usenixsecurity24/presentation/duta [2] https://github.com/vusec/safefetch [3] https://github.com/vusec/safefetch-ae [4] https://github.com/gatlinnewhouse/linux Gatlin Newhouse (17): Add SafeFetch double-fetch protection to the kernel x86: syscall: support caching in do_syscall_64() x86: asm: support caching in do_get_user_call() sched: add protection to task_struct uaccess: add non-caching copy_from_user functions futex: add get_user_no_dfcache() functions gup: add non-caching get_user call to fault_in_readable() init: add caching startup and initialization to start_kernel() exit: add destruction of SafeFetch caches and debug info to do_exit() iov_iter: add SafeFetch pinning call to copy_from_user_iter() kernel: add SafeFetch cache handling to dup_task_struct() bug: add SafeFetch statistics tracking to __report_bug() calls softirq: add SafeFetch statistics to irq_enter_rc() and irq_exit() makefile: add SafeFetch support to makefiles kconfig: debug: add SafeFetch to debug kconfig x86: enable SafeFetch on x86_64 builds vfs: ioctl: add logging to ioctl_file_dedupe_range() for testing Makefile | 3 +- arch/x86/Kconfig | 5 +- arch/x86/entry/syscall_64.c | 76 + arch/x86/include/asm/uaccess.h | 211 ++- arch/x86/include/asm/uaccess_64.h | 54 + fs/ioctl.c | 6 + include/linux/dfcache_measuring.h | 72 + include/linux/mem_range.h | 302 ++++ include/linux/region_allocator.h | 188 +++ include/linux/safefetch.h | 222 +++ include/linux/safefetch_static_keys.h | 22 + include/linux/sched.h | 11 + include/linux/uaccess.h | 30 + init/Kconfig | 2 +- init/init_task.c | 11 + init/main.c | 7 + kernel/exit.c | 16 + kernel/fork.c | 17 + kernel/futex/core.c | 5 + kernel/futex/futex.h | 4 + kernel/futex/pi.c | 5 + kernel/futex/requeue.c | 5 +- kernel/futex/waitwake.c | 4 + kernel/softirq.c | 8 + lib/Kconfig.debug | 1 + lib/Kconfig.safefetch | 36 + lib/bug.c | 10 + lib/iov_iter.c | 12 + mm/Makefile | 1 + mm/gup.c | 4 + mm/safefetch/Makefile | 11 + mm/safefetch/mem_range.c | 1882 +++++++++++++++++++++++++ mm/safefetch/page_cache.c | 129 ++ mm/safefetch/page_cache.h | 141 ++ mm/safefetch/region_allocator.c | 584 ++++++++ mm/safefetch/safefetch.c | 487 +++++++ mm/safefetch/safefetch_debug.c | 110 ++ mm/safefetch/safefetch_debug.h | 86 ++ mm/safefetch/safefetch_static_keys.c | 299 ++++ scripts/Makefile.lib | 4 + scripts/Makefile.safefetch | 10 + 41 files changed, 5077 insertions(+), 16 deletions(-) create mode 100644 include/linux/dfcache_measuring.h create mode 100644 include/linux/mem_range.h create mode 100644 include/linux/region_allocator.h create mode 100644 include/linux/safefetch.h create mode 100644 include/linux/safefetch_static_keys.h create mode 100644 lib/Kconfig.safefetch create mode 100644 mm/safefetch/Makefile create mode 100644 mm/safefetch/mem_range.c create mode 100644 mm/safefetch/page_cache.c create mode 100644 mm/safefetch/page_cache.h create mode 100644 mm/safefetch/region_allocator.c create mode 100644 mm/safefetch/safefetch.c create mode 100644 mm/safefetch/safefetch_debug.c create mode 100644 mm/safefetch/safefetch_debug.h create mode 100644 mm/safefetch/safefetch_static_keys.c create mode 100644 scripts/Makefile.safefetch -- 2.25.1