In first phase, I want to implement the Intel SMAP (Supervisor Mode Access Prevention) technology for x86-64 architecture. In second phase, I plan to implement boot/load time kernel and kernel module patching framework.
Intel SMAP is a hardware extension to support advanced kernel self-protection. The SMAP technology will prevent unintended data access from kernel to userland memory. The technology will appear in Intel Broadwell architecture in 2014Q2/Q3. Currently there is an emulator - namely Qemu with TCG - which supports this technology.
Runtime kernel/kernel module patching is required, otherwise the processor will fail when processing unknown instruction. Newer processors introducing newer instructions which didn't exist on older one. To solve this situation this framework makes the kernel and kernel modules self-modifiable in common way.
phase #1: - Improved security of FreeBSD kernel in future x86-64 processors
phase #2: - generic framework for boot-time/runtime kernel image and kernel modules patching - elliminate hackish “manual” instruction patching: http://svnweb.freebsd.org/base/head/sys/amd64/amd64/cpu_switch.S?r1=238450&r2=238449&pathrev=238450
phase #1:
| 1.1 | May 19 - May 25 | update Intel SMAP knowledege | DONE |
| 1.2 | May 26 - June 8 | update relevant FreeBSD kernel knowledge | DONE |
| 1.3 | June 9 - June 15 | implement/refine trap handler and add/refine required code to relevant parts of kernel | DONE |
| 1.4 | June 16 - June 22 | test and fix | DONE |
phase #2:
| 2.1 | June 23 - June 29 | identify the required places to modify in booting process and kernel module loading process | DONE |
| 2.2 | June 30 - July 6 | design the kernel patching framework | DONE |
| 2.3 | July 7 - July 20 | implement the kernel patching framework | DONE |
| 2.4 | July 21 - July 27 | adapt XSAVE and SMAP instructions to new framework | DONE |
| 2.5 | July 27 - August 3 | optimize implementation | DONE |
| 2.6 | August 3 - EoC August 14 | test, test, fix, test | DONE |
phase #1 - SMAP:
| create a VM image | http://svnweb.freebsd.org/socsvn/soc2014/op/tools/create_smap_test_vm.csh?view=log | DONE |
| write vulnerable kernel module and PoC, and test | http://svnweb.freebsd.org/socsvn/soc2014/op/tests/smap-tester/ | DONE |
| test in qemu with SMAP emulation | http://svnweb.freebsd.org/socsvn/soc2014/op/tools/run_smap_test_vm.csh?view=log | DONE |
phase #2 - kernel patching:
| create a VM image | DONE | |
| boot test in qemu | DONE | |
| kernel module test in qemu | DONE | |
| test in qemu with enabled SMAP | DONE | |
| test on real hardware with XSAVE/XSAVEOPT | DONE | |
| stress test | DONE |
https://svnweb.freebsd.org/socsvn/soc2014/op/
https://github.com/opntr/opBSD/tree/op/gsoc2014/master
https://github.com/opntr/opBSD/tree/op/gsoc2014/smap
http://forums.grsecurity.net/viewtopic.php?f=7&t=3046
https://lwn.net/Articles/517475/
http://www.freebsd.org/doc/en_US.ISO8859-1/articles/committers-guide/subversion-primer.html
https://software.intel.com/sites/default/files/managed/68/8b/319433-019.pdf
http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/24592_APM_v11.pdf
http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/24593_APM_v21.pdf
http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2008/10/24594_APM_v3.pdf
http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/26568_APM_v41.pdf
http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/26569_APM_v51.pdf
http://tigcc.ticalc.org/doc/gnuasm.html#SEC109
http://llvm.org/docs/doxygen/html/AsmParser_8cpp_source.html
http://clang.llvm.org/compatibility.html
http://www.ibm.com/developerworks/aix/library/au-gdb.html
https://sourceware.org/binutils/docs/ld/Scripts.html#Scripts
319433-019.pdf : 10.3; table 2-5; page 887; page 894
CPUID.(EAX=07H,ECX=0H):EBX.SMAP[bit 20] = 1
stac:
STAC sets the AC flag bit in EFLAGS/RFLAGS without affecting other bits. Attempt to execute STAC when CPL > 0 will cause #UD. This instruction's operation is the same in non-64-bit modes and 64-bit mode.
clac:
CLAC clears the AC flag bit in EFLAGS/RFLAGS without affecting other bits. Attempt to execute CLAC when CPL > 0 will cause #UD. This instruction's operation is the same in on-64-bit modes and 64-bit mode.
EFLAGS.AC
“System software enables SMAP by setting the SMAP flag in control register CR4 (bit 21).”
| clang SMAP support | YES | https://github.com/freebsd/freebsd/commit/aa45f148926e3461a1fd8b10c990f0a51a908cc9 | dim@ |
| gcc SMAP support | YES | https://github.com/freebsd/freebsd/commit/72b58728c7463667c6eb881e2f8a0c6d98e8c661 | pfg@ |
| ddb SMAP support | YES | https://github.com/freebsd/freebsd/commit/0fa3283d5a6ef0a3095fd7dd71bf4cea8ecd83ee | jhb@ |
“If CPL < 3, SMAP protections are disabled if EFLAGS.AC = 1. If CPL = 3, SMAP applies to all supervisor-mode data accesses (these are implicit supervisor accesses) regardless of the value of EFLAGS.AC.” - Intel Ref. # 319433-014 9.3.2
BOOL
check_smap_access_violation(FRAME, USERMODE)
{
if SMAP_DISABLED :
RETURN FALSE;
if CPL == 3 OR RFLAGS@FRAME BITAND EFLAGS.AC :
RETURN FALSE;
RETURN TRUE;
}
| linker script | sys/conf/ldscript.amd64 |
| elf linker | sys/kern/kern_linker.c |
| sys/kern/link_elf.c | |
| sys/sys/linker.h | |
| nop tables | XXX |
| kernel image patching | sys/amd64/amd64/machdep.c |
| files, which containes stac, clac or xsave | sys/amd64/amd64/support.S |
| sys/amd64/include/asmacros.h | |
| sys/amd64/include/cpufunc.h | |
| sys/amd64/ia32/ia32_exception.S | |
| amd64/amd64/cpu_switch.S |
typedef struct lf_selfpatch {
void *patchable; /* address of patchable instractions */
void *patch; /* address of patch */
short feature_selector;
int feature;
char *comment;
} lf_selfpatch_t;
→ hammer_time
→ lf_selfpatch(linker_kernel_file)
→ modload
→ lf_selfpatch(linker_module_file)
→ onload
→ lf_patch(linker_module_file, linker_destination_file)
→ smp_rendezvous_cpu(NULL, lf_selfpatch(foo), NULL, arg)
| svn-cherry-pick-from-git.csh | http://svnweb.freebsd.org/socsvn/soc2014/op/tools/svn-cherry-pick-from-git.csh?view=log |
| build_kernel_32bit.csh | http://svnweb.freebsd.org/socsvn/soc2014/op/tools/build_kernel_32bit.csh?view=log |
| build_kernel_64bit.csh | http://svnweb.freebsd.org/socsvn/soc2014/op/tools/build_kernel_64bit.csh?view=log |
| create_smap_test_vm.csh | http://svnweb.freebsd.org/socsvn/soc2014/op/tools/create_smap_test_vm.csh?view=log |
| run_smap_test_vm.csh | http://svnweb.freebsd.org/socsvn/soc2014/op/tools/run_smap_test_vm.csh?view=log |