From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752450AbdIXLCc (ORCPT ); Sun, 24 Sep 2017 07:02:32 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:32841 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751922AbdIXK7g (ORCPT ); Sun, 24 Sep 2017 06:59:36 -0400 X-Google-Smtp-Source: AOwi7QA3bqBdjEeeW/oz9yCXeqDUvfEVkIbXR/O/yQrdJ0gjsCDg17QEyhkTLxQnudMWdWVQGb/oLg== From: Ingo Molnar To: linux-kernel@vger.kernel.org Cc: Andrew Morton , Eric Biggers , Andy Lutomirski , Borislav Petkov , Dave Hansen , Fenghua Yu , "H . Peter Anvin" , Linus Torvalds , Oleg Nesterov , Peter Zijlstra , Rik van Riel , Thomas Gleixner , Yu-cheng Yu Subject: [PATCH 03/10] x86/fpu: Use validate_xstate_header() to validate the xstate_header in sanitize_restored_xstate() Date: Sun, 24 Sep 2017 12:59:06 +0200 Message-Id: <20170924105913.9157-4-mingo@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170924105913.9157-1-mingo@kernel.org> References: <20170924105913.9157-1-mingo@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Biggers Tighten the checks in sanitize_restored_xstate(). Signed-off-by: Eric Biggers Cc: Andy Lutomirski Cc: Dave Hansen Cc: Dmitry Vyukov Cc: Fenghua Yu Cc: Kees Cook Cc: Kevin Hao Cc: Linus Torvalds Cc: Michael Halcrow Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Rik van Riel Cc: Thomas Gleixner Cc: Wanpeng Li Cc: Yu-cheng Yu Cc: kernel-hardening@lists.openwall.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/fpu/signal.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 1ef1b228b9fd..afe54247cf27 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -214,8 +214,11 @@ sanitize_restored_xstate(struct task_struct *tsk, struct xstate_header *header = &xsave->header; if (use_xsave()) { - /* These bits must be zero. */ - memset(header->reserved, 0, 48); + /* + * Note: we don't need to zero the reserved bits in the + * xstate_header here because we either didn't copy them at all, + * or we checked earlier that they aren't set. + */ /* * Init the state that is not present in the memory @@ -224,7 +227,7 @@ sanitize_restored_xstate(struct task_struct *tsk, if (fx_only) header->xfeatures = XFEATURE_MASK_FPSSE; else - header->xfeatures &= (xfeatures_mask & xfeatures); + header->xfeatures &= xfeatures; } if (use_fxsr()) { @@ -308,7 +311,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) /* * For 32-bit frames with fxstate, copy the user state to the * thread's fpu state, reconstruct fxstate from the fsave - * header. Sanitize the copied state etc. + * header. Validate and sanitize the copied state. */ struct fpu *fpu = &tsk->thread.fpu; struct user_i387_ia32_struct env; @@ -328,10 +331,8 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) err = copy_user_to_xstate(&fpu->state.xsave, buf_fx); } else { err = __copy_from_user(&fpu->state.xsave, buf_fx, state_size); - - /* xcomp_bv must be 0 when using uncompacted format */ - if (!err && fpu->state.xsave.header.xcomp_bv) - err = -EINVAL; + if (!err) + err = validate_xstate_header(&fpu->state.xsave.header); } if (err || __copy_from_user(&env, buf, sizeof(env))) { -- 2.11.0