Skip to content

Commit 6ba2dbf

Browse files
committed
2873 sysretq doesn't properly handle non-canonical addresses
Reviewed by: Bryan Cantrill <bryan@joyent.com> Reviewed by: Keith Wesolowski <keith.wesolowski@joyent.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Dan McDonald <danmcd@nexenta.com> Approved by: Richard Lowe <richlowe@richlowe.net>
1 parent 3ddcfad commit 6ba2dbf

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

usr/src/uts/i86pc/ml/syscall_asm_amd64.s

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23+
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
2324
*/
2425

2526
#include <sys/asm_linkage.h>
@@ -565,6 +566,33 @@ _syscall_invoke:
565566
CLI(%r14)
566567
CHECK_POSTSYS_NE(%r15, %r14, %ebx)
567568
jne _syscall_post
569+
570+
/*
571+
* We need to protect ourselves against non-canonical return values
572+
* because Intel doesn't check for them on sysret (AMD does). Canonical
573+
* addresses on current amd64 processors only use 48-bits for VAs; an
574+
* address is canonical if all upper bits (47-63) are identical. If we
575+
* find a non-canonical %rip, we opt to go through the full
576+
* _syscall_post path which takes us into an iretq which is not
577+
* susceptible to the same problems sysret is.
578+
*
579+
* We're checking for a canonical address by first doing an arithmetic
580+
* shift. This will fill in the remaining bits with the value of bit 63.
581+
* If the address were canonical, the register would now have either all
582+
* zeroes or all ones in it. Therefore we add one (inducing overflow)
583+
* and compare against 1. A canonical address will either be zero or one
584+
* at this point, hence the use of ja.
585+
*
586+
* At this point, r12 and r13 have the return value so we can't use
587+
* those registers.
588+
*/
589+
movq REGOFF_RIP(%rsp), %rcx
590+
sarq $47, %rcx
591+
incq %rcx
592+
cmpq $1, %rcx
593+
ja _syscall_post
594+
595+
568596
SIMPLE_SYSCALL_POSTSYS(%r15, %r14, %bx)
569597

570598
movq %r12, REGOFF_RAX(%rsp)

0 commit comments

Comments
 (0)