Messages in this thread Patch in this message | | | Date | Mon, 25 Feb 2019 13:43:32 +0100 | From | Peter Zijlstra <> | Subject | [PATCH 2/6] x86/ia32: Fix ia32_restore_sigcontext AC leak |
| |
Don't call load_gs_index() with AC set; delay the segment setting until after the AC section.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> --- arch/x86/ia32/ia32_signal.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
--- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -60,17 +60,21 @@ regs->seg = GET_SEG(seg) | 3; \ } while (0) -#define RELOAD_SEG(seg) { \ - unsigned int pre = GET_SEG(seg); \ - unsigned int cur = get_user_seg(seg); \ - pre |= 3; \ - if (pre != cur) \ - set_user_seg(seg, pre); \ +#define LOAD_SEG(seg) { \ + pre_##seg = 3 | GET_SEG(seg); \ + cur_##seg = get_user_seg(seg); \ +} + +#define RELOAD_SEG(seg) { \ + if (pre_##seg != cur_##seg) \ + set_user_seg(seg, pre_##seg); \ } static int ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_32 __user *sc) { + u16 pre_gs, pre_fs, pre_ds, pre_es; + u16 cur_gs, cur_fs, cur_ds, cur_es; unsigned int tmpflags, err = 0; void __user *buf; u32 tmp; @@ -85,10 +89,10 @@ static int ia32_restore_sigcontext(struc * the handler, but does not clobber them at least in the * normal case. */ - RELOAD_SEG(gs); - RELOAD_SEG(fs); - RELOAD_SEG(ds); - RELOAD_SEG(es); + LOAD_SEG(gs); + LOAD_SEG(fs); + LOAD_SEG(ds); + LOAD_SEG(es); COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); COPY(dx); COPY(cx); COPY(ip); COPY(ax); @@ -106,6 +110,11 @@ static int ia32_restore_sigcontext(struc buf = compat_ptr(tmp); } get_user_catch(err); + RELOAD_SEG(gs); + RELOAD_SEG(fs); + RELOAD_SEG(ds); + RELOAD_SEG(es); + err |= fpu__restore_sig(buf, 1); force_iret();
| |