]>
Commit | Line | Data |
---|---|---|
04277e02 | 1 | /* Copyright (C) 1999-2019 Free Software Foundation, Inc. |
53ad957e UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Andreas Schwab <schwab@gnu.org>. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
53ad957e UD |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
53ad957e | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 | 16 | License along with the GNU C Library; if not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
53ad957e UD |
18 | |
19 | #include <sysdep.h> | |
20 | #define _ERRNO_H 1 | |
21 | #include <bits/errno.h> | |
e2787137 RM |
22 | #include <tcb-offsets.h> |
23 | ||
3650e1d9 L |
24 | #if SHSTK_ENABLED |
25 | /* The shadow stack prevents us from pushing the saved return PC onto | |
26 | the stack and returning normally. Instead we pop the shadow stack | |
27 | and return directly. This is the safest way to return and ensures | |
28 | any stack manipulations done by the vfork'd child doesn't cause the | |
29 | parent to terminate when CET is enabled. */ | |
30 | # undef SYSCALL_ERROR_HANDLER | |
31 | # ifdef PIC | |
32 | # define SYSCALL_ERROR_HANDLER \ | |
33 | 0: \ | |
34 | calll .L1; \ | |
35 | .L1: \ | |
36 | popl %edx; \ | |
37 | .L2: \ | |
38 | addl $_GLOBAL_OFFSET_TABLE_ + (.L2 - .L1), %edx; \ | |
39 | movl __libc_errno@gotntpoff(%edx), %edx; \ | |
40 | negl %eax; \ | |
41 | movl %eax, %gs:(%edx); \ | |
42 | orl $-1, %eax; \ | |
43 | jmp 1b; | |
44 | # else | |
45 | # define SYSCALL_ERROR_HANDLER \ | |
46 | 0: \ | |
47 | movl __libc_errno@indntpoff, %edx; \ | |
48 | negl %eax; \ | |
49 | movl %eax, %gs:(%edx); \ | |
50 | orl $-1, %eax; \ | |
51 | jmp 1b; | |
52 | # endif | |
53 | # undef SYSCALL_ERROR_LABEL | |
54 | # define SYSCALL_ERROR_LABEL 0f | |
55 | #endif | |
53ad957e UD |
56 | |
57 | /* Clone the calling process, but without copying the whole address space. | |
58 | The calling process is suspended until the new process exits or is | |
59 | replaced by a call to `execve'. Return -1 for errors, 0 to the new process, | |
60 | and the process ID of the new process to the old process. */ | |
61 | ||
62 | ENTRY (__vfork) | |
63 | ||
53ad957e UD |
64 | /* Pop the return PC value into ECX. */ |
65 | popl %ecx | |
fee732e5 | 66 | cfi_adjust_cfa_offset (-4) |
6c30d38f | 67 | cfi_register (%eip, %ecx) |
53ad957e UD |
68 | |
69 | /* Stuff the syscall number in EAX and enter into the kernel. */ | |
70 | movl $SYS_ify (vfork), %eax | |
71 | int $0x80 | |
70829603 | 72 | |
3650e1d9 | 73 | #if !SHSTK_ENABLED |
70829603 UD |
74 | /* Jump to the return PC. Don't jump directly since this |
75 | disturbs the branch target cache. Instead push the return | |
76 | address back on the stack. */ | |
77 | pushl %ecx | |
fee732e5 | 78 | cfi_adjust_cfa_offset (4) |
3650e1d9 | 79 | #endif |
70829603 | 80 | |
53ad957e | 81 | cmpl $-4095, %eax |
70829603 | 82 | /* Branch forward if it failed. */ |
70829603 | 83 | jae SYSCALL_ERROR_LABEL |
53ad957e | 84 | |
3650e1d9 L |
85 | #if SHSTK_ENABLED |
86 | 1: | |
87 | /* Check if shadow stack is in use. */ | |
88 | xorl %edx, %edx | |
89 | rdsspd %edx | |
90 | testl %edx, %edx | |
91 | /* Normal return if shadow stack isn't in use. */ | |
92 | je L(no_shstk) | |
93 | ||
94 | /* Pop return address from shadow stack and jump back to caller | |
95 | directly. */ | |
96 | movl $1, %edx | |
97 | incsspd %edx | |
98 | jmp *%ecx | |
99 | ||
100 | L(no_shstk): | |
101 | /* Jump to the return PC. Don't jump directly since this | |
102 | disturbs the branch target cache. Instead push the return | |
103 | address back on the stack. */ | |
104 | pushl %ecx | |
105 | cfi_adjust_cfa_offset (4) | |
106 | #endif | |
107 | ||
70829603 | 108 | ret |
53ad957e | 109 | |
53ad957e | 110 | PSEUDO_END (__vfork) |
a4baf360 | 111 | libc_hidden_def (__vfork) |
53ad957e UD |
112 | |
113 | weak_alias (__vfork, vfork) | |
e2787137 | 114 | strong_alias (__vfork, __libc_vfork) |