Skip to content

Commit 47f33de

Browse files
Lai Jiangshansuryasaimadhu
authored andcommitted
x86/sev: Mark the code returning to user space as syscall gap
When returning to user space, %rsp is user-controlled value. If it is a SNP-guest and the hypervisor decides to mess with the code-page for this path while a CPU is executing it, a potential #VC could hit in the syscall return path and mislead the #VC handler. So make ip_within_syscall_gap() return true in this case. Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com> Signed-off-by: Borislav Petkov <bp@suse.de> Acked-by: Joerg Roedel <jroedel@suse.de> Link: https://lore.kernel.org/r/20220412124909.10467-1-jiangshanlai@gmail.com
1 parent c42b145 commit 47f33de

4 files changed

Lines changed: 12 additions & 0 deletions

File tree

arch/x86/entry/entry_64.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,10 @@ syscall_return_via_sysret:
215215

216216
popq %rdi
217217
popq %rsp
218+
SYM_INNER_LABEL(entry_SYSRETQ_unsafe_stack, SYM_L_GLOBAL)
218219
swapgs
219220
sysretq
221+
SYM_INNER_LABEL(entry_SYSRETQ_end, SYM_L_GLOBAL)
220222
SYM_CODE_END(entry_SYSCALL_64)
221223

222224
/*

arch/x86/entry/entry_64_compat.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ sysret32_from_system_call:
297297
* code. We zero R8-R10 to avoid info leaks.
298298
*/
299299
movq RSP-ORIG_RAX(%rsp), %rsp
300+
SYM_INNER_LABEL(entry_SYSRETL_compat_unsafe_stack, SYM_L_GLOBAL)
300301

301302
/*
302303
* The original userspace %rsp (RSP-ORIG_RAX(%rsp)) is stored
@@ -314,6 +315,7 @@ sysret32_from_system_call:
314315
xorl %r10d, %r10d
315316
swapgs
316317
sysretl
318+
SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL)
317319
SYM_CODE_END(entry_SYSCALL_compat)
318320

319321
/*

arch/x86/include/asm/proto.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ void syscall_init(void);
1313
#ifdef CONFIG_X86_64
1414
void entry_SYSCALL_64(void);
1515
void entry_SYSCALL_64_safe_stack(void);
16+
void entry_SYSRETQ_unsafe_stack(void);
17+
void entry_SYSRETQ_end(void);
1618
long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2);
1719
#endif
1820

@@ -28,6 +30,8 @@ void entry_SYSENTER_compat(void);
2830
void __end_entry_SYSENTER_compat(void);
2931
void entry_SYSCALL_compat(void);
3032
void entry_SYSCALL_compat_safe_stack(void);
33+
void entry_SYSRETL_compat_unsafe_stack(void);
34+
void entry_SYSRETL_compat_end(void);
3135
void entry_INT80_compat(void);
3236
#ifdef CONFIG_XEN_PV
3337
void xen_entry_INT80_compat(void);

arch/x86/include/asm/ptrace.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,13 @@ static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs)
186186
bool ret = (regs->ip >= (unsigned long)entry_SYSCALL_64 &&
187187
regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack);
188188

189+
ret = ret || (regs->ip >= (unsigned long)entry_SYSRETQ_unsafe_stack &&
190+
regs->ip < (unsigned long)entry_SYSRETQ_end);
189191
#ifdef CONFIG_IA32_EMULATION
190192
ret = ret || (regs->ip >= (unsigned long)entry_SYSCALL_compat &&
191193
regs->ip < (unsigned long)entry_SYSCALL_compat_safe_stack);
194+
ret = ret || (regs->ip >= (unsigned long)entry_SYSRETL_compat_unsafe_stack &&
195+
regs->ip < (unsigned long)entry_SYSRETL_compat_end);
192196
#endif
193197

194198
return ret;

0 commit comments

Comments
 (0)