Skip to content

Commit 005f141

Browse files
ChangSeokBaeKAGA-KOKO
authored andcommitted
x86/process/64: Use FSGSBASE instructions on thread copy and ptrace
When FSGSBASE is enabled, copying threads and reading fsbase and gsbase using ptrace must read the actual values. When copying a thread, use save_fsgs() and copy the saved values. For ptrace, the bases must be read from memory regardless of the selector if FSGSBASE is enabled. [ tglx: Invoke __rdgsbase_inactive() with interrupts disabled ] [ luto: Massage changelog ] Suggested-by: Andy Lutomirski <[email protected]> Signed-off-by: Chang S. Bae <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent 6739034 commit 005f141

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

arch/x86/kernel/process.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,12 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
140140
memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
141141

142142
#ifdef CONFIG_X86_64
143-
savesegment(gs, p->thread.gsindex);
144-
p->thread.gsbase = p->thread.gsindex ? 0 : current->thread.gsbase;
145-
savesegment(fs, p->thread.fsindex);
146-
p->thread.fsbase = p->thread.fsindex ? 0 : current->thread.fsbase;
143+
current_save_fsgs();
144+
p->thread.fsindex = current->thread.fsindex;
145+
p->thread.fsbase = current->thread.fsbase;
146+
p->thread.gsindex = current->thread.gsindex;
147+
p->thread.gsbase = current->thread.gsbase;
148+
147149
savesegment(es, p->thread.es);
148150
savesegment(ds, p->thread.ds);
149151
#else

arch/x86/kernel/process_64.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,8 @@ unsigned long x86_fsbase_read_task(struct task_struct *task)
426426

427427
if (task == current)
428428
fsbase = x86_fsbase_read_cpu();
429-
else if (task->thread.fsindex == 0)
429+
else if (static_cpu_has(X86_FEATURE_FSGSBASE) ||
430+
(task->thread.fsindex == 0))
430431
fsbase = task->thread.fsbase;
431432
else
432433
fsbase = x86_fsgsbase_read_task(task, task->thread.fsindex);
@@ -440,7 +441,8 @@ unsigned long x86_gsbase_read_task(struct task_struct *task)
440441

441442
if (task == current)
442443
gsbase = x86_gsbase_read_cpu_inactive();
443-
else if (task->thread.gsindex == 0)
444+
else if (static_cpu_has(X86_FEATURE_FSGSBASE) ||
445+
(task->thread.gsindex == 0))
444446
gsbase = task->thread.gsbase;
445447
else
446448
gsbase = x86_fsgsbase_read_task(task, task->thread.gsindex);

0 commit comments

Comments
 (0)