Skip to content

Commit fddf8ba

Browse files
ChangSeokBaeKAGA-KOKO
authored andcommitted
x86/ptrace: Prevent ptrace from clearing the FS/GS selector
When a ptracer writes a ptracee's FS/GSBASE with a different value, the selector is also cleared. This behavior is not correct as the selector should be preserved. Update only the base value and leave the selector intact. To simplify the code further remove the conditional checking for the same value as this code is not performance critical. The only recognizable downside of this change is when the selector is already nonzero on write. The base will be reloaded according to the selector. But the case is highly unexpected in real usages. [ tglx: 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 b3a9e3b commit fddf8ba

File tree

1 file changed

+2
-15
lines changed

1 file changed

+2
-15
lines changed

arch/x86/kernel/ptrace.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -379,25 +379,12 @@ static int putreg(struct task_struct *child,
379379
case offsetof(struct user_regs_struct,fs_base):
380380
if (value >= TASK_SIZE_MAX)
381381
return -EIO;
382-
/*
383-
* When changing the FS base, use do_arch_prctl_64()
384-
* to set the index to zero and to set the base
385-
* as requested.
386-
*
387-
* NB: This behavior is nonsensical and likely needs to
388-
* change when FSGSBASE support is added.
389-
*/
390-
if (child->thread.fsbase != value)
391-
return do_arch_prctl_64(child, ARCH_SET_FS, value);
382+
x86_fsbase_write_task(child, value);
392383
return 0;
393384
case offsetof(struct user_regs_struct,gs_base):
394-
/*
395-
* Exactly the same here as the %fs handling above.
396-
*/
397385
if (value >= TASK_SIZE_MAX)
398386
return -EIO;
399-
if (child->thread.gsbase != value)
400-
return do_arch_prctl_64(child, ARCH_SET_GS, value);
387+
x86_gsbase_write_task(child, value);
401388
return 0;
402389
#endif
403390
}

0 commit comments

Comments
 (0)