Received: by 10.213.65.68 with SMTP id h4csp1810400imn; Mon, 19 Mar 2018 13:57:10 -0700 (PDT) X-Google-Smtp-Source: AG47ELtfep4B12SWTN+ETU+gjRGip06ydP/mpcGRUpAWQ8xAmMBC5Tq7hkpDTaSSfNjokD9G75yQ X-Received: by 10.99.154.18 with SMTP id o18mr10340112pge.344.1521493030181; Mon, 19 Mar 2018 13:57:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521493030; cv=none; d=google.com; s=arc-20160816; b=vMHbW5zp0G8kBoMlfJJ+7HYrcjMBFvFyW1iex9IQBSQJfKbYav0gyGhROiLtTzJR1I WTAOZC3GjsVvXLSwUThDlR6RPiemlUZompERzeNyvSnm5ERB7pMyIYG+KjkRqQVRvJDi lbacB2/MsFfw1ZFTV2k0S5vtkgvY1AG+WgfNTYFEpmx4qhGnnul1xhzzpekw4d1tDNDY 2nl274nR86VTUkiC2qj/2dT9JPlY4qs8vSMCZn010XG/V3K7TLDLjvu3ApQ0OoQCu9DD p0xGXaeiab5JlOw07RVKfUZWr41gzwl81Do6JOIKl2p4LsJqF78oFClc5oRorNyyKZzM 99zQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=tdecH+G/NakA4J2hYsO3JXF8oekyIsOTyd/8sK2VanY=; b=u7hljDuFGQucfsK5PWrSNaXHcFuqt+u0QkG0uvBbPmUyj0ff0+UB1R3buQ1hlqiaME FwEzc7dQaa6wHGl6xFwH5uFzcjrwNf1jQ3UHmTDwJEJnBFYUIaU2LrW9fe0C+zZjDJpv VZGADo5b/yzME50NUtMA1sTq6k6JgLlDJV5JYyl/NLf7iD9ih9ylZ08NTUZFxKQJLv5E GVSbzGw7w2YL351UVweZTc/oVjvosiURx0B31YgrAl4LakmuPCfQtT1s8e7oAZRgJnih nIwUfWCnZi2c/jE9TvUOyBO6M5RiLf8OFFx8i3xV3MHnm7m1Xudee94OW5LTrbltN1FK sllg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d191si24137pgc.659.2018.03.19.13.56.25; Mon, 19 Mar 2018 13:57:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S967176AbeCSSJC (ORCPT + 99 others); Mon, 19 Mar 2018 14:09:02 -0400 Received: from mga14.intel.com ([192.55.52.115]:62511 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S968521AbeCSSIx (ORCPT ); Mon, 19 Mar 2018 14:08:53 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Mar 2018 11:08:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,331,1517904000"; d="scan'208";a="39330580" Received: from chang-linux.sc.intel.com ([143.183.85.144]) by fmsmga001.fm.intel.com with ESMTP; 19 Mar 2018 11:08:52 -0700 From: "Chang S. Bae" To: x86@kernel.org Cc: luto@kernel.org, ak@linux.intel.com, hpa@zytor.com, markus.t.metzger@intel.com, tony.luck@intel.com, ravi.v.shankar@intel.com, linux-kernel@vger.kernel.org, chang.seok.bae@intel.com, "Markus T . Metzger" Subject: [PATCH 07/15] x86/fsgsbase/64: putregs() in a reverse order Date: Mon, 19 Mar 2018 10:49:19 -0700 Message-Id: <1521481767-22113-8-git-send-email-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1521481767-22113-1-git-send-email-chang.seok.bae@intel.com> References: <1521481767-22113-1-git-send-email-chang.seok.bae@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch makes a walk of user_regs_struct reversely. Main reason for doing this is to put FS/GS base setting after the selector. Each element is independently set now. When FS/GS base is (only) updated, its index is reset to zero. In putregs(), it does not reset when both FS/GS base and selector are covered. When FSGSBASE is enabled, an arbitrary base value is possible anyways, so it is going to be reasonable to write base lastly. Suggested-by: H. Peter Anvin Signed-off-by: Chang S. Bae Cc: Markus T. Metzger Cc: Andi Kleen Cc: Andy Lutomirski --- arch/x86/kernel/ptrace.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 9c09bf0..ee37e28 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -426,14 +426,56 @@ static int putregs(struct task_struct *child, unsigned int count, const unsigned long *values) { - const unsigned long *v = values; + const unsigned long *v = values + count / sizeof(unsigned long); int ret = 0; +#ifdef CONFIG_X86_64 + bool fs_fully_covered = (offset <= USER_REGS_OFFSET(fs_base)) && + ((offset + count) >= USER_REGS_OFFSET(fs)); + bool gs_fully_covered = (offset <= USER_REGS_OFFSET(gs_base)) && + ((offset + count) >= USER_REGS_OFFSET(gs)); + + offset += count - sizeof(*v); + + while (count >= sizeof(*v) && !ret) { + v--; + switch (offset) { + case USER_REGS_OFFSET(fs_base): + if (fs_fully_covered) { + if (unlikely(*v >= TASK_SIZE_MAX)) + return -EIO; + /* + * When changing both %fs (index) and %fsbase + * write_task_fsbase() tends to overwrite + * task's %fs. Simply setting base only here. + */ + if (child->thread.fsbase != *v) + child->thread.fsbase = *v; + break; + } + case USER_REGS_OFFSET(gs_base): + if (gs_fully_covered) { + if (unlikely(*v >= TASK_SIZE_MAX)) + return -EIO; + /* Same here as the %fs handling above */ + if (child->thread.gsbase != *v) + child->thread.gsbase = *v; + break; + } + default: + ret = putreg(child, offset, *v); + } + count -= sizeof(*v); + offset -= sizeof(*v); + } +#else + offset += count - sizeof(*v); while (count >= sizeof(*v) && !ret) { - ret = putreg(child, offset, *v++); + ret = putreg(child, offset, *(--v)); count -= sizeof(*v); - offset += sizeof(*v); + offset -= sizeof(*v); } +#endif /* CONFIG_X86_64 */ return ret; } -- 2.7.4