From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E30CC433B4 for ; Fri, 9 Apr 2021 15:57:16 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 8D20861042 for ; Fri, 9 Apr 2021 15:57:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8D20861042 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=shutemov.name Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 181B36B006C; Fri, 9 Apr 2021 11:57:15 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 130466B006E; Fri, 9 Apr 2021 11:57:15 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E9EB06B0070; Fri, 9 Apr 2021 11:57:14 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0088.hostedemail.com [216.40.44.88]) by kanga.kvack.org (Postfix) with ESMTP id CCF6F6B006C for ; Fri, 9 Apr 2021 11:57:14 -0400 (EDT) Received: from smtpin33.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id 924FD8248047 for ; Fri, 9 Apr 2021 15:57:14 +0000 (UTC) X-FDA: 78013282788.33.2369889 Received: from mail-lf1-f42.google.com (mail-lf1-f42.google.com [209.85.167.42]) by imf03.hostedemail.com (Postfix) with ESMTP id 6B173C0007DE for ; Fri, 9 Apr 2021 15:57:11 +0000 (UTC) Received: by mail-lf1-f42.google.com with SMTP id b14so10450977lfv.8 for ; Fri, 09 Apr 2021 08:57:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=shutemov-name.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=XsvaSY8zYN9q+b8PbsWtp1w+Khl2vjj666Eagwy6n5c=; b=Sxywz2hcOMwDVDk2CRpRj35+nfOUayyt5AgurLU6/5LbZVVIrGm0OSEUetnqf8s+Xr Ca3L5pd44k1WYJtzFaqb1ge5LmarpaDUj83GyGgHm1xh5gwqrIAqy0/csimThBS4XZKp F90EiIohVQpSZ/n+/XVxCqqjsXRNzApETZu2jafVluNR5Toh2A4EiU+Cy3IjahBUR2KM /rfpuVa/n9Zh2fkO1GBaDCNniGZj/oEm9Od19IKM2cQ3TIcXZ3/MV0RGluxxEd6Vl8dm jBevVax0yxfRXa6E9Lxz5kQMBqE6l252/antXatpXEYgFPqzK22/wjgjhUmtKaffmm8B jeVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=XsvaSY8zYN9q+b8PbsWtp1w+Khl2vjj666Eagwy6n5c=; b=ZbCl89zAfnqcdM0/mekoWSPXKhyUPsTVuvhTXg00eWiDDlqZL4VfhMzY2+cY7ldjEm NYgEDPsya6A/op8ddE09tWvrDQGl3SYfkrWqm2ctPL7DA8XQBqjyDMN6R0IvmjPNrvhq mdQaqg51RewB3dx2ynZSf/jF1IgtBF6Ox2X28Okd8alaT2/ZFv6jzy5rxJ9N1aBVf2+7 YzCoXbKGCbVP/j1CaLuCYxSS4GcuG5g++R2tFQdeekP1YfKi0MWsimNd/HSq70xmko2h Mt1B4aXXZ8u14Qa9H+vwwPnDPwgtEbWnyVKhpbwZ5hV3/U5hbyqML6sTsuCRreDLBnJ7 hmJA== X-Gm-Message-State: AOAM531HJqr4WNRg/1ieF+oXaQpFcafSdKgownh7mKxItZd76LHh40mN 6trUlaH0mj+7E4FYvL1UDjsNlg== X-Google-Smtp-Source: ABdhPJx4167C4epw4GZ3O6x+I3bz4h7dUH3Dy06BAJVx7+AZjRBM6+oPCgBhDIGlc3OtAdyHcZZ4mw== X-Received: by 2002:a05:6512:33a8:: with SMTP id i8mr10617815lfg.375.1617983832458; Fri, 09 Apr 2021 08:57:12 -0700 (PDT) Received: from box.localdomain ([86.57.175.117]) by smtp.gmail.com with ESMTPSA id f15sm304423lfr.51.2021.04.09.08.57.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Apr 2021 08:57:11 -0700 (PDT) Received: by box.localdomain (Postfix, from userid 1000) id 586C5102498; Fri, 9 Apr 2021 18:57:11 +0300 (+03) Date: Fri, 9 Apr 2021 18:57:11 +0300 From: "Kirill A. Shutemov" To: Yu-cheng Yu Cc: x86@kernel.org, "H. Peter Anvin" , Thomas Gleixner , Ingo Molnar , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, linux-api@vger.kernel.org, Arnd Bergmann , Andy Lutomirski , Balbir Singh , Borislav Petkov , Cyrill Gorcunov , Dave Hansen , Eugene Syromiatnikov , Florian Weimer , "H.J. Lu" , Jann Horn , Jonathan Corbet , Kees Cook , Mike Kravetz , Nadav Amit , Oleg Nesterov , Pavel Machek , Peter Zijlstra , Randy Dunlap , "Ravi V. Shankar" , Vedvyas Shanbhogue , Dave Martin , Weijiang Yang , Pengfei Xu , Haitao Huang Subject: Re: [PATCH v24 22/30] x86/cet/shstk: Add user-mode shadow stack support Message-ID: <20210409155711.kxf3fjc7csvqpl33@box.shutemov.name> References: <20210401221104.31584-1-yu-cheng.yu@intel.com> <20210401221104.31584-23-yu-cheng.yu@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210401221104.31584-23-yu-cheng.yu@intel.com> X-Rspamd-Server: rspam01 X-Rspamd-Queue-Id: 6B173C0007DE X-Stat-Signature: eyht9uhh71g4dawdopagitndbt7wd5wg Received-SPF: none (shutemov.name>: No applicable sender policy available) receiver=imf03; identity=mailfrom; envelope-from=""; helo=mail-lf1-f42.google.com; client-ip=209.85.167.42 X-HE-DKIM-Result: pass/pass X-HE-Tag: 1617983831-286729 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On Thu, Apr 01, 2021 at 03:10:56PM -0700, Yu-cheng Yu wrote: > Introduce basic shadow stack enabling/disabling/allocation routines. > A task's shadow stack is allocated from memory with VM_SHADOW_STACK flag > and has a fixed size of min(RLIMIT_STACK, 4GB). > > Signed-off-by: Yu-cheng Yu > Cc: Kees Cook > --- > v24: > - Rename cet.c to shstk.c, update related areas accordingly. > > arch/x86/include/asm/cet.h | 29 +++++++ > arch/x86/include/asm/processor.h | 5 ++ > arch/x86/kernel/Makefile | 2 + > arch/x86/kernel/shstk.c | 128 +++++++++++++++++++++++++++++++ > 4 files changed, 164 insertions(+) > create mode 100644 arch/x86/include/asm/cet.h > create mode 100644 arch/x86/kernel/shstk.c > > diff --git a/arch/x86/include/asm/cet.h b/arch/x86/include/asm/cet.h > new file mode 100644 > index 000000000000..aa85d599b184 > --- /dev/null > +++ b/arch/x86/include/asm/cet.h > @@ -0,0 +1,29 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef _ASM_X86_CET_H > +#define _ASM_X86_CET_H > + > +#ifndef __ASSEMBLY__ > +#include > + > +struct task_struct; > +/* > + * Per-thread CET status > + */ > +struct cet_status { > + unsigned long shstk_base; > + unsigned long shstk_size; > +}; > + > +#ifdef CONFIG_X86_SHADOW_STACK > +int shstk_setup(void); > +void shstk_free(struct task_struct *p); > +void shstk_disable(void); > +#else > +static inline int shstk_setup(void) { return 0; } > +static inline void shstk_free(struct task_struct *p) {} > +static inline void shstk_disable(void) {} > +#endif > + > +#endif /* __ASSEMBLY__ */ > + > +#endif /* _ASM_X86_CET_H */ > diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h > index f1b9ed5efaa9..a5d703fda74e 100644 > --- a/arch/x86/include/asm/processor.h > +++ b/arch/x86/include/asm/processor.h > @@ -27,6 +27,7 @@ struct vm86; > #include > #include > #include > +#include > > #include > #include > @@ -535,6 +536,10 @@ struct thread_struct { > > unsigned int sig_on_uaccess_err:1; > > +#ifdef CONFIG_X86_CET > + struct cet_status cet; > +#endif > + > /* Floating point and extended processor state */ > struct fpu fpu; > /* > diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile > index 2ddf08351f0b..0f99b093f350 100644 > --- a/arch/x86/kernel/Makefile > +++ b/arch/x86/kernel/Makefile > @@ -150,6 +150,8 @@ obj-$(CONFIG_UNWINDER_FRAME_POINTER) += unwind_frame.o > obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o > > obj-$(CONFIG_AMD_MEM_ENCRYPT) += sev-es.o > +obj-$(CONFIG_X86_SHADOW_STACK) += shstk.o > + > ### > # 64 bit specific files > ifeq ($(CONFIG_X86_64),y) > diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c > new file mode 100644 > index 000000000000..5406fdf6df3c > --- /dev/null > +++ b/arch/x86/kernel/shstk.c > @@ -0,0 +1,128 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * shstk.c - Intel shadow stack support > + * > + * Copyright (c) 2021, Intel Corporation. > + * Yu-cheng Yu > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +static void start_update_msrs(void) > +{ > + fpregs_lock(); > + if (test_thread_flag(TIF_NEED_FPU_LOAD)) > + __fpregs_load_activate(); > +} > + > +static void end_update_msrs(void) > +{ > + fpregs_unlock(); > +} > + > +static unsigned long alloc_shstk(unsigned long size, int flags) > +{ > + struct mm_struct *mm = current->mm; > + unsigned long addr, populate; > + > + /* VM_SHADOW_STACK requires MAP_ANONYMOUS, MAP_PRIVATE */ > + flags |= MAP_ANONYMOUS | MAP_PRIVATE; Looks like all callers has flags == 0. Do I miss something. > + > + mmap_write_lock(mm); > + addr = do_mmap(NULL, 0, size, PROT_READ, flags, VM_SHADOW_STACK, 0, > + &populate, NULL); > + mmap_write_unlock(mm); > + > + if (populate) > + mm_populate(addr, populate); If all callers pass down flags==0, populate will never happen. > + > + return addr; > +} > + > +int shstk_setup(void) > +{ > + unsigned long addr, size; > + struct cet_status *cet = ¤t->thread.cet; > + > + if (!cpu_feature_enabled(X86_FEATURE_SHSTK)) > + return -EOPNOTSUPP; > + > + size = round_up(min_t(unsigned long long, rlimit(RLIMIT_STACK), SZ_4G), PAGE_SIZE); > + addr = alloc_shstk(size, 0); > + if (IS_ERR_VALUE(addr)) > + return PTR_ERR((void *)addr); > + > + cet->shstk_base = addr; > + cet->shstk_size = size; > + > + start_update_msrs(); > + wrmsrl(MSR_IA32_PL3_SSP, addr + size); > + wrmsrl(MSR_IA32_U_CET, CET_SHSTK_EN); > + end_update_msrs(); > + return 0; > +} > + > +void shstk_free(struct task_struct *tsk) > +{ > + struct cet_status *cet = &tsk->thread.cet; > + > + if (!cpu_feature_enabled(X86_FEATURE_SHSTK) || > + !cet->shstk_size || > + !cet->shstk_base) > + return; > + > + if (!tsk->mm) > + return; > + > + while (1) { > + int r; > + > + r = vm_munmap(cet->shstk_base, cet->shstk_size); > + > + /* > + * vm_munmap() returns -EINTR when mmap_lock is held by > + * something else, and that lock should not be held for a > + * long time. Retry it for the case. > + */ Hm, no. -EINTR is not about the lock being held by somebody else. The task got a signal and need to return to userspace. I have not looked at the rest of the patches yet, but why do you need a special free path for shadow stack? Why the normal unmap route doesn't work for you? > + if (r == -EINTR) { > + cond_resched(); > + continue; > + } > + break; > + } > + > + cet->shstk_base = 0; > + cet->shstk_size = 0; > +} > + > +void shstk_disable(void) > +{ > + struct cet_status *cet = ¤t->thread.cet; > + u64 msr_val; > + > + if (!cpu_feature_enabled(X86_FEATURE_SHSTK) || > + !cet->shstk_size || > + !cet->shstk_base) > + return; > + > + start_update_msrs(); > + rdmsrl(MSR_IA32_U_CET, msr_val); > + wrmsrl(MSR_IA32_U_CET, msr_val & ~CET_SHSTK_EN); > + wrmsrl(MSR_IA32_PL3_SSP, 0); > + end_update_msrs(); > + > + shstk_free(current); > +} > -- > 2.21.0 > > -- Kirill A. Shutemov