1# Avoiding a problem with the SYSRET instruction 2 3On x86-64, the kernel uses the SYSRET instruction to return from system 4calls. We must be careful not to use a non-canonical return address with 5SYSRET, at least on Intel CPUs, because this causes the SYSRET instruction 6to fault in kernel mode, which is potentially unsafe. (In contrast, on AMD 7CPUs, SYSRET faults in user mode when used with a non-canonical return 8address.) 9 10Usually, the lowest non-negative non-canonical address is 0x0000800000000000 11(== 1 << 47). One way that a user process could cause the syscall return 12address to be non-canonical is by mapping a 4k executable page immediately 13below that address (at 0x00007ffffffff000), putting a SYSCALL instruction 14at the end of that page, and executing the SYSCALL instruction. 15 16To avoid this problem: 17 18* We disallow mapping a page when the virtual address of the following page 19 will be non-canonical. 20 21* We disallow setting the RIP register to a non-canonical address using 22 **zx_thread_write_state**() when the address would be used with SYSRET. 23 24For more background, see "A Stitch In Time Saves Nine: A Case Of Multiple 25OS Vulnerability", Rafal Wojtczuk 26(https://media.blackhat.com/bh-us-12/Briefings/Wojtczuk/BH_US_12_Wojtczuk_A_Stitch_In_Time_WP.pdf). 27