From nobody Thu Apr 30 09:38:02 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AB624C43334 for ; Mon, 6 Jun 2022 20:42:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234301AbiFFUm4 (ORCPT ); Mon, 6 Jun 2022 16:42:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234356AbiFFUm2 (ORCPT ); Mon, 6 Jun 2022 16:42:28 -0400 Received: from mail-oa1-x2f.google.com (mail-oa1-x2f.google.com [IPv6:2001:4860:4864:20::2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 33BD51203FB for ; Mon, 6 Jun 2022 13:38:49 -0700 (PDT) Received: by mail-oa1-x2f.google.com with SMTP id 586e51a60fabf-fb6b4da1dfso2613921fac.4 for ; Mon, 06 Jun 2022 13:38:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ysbTnxMyTI7DA06kRA/I/BJnOe40tZ93n6R0vsgYdKA=; b=iAVzH1ORlcaCwh4OShvMXQ6EwyCa/kxQR5eF6qaHNV8VRYUTO3ep/UT6gHTGZpsHhi 5gU63AFMGcaBlP6wp6onSY9wwxD/zeNiE3Okdxat9X/aOdBloKhOWvpSM8W+1Qr/88v5 wxOayY7yPjBG8JHtkf19qygXBfJ3P23cASLsTYGj/DN5pz09zb17sWlp+EV1qoeSUaK9 zaOxt6ZjjN/prZStkvqIefHaOq0gRNDDLpKUwaZWVJ5Zv/waRVNaWHQ2cbQFRo4XspL5 dVyXl76qvhHJkNVrSIVDknonSIYFsDv6+o7PLIPEW2h18CKHaeIx5v0WzN/AP4r2JRYT lEGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ysbTnxMyTI7DA06kRA/I/BJnOe40tZ93n6R0vsgYdKA=; b=BYh/HQDeuS/MT272TSOKP1vSNfdyRgMo5tCQqUovHgHBuptrNl5Lpj2eaUnoisQ39C FqDu4XkcWAL3lXVjgY3vW1GRPl4FhnsCPrDIGnLLoR33/ODmThOJKZ4hk/U0z53ZGdqo Aohzhapsww69UqJvADPn3ROKhdWlVYuwvHOidOhrNctbXqXXA30KTlUWpTNlhof5rqfD 5KTC/sjcG/iLi1Vr4DALSgNcYUcNR7WnXFI4o/HxeBagHChCpob5v7j3vrXUnJG8iUTA f6BQN9S+i9Qy4WJaWleiMNmx7UoJNq+jIsFWag3rk+sTzfcb9SAlMiL6v/FaJQymXMFp FQHg== X-Gm-Message-State: AOAM530BADW/KjWgGfhpM8E+jfyGPlytB7YTwPEs2QQ/TES2ZOJZAou+ cvH4Bbb+QodSonwVVzQ09V1RIYLZOQ== X-Google-Smtp-Source: ABdhPJwkR5pQvQLCL8y/RAzGt3HAYuENym2fYuLb0KluX9h6YNsz+Op1ABJkU6ZxTBnPMSQnsZmoGw== X-Received: by 2002:a05:6870:32d6:b0:fb:3d62:b5b7 with SMTP id r22-20020a05687032d600b000fb3d62b5b7mr6225967oac.285.1654547927945; Mon, 06 Jun 2022 13:38:47 -0700 (PDT) Received: from citadel.. (174-084-153-250.res.spectrum.com. [174.84.153.250]) by smtp.gmail.com with ESMTPSA id j22-20020a056808035600b0032e3cca8561sm4327188oie.21.2022.06.06.13.38.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jun 2022 13:38:47 -0700 (PDT) From: Brian Gerst To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Thomas Gleixner , Andy Lutomirski , Borislav Petkov , "H . Peter Anvin" , Peter Zijlstra , "Eric W . Biederman" , Brian Gerst Subject: [PATCH 1/8] x86/signal: Remove sig parameter from frame setup functions Date: Mon, 6 Jun 2022 16:37:55 -0400 Message-Id: <20220606203802.158958-2-brgerst@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220606203802.158958-1-brgerst@gmail.com> References: <20220606203802.158958-1-brgerst@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Passing the signal number as a seperate parameter is unnecessary, since it is always ksig->sig. Signed-off-by: Brian Gerst Acked-by: "Eric W. Biederman" --- arch/x86/ia32/ia32_signal.c | 12 ++++++------ arch/x86/include/asm/fpu/signal.h | 4 ++-- arch/x86/kernel/signal.c | 23 +++++++++++------------ 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index c9c3859322fa..390347ab92de 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -230,7 +230,7 @@ static void __user *get_sigframe(struct ksignal *ksig, = struct pt_regs *regs, return (void __user *) sp; } =20 -int ia32_setup_frame(int sig, struct ksignal *ksig, +int ia32_setup_frame(struct ksignal *ksig, compat_sigset_t *set, struct pt_regs *regs) { struct sigframe_ia32 __user *frame; @@ -264,7 +264,7 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, if (!user_access_begin(frame, sizeof(*frame))) return -EFAULT; =20 - unsafe_put_user(sig, &frame->sig, Efault); + unsafe_put_user(ksig->sig, &frame->sig, Efault); unsafe_put_sigcontext32(&frame->sc, fp, regs, set, Efault); unsafe_put_user(set->sig[1], &frame->extramask[0], Efault); unsafe_put_user(ptr_to_compat(restorer), &frame->pretcode, Efault); @@ -280,7 +280,7 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, regs->ip =3D (unsigned long) ksig->ka.sa.sa_handler; =20 /* Make -mregparm=3D3 work */ - regs->ax =3D sig; + regs->ax =3D ksig->sig; regs->dx =3D 0; regs->cx =3D 0; =20 @@ -296,7 +296,7 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, return -EFAULT; } =20 -int ia32_setup_rt_frame(int sig, struct ksignal *ksig, +int ia32_setup_rt_frame(struct ksignal *ksig, compat_sigset_t *set, struct pt_regs *regs) { struct rt_sigframe_ia32 __user *frame; @@ -321,7 +321,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig, if (!user_access_begin(frame, sizeof(*frame))) return -EFAULT; =20 - unsafe_put_user(sig, &frame->sig, Efault); + unsafe_put_user(ksig->sig, &frame->sig, Efault); unsafe_put_user(ptr_to_compat(&frame->info), &frame->pinfo, Efault); unsafe_put_user(ptr_to_compat(&frame->uc), &frame->puc, Efault); =20 @@ -357,7 +357,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig, regs->ip =3D (unsigned long) ksig->ka.sa.sa_handler; =20 /* Make -mregparm=3D3 work */ - regs->ax =3D sig; + regs->ax =3D ksig->sig; regs->dx =3D (unsigned long) &frame->info; regs->cx =3D (unsigned long) &frame->uc; =20 diff --git a/arch/x86/include/asm/fpu/signal.h b/arch/x86/include/asm/fpu/s= ignal.h index e1c9df9102a5..08826ad0254d 100644 --- a/arch/x86/include/asm/fpu/signal.h +++ b/arch/x86/include/asm/fpu/signal.h @@ -14,9 +14,9 @@ # include # include struct ksignal; -int ia32_setup_rt_frame(int sig, struct ksignal *ksig, +int ia32_setup_rt_frame(struct ksignal *ksig, compat_sigset_t *set, struct pt_regs *regs); -int ia32_setup_frame(int sig, struct ksignal *ksig, +int ia32_setup_frame(struct ksignal *ksig, compat_sigset_t *set, struct pt_regs *regs); #else # define user_i387_ia32_struct user_i387_struct diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 9c7265b524c7..40b1373bb70b 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -324,7 +324,7 @@ static const struct { }; =20 static int -__setup_frame(int sig, struct ksignal *ksig, sigset_t *set, +__setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { struct sigframe __user *frame; @@ -336,7 +336,7 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *= set, if (!user_access_begin(frame, sizeof(*frame))) return -EFAULT; =20 - unsafe_put_user(sig, &frame->sig, Efault); + unsafe_put_user(ksig->sig, &frame->sig, Efault); unsafe_put_sigcontext(&frame->sc, fp, regs, set, Efault); unsafe_put_user(set->sig[1], &frame->extramask[0], Efault); if (current->mm->context.vdso) @@ -363,7 +363,7 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *= set, /* Set up registers for signal handler */ regs->sp =3D (unsigned long)frame; regs->ip =3D (unsigned long)ksig->ka.sa.sa_handler; - regs->ax =3D (unsigned long)sig; + regs->ax =3D (unsigned long)ksig->sig; regs->dx =3D 0; regs->cx =3D 0; =20 @@ -379,7 +379,7 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *= set, return -EFAULT; } =20 -static int __setup_rt_frame(int sig, struct ksignal *ksig, +static int __setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; @@ -391,7 +391,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ks= ig, if (!user_access_begin(frame, sizeof(*frame))) return -EFAULT; =20 - unsafe_put_user(sig, &frame->sig, Efault); + unsafe_put_user(ksig->sig, &frame->sig, Efault); unsafe_put_user(&frame->info, &frame->pinfo, Efault); unsafe_put_user(&frame->uc, &frame->puc, Efault); =20 @@ -428,7 +428,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ks= ig, /* Set up registers for signal handler */ regs->sp =3D (unsigned long)frame; regs->ip =3D (unsigned long)ksig->ka.sa.sa_handler; - regs->ax =3D (unsigned long)sig; + regs->ax =3D (unsigned long)ksig->sig; regs->dx =3D (unsigned long)&frame->info; regs->cx =3D (unsigned long)&frame->uc; =20 @@ -458,7 +458,7 @@ static unsigned long frame_uc_flags(struct pt_regs *reg= s) return flags; } =20 -static int __setup_rt_frame(int sig, struct ksignal *ksig, +static int __setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; @@ -493,7 +493,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ks= ig, } =20 /* Set up registers for signal handler */ - regs->di =3D sig; + regs->di =3D ksig->sig; /* In case the signal handler was declared without prototypes */ regs->ax =3D 0; =20 @@ -763,7 +763,6 @@ static inline int is_x32_frame(struct ksignal *ksig) static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { - int usig =3D ksig->sig; sigset_t *set =3D sigmask_to_save(); compat_sigset_t *cset =3D (compat_sigset_t *) set; =20 @@ -773,13 +772,13 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *= regs) /* Set up the stack frame */ if (is_ia32_frame(ksig)) { if (ksig->ka.sa.sa_flags & SA_SIGINFO) - return ia32_setup_rt_frame(usig, ksig, cset, regs); + return ia32_setup_rt_frame(ksig, cset, regs); else - return ia32_setup_frame(usig, ksig, cset, regs); + return ia32_setup_frame(ksig, cset, regs); } else if (is_x32_frame(ksig)) { return x32_setup_rt_frame(ksig, cset, regs); } else { - return __setup_rt_frame(ksig->sig, ksig, set, regs); + return __setup_rt_frame(ksig, set, regs); } } =20 --=20 2.35.3 From nobody Thu Apr 30 09:38:02 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D540FC43334 for ; Mon, 6 Jun 2022 20:43:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234305AbiFFUn2 (ORCPT ); Mon, 6 Jun 2022 16:43:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234370AbiFFUmc (ORCPT ); Mon, 6 Jun 2022 16:42:32 -0400 Received: from mail-oi1-x22d.google.com (mail-oi1-x22d.google.com [IPv6:2607:f8b0:4864:20::22d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08FA5EC3D1 for ; Mon, 6 Jun 2022 13:38:50 -0700 (PDT) Received: by mail-oi1-x22d.google.com with SMTP id l81so5810859oif.9 for ; Mon, 06 Jun 2022 13:38:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BwpkThbvkxh/rjj/lCthjYx3mlhn8/KzxxJnXGD2OHA=; b=SSL2Z3v0Q1/TXhdjCDgZ4r07nHHBFwDQFsnuo4DgZJktdlDD5Jk5RSO+k/ok+uEfmz bX+DI5w0K+oBd/Zr94iY4dj0FpxC6AcEEBbTtM12T/I+7JJvVaDIb7DkFuFfL0wRYbi7 lcVH2Q1nH+6H1jnm2Bc1WatfBs9oJb5ts0z7s7iRiyaY7XWuLpgzk6NRYjn3Da3L0ggt Q/M9HVnVErPthbUocj1GOeePJ/cvm+ghPl13tfQbyrU8ssJXsdGY+SUbBdwM0LOlNgAG V5JGhT0tP1T46DMAJRdk9zm+gJIwTkSX08MUbad6FMdrDSYADPOZJYfzjESCtvqH3W1U 248A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BwpkThbvkxh/rjj/lCthjYx3mlhn8/KzxxJnXGD2OHA=; b=bjARY/UT3n2fxzlstFANDiUDUByfCmFsf8D6z6Ud9dYUei8z+NxQEqtfAn0JwxpN0V E8Qn2NJmin6Mka2/YaYiHkwdZTkzU4cnSPVvngpL1f+EdgeI4npeVrrp9feJ9iJ4UGD1 2NlEbClfsmA0hzJCuFX4MHX7tsuYTD2iQxKadTymSeoSjJaK4MoxnKY+g0ZcZB5/O+04 Zm3WULajRQEk25rHtM5KQXZvGM5xz4cvGSpDLIs6yPwYWEduv83RySflwMCFqUqDjjgK bURGd+CWoGpRZwFjbt2iZ0bB8ufc//vJqIY5NOnMG6GMOH/tAx7UrlLi1gu7jMWmlAV6 Nt3Q== X-Gm-Message-State: AOAM531C47TbF/FzkLAyhwXJ/UpiJiaJAEG9oIrNDZVdmqR+Vqg48K5k rQurEln7KwHiG3nZpokDaoQKkaWgMA== X-Google-Smtp-Source: ABdhPJzxUopmRGqTGnu9FwlgxPrvrrjfQPsdkdjIYjuQQUCjkJ3F3QyV84qIUEZWPStsuVVyfxZQRA== X-Received: by 2002:a05:6808:170a:b0:2fa:7168:392b with SMTP id bc10-20020a056808170a00b002fa7168392bmr31019896oib.84.1654547929133; Mon, 06 Jun 2022 13:38:49 -0700 (PDT) Received: from citadel.. (174-084-153-250.res.spectrum.com. [174.84.153.250]) by smtp.gmail.com with ESMTPSA id j22-20020a056808035600b0032e3cca8561sm4327188oie.21.2022.06.06.13.38.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jun 2022 13:38:48 -0700 (PDT) From: Brian Gerst To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Thomas Gleixner , Andy Lutomirski , Borislav Petkov , "H . Peter Anvin" , Peter Zijlstra , "Eric W . Biederman" , Brian Gerst Subject: [PATCH 2/8] x86/signal: Remove sigset_t parameter from frame setup functions Date: Mon, 6 Jun 2022 16:37:56 -0400 Message-Id: <20220606203802.158958-3-brgerst@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220606203802.158958-1-brgerst@gmail.com> References: <20220606203802.158958-1-brgerst@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Push down the call to sigmask_to_save() into the frame setup functions. This removes the use of compat_sigset_t outside of the compat code. Signed-off-by: Brian Gerst Acked-by: "Eric W. Biederman" --- arch/x86/ia32/ia32_signal.c | 8 ++++---- arch/x86/include/asm/fpu/signal.h | 6 ++---- arch/x86/include/asm/signal.h | 5 ----- arch/x86/kernel/signal.c | 28 ++++++++++++---------------- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 390347ab92de..b67e27685d46 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -230,9 +230,9 @@ static void __user *get_sigframe(struct ksignal *ksig, = struct pt_regs *regs, return (void __user *) sp; } =20 -int ia32_setup_frame(struct ksignal *ksig, - compat_sigset_t *set, struct pt_regs *regs) +int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs) { + compat_sigset_t *set =3D (compat_sigset_t *) sigmask_to_save(); struct sigframe_ia32 __user *frame; void __user *restorer; void __user *fp =3D NULL; @@ -296,9 +296,9 @@ int ia32_setup_frame(struct ksignal *ksig, return -EFAULT; } =20 -int ia32_setup_rt_frame(struct ksignal *ksig, - compat_sigset_t *set, struct pt_regs *regs) +int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { + compat_sigset_t *set =3D (compat_sigset_t *) sigmask_to_save(); struct rt_sigframe_ia32 __user *frame; void __user *restorer; void __user *fp =3D NULL; diff --git a/arch/x86/include/asm/fpu/signal.h b/arch/x86/include/asm/fpu/s= ignal.h index 08826ad0254d..2f255aca5622 100644 --- a/arch/x86/include/asm/fpu/signal.h +++ b/arch/x86/include/asm/fpu/signal.h @@ -14,10 +14,8 @@ # include # include struct ksignal; -int ia32_setup_rt_frame(struct ksignal *ksig, - compat_sigset_t *set, struct pt_regs *regs); -int ia32_setup_frame(struct ksignal *ksig, - compat_sigset_t *set, struct pt_regs *regs); +int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs); +int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs); #else # define user_i387_ia32_struct user_i387_struct # define user32_fxsr_struct user_fxsr_struct diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h index 2dfb5fea13af..4a4043ca6493 100644 --- a/arch/x86/include/asm/signal.h +++ b/arch/x86/include/asm/signal.h @@ -28,11 +28,6 @@ typedef struct { #define SA_IA32_ABI 0x02000000u #define SA_X32_ABI 0x01000000u =20 -#ifndef CONFIG_COMPAT -#define compat_sigset_t compat_sigset_t -typedef sigset_t compat_sigset_t; -#endif - #endif /* __ASSEMBLY__ */ #include #ifndef __ASSEMBLY__ diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 40b1373bb70b..489a0859afd2 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -324,9 +324,9 @@ static const struct { }; =20 static int -__setup_frame(struct ksignal *ksig, sigset_t *set, - struct pt_regs *regs) +__setup_frame(struct ksignal *ksig, struct pt_regs *regs) { + sigset_t *set =3D sigmask_to_save(); struct sigframe __user *frame; void __user *restorer; void __user *fp =3D NULL; @@ -379,9 +379,9 @@ __setup_frame(struct ksignal *ksig, sigset_t *set, return -EFAULT; } =20 -static int __setup_rt_frame(struct ksignal *ksig, - sigset_t *set, struct pt_regs *regs) +static int __setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { + sigset_t *set =3D sigmask_to_save(); struct rt_sigframe __user *frame; void __user *restorer; void __user *fp =3D NULL; @@ -458,9 +458,9 @@ static unsigned long frame_uc_flags(struct pt_regs *reg= s) return flags; } =20 -static int __setup_rt_frame(struct ksignal *ksig, - sigset_t *set, struct pt_regs *regs) +static int __setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { + sigset_t *set =3D sigmask_to_save(); struct rt_sigframe __user *frame; void __user *fp =3D NULL; unsigned long uc_flags; @@ -560,11 +560,10 @@ int copy_siginfo_to_user32(struct compat_siginfo __us= er *to, } #endif /* CONFIG_X86_X32_ABI */ =20 -static int x32_setup_rt_frame(struct ksignal *ksig, - compat_sigset_t *set, - struct pt_regs *regs) +static int x32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { #ifdef CONFIG_X86_X32_ABI + compat_sigset_t *set =3D (compat_sigset_t *) sigmask_to_save(); struct rt_sigframe_x32 __user *frame; unsigned long uc_flags; void __user *restorer; @@ -763,22 +762,19 @@ static inline int is_x32_frame(struct ksignal *ksig) static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { - sigset_t *set =3D sigmask_to_save(); - compat_sigset_t *cset =3D (compat_sigset_t *) set; - /* Perform fixup for the pre-signal frame. */ rseq_signal_deliver(ksig, regs); =20 /* Set up the stack frame */ if (is_ia32_frame(ksig)) { if (ksig->ka.sa.sa_flags & SA_SIGINFO) - return ia32_setup_rt_frame(ksig, cset, regs); + return ia32_setup_rt_frame(ksig, regs); else - return ia32_setup_frame(ksig, cset, regs); + return ia32_setup_frame(ksig, regs); } else if (is_x32_frame(ksig)) { - return x32_setup_rt_frame(ksig, cset, regs); + return x32_setup_rt_frame(ksig, regs); } else { - return __setup_rt_frame(ksig, set, regs); + return __setup_rt_frame(ksig, regs); } } =20 --=20 2.35.3 From nobody Thu Apr 30 09:38:02 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 84A06C43334 for ; Mon, 6 Jun 2022 20:43:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234146AbiFFUnJ (ORCPT ); Mon, 6 Jun 2022 16:43:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234244AbiFFUmc (ORCPT ); Mon, 6 Jun 2022 16:42:32 -0400 Received: from mail-oa1-x2f.google.com (mail-oa1-x2f.google.com [IPv6:2001:4860:4864:20::2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5325D1208B1 for ; Mon, 6 Jun 2022 13:38:51 -0700 (PDT) Received: by mail-oa1-x2f.google.com with SMTP id 586e51a60fabf-e656032735so20653554fac.0 for ; Mon, 06 Jun 2022 13:38:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zN7yZdXGDF9PPNDxZsgYWxX8yKA4nCi67h3WnKoi/Sc=; b=gR+ZqTNEY2oneCOOINaXerlABfVjfegVqPEAFOUx+e41iHPZqWuoSvB3U7W+hG637B SLS4OfO+8R6z0aLbzDhoxgNXz7OecFthBjJVdWzppPR3gOH3JL/lWCe7aa1CvwIeuDsz MYoQ9YA6J4efrzkkKb5UIYKUbidZoSXMxYgeXeNTaC2F4PiPpEi7hx7w7qiPuVFP1vCS c9zoMH4HmZhwPC4kHRveq3sr39ydbDioDIufjmhfcEFeLKmqok/hOSkroaESNG42C6td SR2oeM6Ys5NcAmmTaOmNWvG2vT+4hDamnw4a86phgUCcExZlVfBzAUCJqv258spBA4GY DB4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zN7yZdXGDF9PPNDxZsgYWxX8yKA4nCi67h3WnKoi/Sc=; b=h8238dM6yxZQnqM3exNY1kf/LREPnGZQ1agyFBUzOH7Ue6iXqMic7AP/SukyfjxzTW 6O5ZsAVHkZ3mNfoMfJD0orxJc9ar7fQoRbSHR8ty5IPPOuAiaABQjecwOUVbKbJmlr29 bE+5J1N7A/s0jTBjrkk1Pw9oCKDzMaTPYnSL/LyzTTTgpdZIX7bNb+CYpKwHqxfM/YNq PuLZsA+VWtWDFWIQEsOdSH2DCa79qiayqt9U5AomiLaNSrUSWA88jLufgMz8uNFd+pjx 8ATsHnhU38LvxGLpbMP0mHEj7xQO3vxVkYbd9ntqLwnEr6ZFnpMGM6wCXLlMBqpdzA0C r5PA== X-Gm-Message-State: AOAM532arabpvV07PFy/nP47Q3m+gd7HwPaGzxRI0M039Q5ij7hYhMav +QfKSkWx9C5yL42a21f7rrunhxpB6A== X-Google-Smtp-Source: ABdhPJw/XjRxHKzCBw4N3AcILogPcpEvbEODBwQq63HwujCnt98GlY2TKNISuQnTW15c0UGWqt8lVw== X-Received: by 2002:a05:6870:7009:b0:f3:4965:5b1a with SMTP id u9-20020a056870700900b000f349655b1amr14053098oae.234.1654547930552; Mon, 06 Jun 2022 13:38:50 -0700 (PDT) Received: from citadel.. (174-084-153-250.res.spectrum.com. [174.84.153.250]) by smtp.gmail.com with ESMTPSA id j22-20020a056808035600b0032e3cca8561sm4327188oie.21.2022.06.06.13.38.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jun 2022 13:38:49 -0700 (PDT) From: Brian Gerst To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Thomas Gleixner , Andy Lutomirski , Borislav Petkov , "H . Peter Anvin" , Peter Zijlstra , "Eric W . Biederman" , Brian Gerst Subject: [PATCH 3/8] signal/compat: Remove compat_sigset_t override Date: Mon, 6 Jun 2022 16:37:57 -0400 Message-Id: <20220606203802.158958-4-brgerst@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220606203802.158958-1-brgerst@gmail.com> References: <20220606203802.158958-1-brgerst@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" x86 no longer uses compat_sigset_t when CONFIG_COMPAT isn't enabled, so remove the override define. Signed-off-by: Brian Gerst Acked-by: "Eric W. Biederman" --- include/linux/compat.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/compat.h b/include/linux/compat.h index 594357881b0b..44b1736c95b5 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -126,11 +126,9 @@ struct compat_tms { =20 #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) =20 -#ifndef compat_sigset_t typedef struct { compat_sigset_word sig[_COMPAT_NSIG_WORDS]; } compat_sigset_t; -#endif =20 int set_compat_user_sigmask(const compat_sigset_t __user *umask, size_t sigsetsize); --=20 2.35.3 From nobody Thu Apr 30 09:38:02 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14DF9C433EF for ; Mon, 6 Jun 2022 20:43:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234218AbiFFUnQ (ORCPT ); Mon, 6 Jun 2022 16:43:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234393AbiFFUmc (ORCPT ); Mon, 6 Jun 2022 16:42:32 -0400 Received: from mail-oi1-x22d.google.com (mail-oi1-x22d.google.com [IPv6:2607:f8b0:4864:20::22d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 999FCED737 for ; Mon, 6 Jun 2022 13:38:52 -0700 (PDT) Received: by mail-oi1-x22d.google.com with SMTP id i66so21215273oia.11 for ; Mon, 06 Jun 2022 13:38:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mqR3X/F3Pv3CiLzjWRVRYnBoua48jzxnCD1fH10NX1o=; b=IdlaCmhNQV92UfWSRiLtS5CoqgLmkwQZd9jIk90nIai7D8mxkN9zkeAfCZLuGPsiEW gv3d4QSRbn9bLGKaRaKAu0mA9tZUlPahF8DyMngNzdPIdWCThtFmsPMTyAUHbYgv/Avo DUHpowpgnEM++fz+bTQugavl+BBGsStliPD7jeODDJZKSq0qyudYIFRkmwhXcd3Z4MFg lLYrn9s0lm/UUKoLK09ukii5DspA9LqsDpobune5GaxWg2VTZq4l/RoUgeeMjYnl7dzq La24GcfP2kg7dsxR7dSvG0gohuhv8iIWZMSiT8pkDSIH5E9haQelFYWQKXef1uAj0ZbM agRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mqR3X/F3Pv3CiLzjWRVRYnBoua48jzxnCD1fH10NX1o=; b=ac30AKGmYtLi+rf4zyCa7dc7+LT6dtsAENGZ9EDUuR2m66yC+sWnpmnzepz2MMkij+ Kctlxz8ZmyZeaUMoRGNLs+Z5OHwGw6JQXCzMJOBZnB0jYF9o8LXSeIc6gVO4pnkI1zEe 3/sKvn2JWsO7wPSQ7ziJoq+0uHfitAif/1vieUU8ox99ClIISll9UfFD+5+pypZZry83 x9jbqgpDFG86Rh60mwiu7xCpTVWVMp/Yop9mrX+rSEBs6SUjXFYZWJj8Vm4yu2n0tTBS 5+3sKo2M+ucvYL+oW/70LpYw4ZRBB7Cu9DdcbQ34CJqm6WS6gWAYpct6vPy4kLTvZYv5 Fe+Q== X-Gm-Message-State: AOAM530h4VhnIYOiczfvOSu2n/tTWBpKnaIXhzb9uOg+Bn8vdrt4ZSgE IeRLwlduR298/J//urniMjDQnQJInw== X-Google-Smtp-Source: ABdhPJzyOUqEiHvMYNpcIZyc7v1oJuOZpS/iz0xSZ2Ghr+wXo6osxkaehPKnhPHE1ZBiR7Rlef2fEg== X-Received: by 2002:a05:6808:1825:b0:32b:a1e9:fdb6 with SMTP id bh37-20020a056808182500b0032ba1e9fdb6mr31104546oib.73.1654547931735; Mon, 06 Jun 2022 13:38:51 -0700 (PDT) Received: from citadel.. (174-084-153-250.res.spectrum.com. [174.84.153.250]) by smtp.gmail.com with ESMTPSA id j22-20020a056808035600b0032e3cca8561sm4327188oie.21.2022.06.06.13.38.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jun 2022 13:38:51 -0700 (PDT) From: Brian Gerst To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Thomas Gleixner , Andy Lutomirski , Borislav Petkov , "H . Peter Anvin" , Peter Zijlstra , "Eric W . Biederman" , Brian Gerst Subject: [PATCH 4/8] x86: Remove __USER32_DS Date: Mon, 6 Jun 2022 16:37:58 -0400 Message-Id: <20220606203802.158958-5-brgerst@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220606203802.158958-1-brgerst@gmail.com> References: <20220606203802.158958-1-brgerst@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Replace all users with the equivalent __USER_DS, which will make merging native and compat code simpler. Signed-off-by: Brian Gerst Acked-by: "Eric W. Biederman" --- arch/x86/entry/entry_64_compat.S | 4 ++-- arch/x86/ia32/ia32_signal.c | 14 +++++++------- arch/x86/include/asm/elf.h | 4 ---- arch/x86/include/asm/segment.h | 1 - arch/x86/xen/xen-asm.S | 8 ++++---- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_com= pat.S index d1052742ad0c..cd51d1f70382 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -59,7 +59,7 @@ SYM_CODE_START(entry_SYSENTER_compat) movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp =20 /* Construct struct pt_regs on stack */ - pushq $__USER32_DS /* pt_regs->ss */ + pushq $__USER_DS /* pt_regs->ss */ pushq $0 /* pt_regs->sp =3D 0 (placeholder) */ =20 /* @@ -192,7 +192,7 @@ SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_= GLOBAL) ANNOTATE_NOENDBR =20 /* Construct struct pt_regs on stack */ - pushq $__USER32_DS /* pt_regs->ss */ + pushq $__USER_DS /* pt_regs->ss */ pushq %r8 /* pt_regs->sp */ pushq %r11 /* pt_regs->flags */ pushq $__USER32_CS /* pt_regs->cs */ diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index b67e27685d46..a78885e3e85d 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -212,7 +212,7 @@ static void __user *get_sigframe(struct ksignal *ksig, = struct pt_regs *regs, if (ksig->ka.sa.sa_flags & SA_ONSTACK) sp =3D sigsp(sp, ksig); /* This is the legacy signal stack switching. */ - else if (regs->ss !=3D __USER32_DS && + else if (regs->ss !=3D __USER_DS && !(ksig->ka.sa.sa_flags & SA_RESTORER) && ksig->ka.sa.sa_restorer) sp =3D (unsigned long) ksig->ka.sa.sa_restorer; @@ -284,11 +284,11 @@ int ia32_setup_frame(struct ksignal *ksig, struct pt_= regs *regs) regs->dx =3D 0; regs->cx =3D 0; =20 - loadsegment(ds, __USER32_DS); - loadsegment(es, __USER32_DS); + loadsegment(ds, __USER_DS); + loadsegment(es, __USER_DS); =20 regs->cs =3D __USER32_CS; - regs->ss =3D __USER32_DS; + regs->ss =3D __USER_DS; =20 return 0; Efault: @@ -361,11 +361,11 @@ int ia32_setup_rt_frame(struct ksignal *ksig, struct = pt_regs *regs) regs->dx =3D (unsigned long) &frame->info; regs->cx =3D (unsigned long) &frame->uc; =20 - loadsegment(ds, __USER32_DS); - loadsegment(es, __USER32_DS); + loadsegment(ds, __USER_DS); + loadsegment(es, __USER_DS); =20 regs->cs =3D __USER32_CS; - regs->ss =3D __USER32_DS; + regs->ss =3D __USER_DS; =20 return 0; Efault: diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index cb0ff1055ab1..be8b58da63b9 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -152,10 +152,6 @@ do { \ (elf_check_arch_ia32(x) || \ (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine =3D=3D EM_X86_64)) =20 -#if __USER32_DS !=3D __USER_DS -# error "The following code assumes __USER32_DS =3D=3D __USER_DS" -#endif - static inline void elf_common_init(struct thread_struct *t, struct pt_regs *regs, const u16 ds) { diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 2e7890dd58a4..e056c29dfcda 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -210,7 +210,6 @@ #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8) #define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8 + 3) #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3) -#define __USER32_DS __USER_DS #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8 + 3) #define __CPUNODE_SEG (GDT_ENTRY_CPUNODE*8 + 3) =20 diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index caa9bc2fa100..350174cf9d71 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S @@ -262,10 +262,10 @@ SYM_CODE_START(xen_syscall32_target) =20 /* * Neither Xen nor the kernel really knows what the old SS and - * CS were. The kernel expects __USER32_DS and __USER32_CS, so + * CS were. The kernel expects __USER_DS and __USER32_CS, so * report those values even though Xen will guess its own values. */ - movq $__USER32_DS, 4*8(%rsp) + movq $__USER_DS, 4*8(%rsp) movq $__USER32_CS, 1*8(%rsp) =20 jmp entry_SYSCALL_compat_after_hwframe @@ -284,10 +284,10 @@ SYM_CODE_START(xen_sysenter_target) =20 /* * Neither Xen nor the kernel really knows what the old SS and - * CS were. The kernel expects __USER32_DS and __USER32_CS, so + * CS were. The kernel expects __USER_DS and __USER32_CS, so * report those values even though Xen will guess its own values. */ - movq $__USER32_DS, 4*8(%rsp) + movq $__USER_DS, 4*8(%rsp) movq $__USER32_CS, 1*8(%rsp) =20 jmp entry_SYSENTER_compat_after_hwframe --=20 2.35.3 From nobody Thu Apr 30 09:38:02 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09288C43334 for ; Mon, 6 Jun 2022 20:43:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234372AbiFFUnO (ORCPT ); Mon, 6 Jun 2022 16:43:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233931AbiFFUmr (ORCPT ); Mon, 6 Jun 2022 16:42:47 -0400 Received: from mail-oo1-xc30.google.com (mail-oo1-xc30.google.com [IPv6:2607:f8b0:4864:20::c30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC247122959 for ; Mon, 6 Jun 2022 13:38:53 -0700 (PDT) Received: by mail-oo1-xc30.google.com with SMTP id x11-20020a4a800b000000b0041a5b6d7c42so2877945oof.10 for ; Mon, 06 Jun 2022 13:38:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ffXa0Srpu9DUG1vR5Q2Yy9d85Kw9mLdPILu27FpkxDY=; b=PIUQ+iLu7lzRky4kxfFQyAkAzQG8t/ZxMGdARewq0AfvvwOIfUACOftWXw6JLRqzta ovkqGdhOaaC7OXmICULWuNsDwNVpAQjVSDmiSNBcyo0YnuJaFoVdqDQqZHJP/zJfFHlz UhmrX6t2ZLw9j6WCqF4kuuEM1ARneVZ5dWVYGIfM2Xjqwz8i3yWd6FVw2JsU0iVT6iCG Eazq+wGYTalQdbcowHFu+keOUVcLeL2dXpoj4efct6/yz4YN4NeLxHmyedGADbIAi8dT ybafNlI/J0uJjdpXIW2xfMnF8G7tpElR36Fl4dL5g0HMXUGKAHTwgiLkXr0mjpCCBJKR SANw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ffXa0Srpu9DUG1vR5Q2Yy9d85Kw9mLdPILu27FpkxDY=; b=2KE1Dg8tQx7ldKy4+X3C1lTB6IbXBR80eY/KRP0ZDzSldO87IUyN6zvVrwLgcNYI0j g9y4xp0Iq/HlMfBkHegyB1y2E9mM1ZuHBH9eolZrW75K/4jmKnRJaq4YJamtWLwqT77Z 1NRtobK+gFSTXRlWnaf3l+hA5usiCkXeH4QeJDgoFDjXEBSN9/wviLHXdNVz8GcUzXw1 HoVHWoH6UqU76QmwHZWTDKLpSxRBE07AEFzn/7a8y2SUrgr2tvnOFr8VlNwR72rRqW18 W9/KDCnvqJSsehG5kXl0ndkB0uJqED624hBwSpgkmk7JRInnzTjqkafmeTn2BuHo87LE LZoQ== X-Gm-Message-State: AOAM530S/VMLe7UYVSXoHz43GKou1ZPKjt5kPLqcdaqIapdeETqdCvo4 wPvKzw7eZynRh4h02G5hcLJeqHaj+Q== X-Google-Smtp-Source: ABdhPJzFIdb/tmerI3hQmpnIL3gi5FSrZcMbhq86a4TB5s3AKiP+u4uGgt2JKuSEkthc0exRIOWthQ== X-Received: by 2002:a4a:11c7:0:b0:41a:c989:659e with SMTP id 190-20020a4a11c7000000b0041ac989659emr10821998ooc.38.1654547932953; Mon, 06 Jun 2022 13:38:52 -0700 (PDT) Received: from citadel.. (174-084-153-250.res.spectrum.com. [174.84.153.250]) by smtp.gmail.com with ESMTPSA id j22-20020a056808035600b0032e3cca8561sm4327188oie.21.2022.06.06.13.38.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jun 2022 13:38:52 -0700 (PDT) From: Brian Gerst To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Thomas Gleixner , Andy Lutomirski , Borislav Petkov , "H . Peter Anvin" , Peter Zijlstra , "Eric W . Biederman" , Brian Gerst Subject: [PATCH 5/8] x86/signal: Merge get_sigframe() Date: Mon, 6 Jun 2022 16:37:59 -0400 Message-Id: <20220606203802.158958-6-brgerst@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220606203802.158958-1-brgerst@gmail.com> References: <20220606203802.158958-1-brgerst@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Adapt the native get_sigframe() function so that the compat signal code can use it. Signed-off-by: Brian Gerst Acked-by: "Eric W. Biederman" --- arch/x86/ia32/ia32_signal.c | 34 ------------- arch/x86/include/asm/sighandling.h | 4 ++ arch/x86/kernel/signal.c | 80 ++++++++++++++---------------- 3 files changed, 42 insertions(+), 76 deletions(-) diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index a78885e3e85d..e28421f53d44 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -196,40 +196,6 @@ do { \ goto label; \ } while(0) =20 -/* - * Determine which stack to use.. - */ -static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *reg= s, - size_t frame_size, - void __user **fpstate) -{ - unsigned long sp, fx_aligned, math_size; - - /* Default to using normal stack */ - sp =3D regs->sp; - - /* This is the X/Open sanctioned signal stack switching. */ - if (ksig->ka.sa.sa_flags & SA_ONSTACK) - sp =3D sigsp(sp, ksig); - /* This is the legacy signal stack switching. */ - else if (regs->ss !=3D __USER_DS && - !(ksig->ka.sa.sa_flags & SA_RESTORER) && - ksig->ka.sa.sa_restorer) - sp =3D (unsigned long) ksig->ka.sa.sa_restorer; - - sp =3D fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size); - *fpstate =3D (struct _fpstate_32 __user *) sp; - if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned, - math_size)) - return (void __user *) -1L; - - sp -=3D frame_size; - /* Align the stack pointer according to the i386 ABI, - * i.e. so that on function entry ((sp + 4) & 15) =3D=3D 0. */ - sp =3D ((sp + 4) & -16ul) - 4; - return (void __user *) sp; -} - int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs) { compat_sigset_t *set =3D (compat_sigset_t *) sigmask_to_save(); diff --git a/arch/x86/include/asm/sighandling.h b/arch/x86/include/asm/sigh= andling.h index 65e667279e0f..c9e9784efe38 100644 --- a/arch/x86/include/asm/sighandling.h +++ b/arch/x86/include/asm/sighandling.h @@ -15,4 +15,8 @@ =20 void signal_fault(struct pt_regs *regs, void __user *frame, char *where); =20 +void __user * +get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size, + void __user **fpstate); + #endif /* _ASM_X86_SIGHANDLING_H */ diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 489a0859afd2..890ca0523570 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -48,6 +48,23 @@ #include #include =20 +static inline int is_ia32_compat_frame(struct ksignal *ksig) +{ + return IS_ENABLED(CONFIG_IA32_EMULATION) && + ksig->ka.sa.sa_flags & SA_IA32_ABI; +} + +static inline int is_ia32_frame(struct ksignal *ksig) +{ + return IS_ENABLED(CONFIG_X86_32) || is_ia32_compat_frame(ksig); +} + +static inline int is_x32_frame(struct ksignal *ksig) +{ + return IS_ENABLED(CONFIG_X86_X32_ABI) && + ksig->ka.sa.sa_flags & SA_X32_ABI; +} + #ifdef CONFIG_X86_64 /* * If regs->ss will cause an IRET fault, change it. Otherwise leave it @@ -223,24 +240,12 @@ do { \ /* * Determine which stack to use.. */ -static unsigned long align_sigframe(unsigned long sp) -{ -#ifdef CONFIG_X86_32 - /* - * Align the stack pointer according to the i386 ABI, - * i.e. so that on function entry ((sp + 4) & 15) =3D=3D 0. - */ - sp =3D ((sp + 4) & -FRAME_ALIGNMENT) - 4; -#else /* !CONFIG_X86_32 */ - sp =3D round_down(sp, FRAME_ALIGNMENT) - 8; -#endif - return sp; -} - -static void __user * -get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_si= ze, +void __user * +get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size, void __user **fpstate) { + struct k_sigaction *ka =3D &ksig->ka; + int ia32_frame =3D is_ia32_frame(ksig); /* Default to using normal stack */ bool nested_altstack =3D on_sig_stack(regs->sp); bool entering_altstack =3D false; @@ -249,7 +254,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *re= gs, size_t frame_size, unsigned long buf_fx =3D 0; =20 /* redzone */ - if (IS_ENABLED(CONFIG_X86_64)) + if (!ia32_frame) sp -=3D 128; =20 /* This is the X/Open sanctioned signal stack switching. */ @@ -263,7 +268,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *re= gs, size_t frame_size, sp =3D current->sas_ss_sp + current->sas_ss_size; entering_altstack =3D true; } - } else if (IS_ENABLED(CONFIG_X86_32) && + } else if (ia32_frame && !nested_altstack && regs->ss !=3D __USER_DS && !(ka->sa.sa_flags & SA_RESTORER) && @@ -273,11 +278,19 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *= regs, size_t frame_size, entering_altstack =3D true; } =20 - sp =3D fpu__alloc_mathframe(sp, IS_ENABLED(CONFIG_X86_32), - &buf_fx, &math_size); + sp =3D fpu__alloc_mathframe(sp, ia32_frame, &buf_fx, &math_size); *fpstate =3D (void __user *)sp; =20 - sp =3D align_sigframe(sp - frame_size); + sp -=3D frame_size; + + if (ia32_frame) + /* + * Align the stack pointer according to the i386 ABI, + * i.e. so that on function entry ((sp + 4) & 15) =3D=3D 0. + */ + sp =3D ((sp + 4) & -FRAME_ALIGNMENT) - 4; + else + sp =3D round_down(sp, FRAME_ALIGNMENT) - 8; =20 /* * If we are on the alternate signal stack and would overflow it, don't. @@ -331,7 +344,7 @@ __setup_frame(struct ksignal *ksig, struct pt_regs *reg= s) void __user *restorer; void __user *fp =3D NULL; =20 - frame =3D get_sigframe(&ksig->ka, regs, sizeof(*frame), &fp); + frame =3D get_sigframe(ksig, regs, sizeof(*frame), &fp); =20 if (!user_access_begin(frame, sizeof(*frame))) return -EFAULT; @@ -386,7 +399,7 @@ static int __setup_rt_frame(struct ksignal *ksig, struc= t pt_regs *regs) void __user *restorer; void __user *fp =3D NULL; =20 - frame =3D get_sigframe(&ksig->ka, regs, sizeof(*frame), &fp); + frame =3D get_sigframe(ksig, regs, sizeof(*frame), &fp); =20 if (!user_access_begin(frame, sizeof(*frame))) return -EFAULT; @@ -469,7 +482,7 @@ static int __setup_rt_frame(struct ksignal *ksig, struc= t pt_regs *regs) if (!(ksig->ka.sa.sa_flags & SA_RESTORER)) return -EFAULT; =20 - frame =3D get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp); + frame =3D get_sigframe(ksig, regs, sizeof(struct rt_sigframe), &fp); uc_flags =3D frame_uc_flags(regs); =20 if (!user_access_begin(frame, sizeof(*frame))) @@ -572,7 +585,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig, str= uct pt_regs *regs) if (!(ksig->ka.sa.sa_flags & SA_RESTORER)) return -EFAULT; =20 - frame =3D get_sigframe(&ksig->ka, regs, sizeof(*frame), &fp); + frame =3D get_sigframe(ksig, regs, sizeof(*frame), &fp); =20 uc_flags =3D frame_uc_flags(regs); =20 @@ -742,23 +755,6 @@ unsigned long get_sigframe_size(void) return max_frame_size; } =20 -static inline int is_ia32_compat_frame(struct ksignal *ksig) -{ - return IS_ENABLED(CONFIG_IA32_EMULATION) && - ksig->ka.sa.sa_flags & SA_IA32_ABI; -} - -static inline int is_ia32_frame(struct ksignal *ksig) -{ - return IS_ENABLED(CONFIG_X86_32) || is_ia32_compat_frame(ksig); -} - -static inline int is_x32_frame(struct ksignal *ksig) -{ - return IS_ENABLED(CONFIG_X86_X32_ABI) && - ksig->ka.sa.sa_flags & SA_X32_ABI; -} - static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { --=20 2.35.3 From nobody Thu Apr 30 09:38:02 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF57DC433EF for ; Mon, 6 Jun 2022 20:43:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234327AbiFFUnf (ORCPT ); Mon, 6 Jun 2022 16:43:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234181AbiFFUms (ORCPT ); Mon, 6 Jun 2022 16:42:48 -0400 Received: from mail-oi1-x231.google.com (mail-oi1-x231.google.com [IPv6:2607:f8b0:4864:20::231]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB041122B6C for ; Mon, 6 Jun 2022 13:38:54 -0700 (PDT) Received: by mail-oi1-x231.google.com with SMTP id q11so5934396oih.10 for ; Mon, 06 Jun 2022 13:38:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=MjojrqCS6xuxZg5uh79IanvQVrJGjYSajetX/zMk8e0=; b=CyCxT5CceEiDwirzG5qf3Az/veov1N3xQFxd+GDt5IeT6iXLElSuuJiVfLgT0IH+bQ sePYEi9fuWmV4kN01dV49Mzcq72MvZPPzVTDOxFRvOPYVxmc3piQ1KAvTYzzgjLDC2bn yxW7w96cbKcD+tg2oUfzWi9exLkmI8Nm55adKYpL4h6CIi5GVmE1077zh36ZGnGdw3+8 mxWJTnk+Gb6fC+cBYkrVOh+JwXFj4APDuUWg+5wDgFzxOXax7P4jo00om8Ch8rxgwIvx tKwbXmqNcbRjYnPCLUfzEy3ZbFdQNTjwehaHQMKLjR7u/XghCI1493zfPyicVlIlibba 3cUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MjojrqCS6xuxZg5uh79IanvQVrJGjYSajetX/zMk8e0=; b=0wwR88+C8EALD2biq7U0g7371il+/pwMZmTzw97epawRAJc8jVULGrYSX6vtzGInGu m3MihlEhUS1ud8YwOWDiyMJHJVfqTcL6ykenqYwL5zEq98hYKCJ0EAO9R2JG/lWvjFy7 myknGpMfPEf1v6OjWiFDs+MdwenbOpMoVHOetdPCzVjyVUztMlCk8fnyOhjn93Ng0LBB q80eRXVsfE6RDhdpJJgvz9vRZRBADbuP6Q3AdMWpXHEq2g7vR39Z1wK2BqgDcZUHxofA Q3nYngn2La1jNQTPsV+oCCw96eDEfd6Q7L2pyTLcte2YrmSCo9sIcBl1m/rWuNtap5ys x81A== X-Gm-Message-State: AOAM532DHyqfrKeE3NUxHp0tykZVHnI8dK0yvz+XibRMTa6oB6g2Wc4Q ek9mtfmSHnuz2YI7oYZJrW4+8BXWXg== X-Google-Smtp-Source: ABdhPJzAQsD3jKRw5cnBZKKBmNFoGEUDVWEOICCfydL1u8jgpnmV5AIKp3vx1gXsE3b6VNt2lFTThA== X-Received: by 2002:a05:6808:f91:b0:32b:5c6f:4cce with SMTP id o17-20020a0568080f9100b0032b5c6f4ccemr15325454oiw.274.1654547934113; Mon, 06 Jun 2022 13:38:54 -0700 (PDT) Received: from citadel.. (174-084-153-250.res.spectrum.com. [174.84.153.250]) by smtp.gmail.com with ESMTPSA id j22-20020a056808035600b0032e3cca8561sm4327188oie.21.2022.06.06.13.38.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jun 2022 13:38:53 -0700 (PDT) From: Brian Gerst To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Thomas Gleixner , Andy Lutomirski , Borislav Petkov , "H . Peter Anvin" , Peter Zijlstra , "Eric W . Biederman" , Brian Gerst Subject: [PATCH 6/8] x86/signal: Add ABI prefixes to frame setup functions Date: Mon, 6 Jun 2022 16:38:00 -0400 Message-Id: <20220606203802.158958-7-brgerst@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220606203802.158958-1-brgerst@gmail.com> References: <20220606203802.158958-1-brgerst@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add ABI prefixes to the frame setup functions that didn't already have them. To avoid compiler warnings and prepare for moving these functions to separate files, make them non-static. Signed-off-by: Brian Gerst Acked-by: "Eric W. Biederman" --- arch/x86/include/asm/fpu/signal.h | 5 ----- arch/x86/include/asm/sighandling.h | 5 +++++ arch/x86/kernel/signal.c | 18 +++++++----------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/fpu/signal.h b/arch/x86/include/asm/fpu/s= ignal.h index 2f255aca5622..611fa41711af 100644 --- a/arch/x86/include/asm/fpu/signal.h +++ b/arch/x86/include/asm/fpu/signal.h @@ -13,14 +13,9 @@ #ifdef CONFIG_X86_64 # include # include -struct ksignal; -int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs); -int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs); #else # define user_i387_ia32_struct user_i387_struct # define user32_fxsr_struct user_fxsr_struct -# define ia32_setup_frame __setup_frame -# define ia32_setup_rt_frame __setup_rt_frame #endif =20 extern void convert_from_fxsr(struct user_i387_ia32_struct *env, diff --git a/arch/x86/include/asm/sighandling.h b/arch/x86/include/asm/sigh= andling.h index c9e9784efe38..e770c4fc47f4 100644 --- a/arch/x86/include/asm/sighandling.h +++ b/arch/x86/include/asm/sighandling.h @@ -19,4 +19,9 @@ void __user * get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size, void __user **fpstate); =20 +int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs); +int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs); +int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs); +int x32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs); + #endif /* _ASM_X86_SIGHANDLING_H */ diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 890ca0523570..0511e050d24a 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -336,8 +336,7 @@ static const struct { 0 }; =20 -static int -__setup_frame(struct ksignal *ksig, struct pt_regs *regs) +int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *set =3D sigmask_to_save(); struct sigframe __user *frame; @@ -392,7 +391,7 @@ __setup_frame(struct ksignal *ksig, struct pt_regs *reg= s) return -EFAULT; } =20 -static int __setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) +int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *set =3D sigmask_to_save(); struct rt_sigframe __user *frame; @@ -471,7 +470,7 @@ static unsigned long frame_uc_flags(struct pt_regs *reg= s) return flags; } =20 -static int __setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) +int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *set =3D sigmask_to_save(); struct rt_sigframe __user *frame; @@ -571,11 +570,9 @@ int copy_siginfo_to_user32(struct compat_siginfo __use= r *to, return x32_copy_siginfo_to_user(to, from); return __copy_siginfo_to_user32(to, from); } -#endif /* CONFIG_X86_X32_ABI */ =20 -static int x32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) +int x32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { -#ifdef CONFIG_X86_X32_ABI compat_sigset_t *set =3D (compat_sigset_t *) sigmask_to_save(); struct rt_sigframe_x32 __user *frame; unsigned long uc_flags; @@ -622,15 +619,14 @@ static int x32_setup_rt_frame(struct ksignal *ksig, s= truct pt_regs *regs) =20 regs->cs =3D __USER_CS; regs->ss =3D __USER_DS; -#endif /* CONFIG_X86_X32_ABI */ =20 return 0; -#ifdef CONFIG_X86_X32_ABI + Efault: user_access_end(); return -EFAULT; -#endif } +#endif /* CONFIG_X86_X32_ABI */ =20 /* * Do a signal return; undo the signal stack. @@ -770,7 +766,7 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *re= gs) } else if (is_x32_frame(ksig)) { return x32_setup_rt_frame(ksig, regs); } else { - return __setup_rt_frame(ksig, regs); + return x64_setup_rt_frame(ksig, regs); } } =20 --=20 2.35.3 From nobody Thu Apr 30 09:38:02 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C7D4C433EF for ; Mon, 6 Jun 2022 20:43:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232799AbiFFUnj (ORCPT ); Mon, 6 Jun 2022 16:43:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234219AbiFFUmt (ORCPT ); Mon, 6 Jun 2022 16:42:49 -0400 Received: from mail-oi1-x22e.google.com (mail-oi1-x22e.google.com [IPv6:2607:f8b0:4864:20::22e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 473401238AC for ; Mon, 6 Jun 2022 13:38:56 -0700 (PDT) Received: by mail-oi1-x22e.google.com with SMTP id s124so3134137oia.0 for ; Mon, 06 Jun 2022 13:38:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OL+TIMQawJULWoHOFD9o6u7skDxbFg5kN3WkY6imDKw=; b=E23L0GB/iPJMFxfQgpNYcb9nXgjW69zmuHnYI0oV9nam6JU0td5eo4SN5et6B8eYJM yFKdqn224YDQCoWJ1oUoBn5sQyw17spsPUC9JusNFfXOGzHpzLwHv2pOOtTFYPsmsCfQ EyhzwUxaFaBUh9gGaa9I24zFOgGFxAedIHQF1MWQ7tFX1pIdmyTMw2s9fB+DOKjupX+Z Z+cza+8jWfknmDISkc059a/fVqYtqR9sMSVnWYt783cFUgI6WD1pB5U9IBbqSxZMYDOo I4oFBh2xlMgRUxwc0OYETkqUjSJxlMj92EopjvO9mu4qI4vk3kut/O2rM+hU6k6qqSzX p8sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OL+TIMQawJULWoHOFD9o6u7skDxbFg5kN3WkY6imDKw=; b=gUbeeYoW41uGQai4x2DXhJlOHL+8oFOpTlvC7MsctsdVCr2uq90/OVnmVzp7hJBcil UijuC3YiZYTm1vJohweeaugrse9sLWCN6/PNP1o8jPZFjgrtokqirrYR3M1butC9YSdx j18yJnKMRxbCo0bZ5CsFF97X0AbkU1dww4QsYU7wAxm8h0l+Uk8zh2QrqihzLkHCOnxW PDtuhAn9gZbmjyMSB9EM/l9gvmohO1lOBcI/BCanjwKVRRvgxoobqJENZ/JhQ31JuqHG dWnIGiiOzWQ5KNC/8M7LZYFXgWAHF0S2uamMWrKEBq0Xji0u3DR0Sx50yQrtlCAVBJqv ySsA== X-Gm-Message-State: AOAM530FgyOJxlK23aDkKgB+DrHuqLHvotcVqNvcLzk1Rbbaxp5QGDBC ZRZuVcdBDCnYsTZ4xI6mp0aXSXyYUQ== X-Google-Smtp-Source: ABdhPJzwijnPlj7T5t5Ac/cRAspi0q/AMsrJlhdGbJX4A0L2oyrd0gz3lWLCLlrkEJVqMw12fEeYIw== X-Received: by 2002:a05:6808:1202:b0:2f9:c7b4:fd56 with SMTP id a2-20020a056808120200b002f9c7b4fd56mr15143122oil.55.1654547935166; Mon, 06 Jun 2022 13:38:55 -0700 (PDT) Received: from citadel.. (174-084-153-250.res.spectrum.com. [174.84.153.250]) by smtp.gmail.com with ESMTPSA id j22-20020a056808035600b0032e3cca8561sm4327188oie.21.2022.06.06.13.38.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jun 2022 13:38:54 -0700 (PDT) From: Brian Gerst To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Thomas Gleixner , Andy Lutomirski , Borislav Petkov , "H . Peter Anvin" , Peter Zijlstra , "Eric W . Biederman" , Brian Gerst Subject: [PATCH 7/8] x86/signal/32: Merge native and compat 32-bit signal code Date: Mon, 6 Jun 2022 16:38:01 -0400 Message-Id: <20220606203802.158958-8-brgerst@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220606203802.158958-1-brgerst@gmail.com> References: <20220606203802.158958-1-brgerst@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" There are significant differences between signal handling on 32-bit vs. 64-bit, like different structure layouts and legacy syscalls. Instead of duplicating that code for native and compat, merge both versions into one file. Signed-off-by: Brian Gerst Acked-by: "Eric W. Biederman" --- arch/x86/ia32/Makefile | 2 - arch/x86/include/asm/segment.h | 1 + arch/x86/kernel/Makefile | 4 +- arch/x86/kernel/signal.c | 219 +----------------- .../ia32_signal.c =3D> kernel/signal_32.c} | 59 ++++- include/linux/syscalls.h | 2 + 6 files changed, 60 insertions(+), 227 deletions(-) rename arch/x86/{ia32/ia32_signal.c =3D> kernel/signal_32.c} (86%) diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile index e481056698de..333556a86b2a 100644 --- a/arch/x86/ia32/Makefile +++ b/arch/x86/ia32/Makefile @@ -3,7 +3,5 @@ # Makefile for the ia32 kernel emulation subsystem. # =20 -obj-$(CONFIG_IA32_EMULATION) :=3D ia32_signal.o - audit-class-$(CONFIG_AUDIT) :=3D audit.o obj-$(CONFIG_IA32_EMULATION) +=3D $(audit-class-y) diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index e056c29dfcda..c390a672d560 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -135,6 +135,7 @@ #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8) #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3) #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8 + 3) +#define __USER32_CS __USER_CS #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS*8) =20 /* segment for calling fn: */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 03364dc40d8d..4aa1bd55a362 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -57,8 +57,8 @@ obj-y +=3D setup.o x86_init.o i8259.o irqinit.o obj-$(CONFIG_JUMP_LABEL) +=3D jump_label.o obj-$(CONFIG_IRQ_WORK) +=3D irq_work.o obj-y +=3D probe_roms.o -obj-$(CONFIG_X86_32) +=3D sys_ia32.o -obj-$(CONFIG_IA32_EMULATION) +=3D sys_ia32.o +obj-$(CONFIG_X86_32) +=3D sys_ia32.o signal_32.o +obj-$(CONFIG_IA32_EMULATION) +=3D sys_ia32.o signal_32.o obj-$(CONFIG_X86_64) +=3D sys_x86_64.o obj-$(CONFIG_X86_ESPFIX64) +=3D espfix_64.o obj-$(CONFIG_SYSFS) +=3D ksysfs.o diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 0511e050d24a..962cfd835c90 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -92,10 +92,6 @@ static void force_valid_ss(struct pt_regs *regs) ar !=3D (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA_EXPDOWN)) regs->ss =3D __USER_DS; } -# define CONTEXT_COPY_SIZE offsetof(struct sigcontext, reserved1) -#else -# define CONTEXT_COPY_SIZE sizeof(struct sigcontext) -#endif =20 static bool restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, @@ -106,16 +102,9 @@ static bool restore_sigcontext(struct pt_regs *regs, /* Always make any pending restarted system calls return -EINTR */ current->restart_block.fn =3D do_no_restart_syscall; =20 - if (copy_from_user(&sc, usc, CONTEXT_COPY_SIZE)) + if (copy_from_user(&sc, usc, offsetof(struct sigcontext, reserved1))) return false; =20 -#ifdef CONFIG_X86_32 - loadsegment(gs, sc.gs); - regs->fs =3D sc.fs; - regs->es =3D sc.es; - regs->ds =3D sc.ds; -#endif /* CONFIG_X86_32 */ - regs->bx =3D sc.bx; regs->cx =3D sc.cx; regs->dx =3D sc.dx; @@ -125,8 +114,6 @@ static bool restore_sigcontext(struct pt_regs *regs, regs->ax =3D sc.ax; regs->sp =3D sc.sp; regs->ip =3D sc.ip; - -#ifdef CONFIG_X86_64 regs->r8 =3D sc.r8; regs->r9 =3D sc.r9; regs->r10 =3D sc.r10; @@ -135,7 +122,6 @@ static bool restore_sigcontext(struct pt_regs *regs, regs->r13 =3D sc.r13; regs->r14 =3D sc.r14; regs->r15 =3D sc.r15; -#endif /* CONFIG_X86_64 */ =20 /* Get CS/SS and force CPL3 */ regs->cs =3D sc.cs | 0x03; @@ -145,33 +131,20 @@ static bool restore_sigcontext(struct pt_regs *regs, /* disable syscall checks */ regs->orig_ax =3D -1; =20 -#ifdef CONFIG_X86_64 /* * Fix up SS if needed for the benefit of old DOSEMU and * CRIU. */ if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && user_64bit_mode(regs))) force_valid_ss(regs); -#endif =20 - return fpu__restore_sig((void __user *)sc.fpstate, - IS_ENABLED(CONFIG_X86_32)); + return fpu__restore_sig((void __user *)sc.fpstate, 0); } =20 static __always_inline int __unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpsta= te, struct pt_regs *regs, unsigned long mask) { -#ifdef CONFIG_X86_32 - unsigned int gs; - savesegment(gs, gs); - - unsafe_put_user(gs, (unsigned int __user *)&sc->gs, Efault); - unsafe_put_user(regs->fs, (unsigned int __user *)&sc->fs, Efault); - unsafe_put_user(regs->es, (unsigned int __user *)&sc->es, Efault); - unsafe_put_user(regs->ds, (unsigned int __user *)&sc->ds, Efault); -#endif /* CONFIG_X86_32 */ - unsafe_put_user(regs->di, &sc->di, Efault); unsafe_put_user(regs->si, &sc->si, Efault); unsafe_put_user(regs->bp, &sc->bp, Efault); @@ -180,7 +153,6 @@ __unsafe_setup_sigcontext(struct sigcontext __user *sc,= void __user *fpstate, unsafe_put_user(regs->dx, &sc->dx, Efault); unsafe_put_user(regs->cx, &sc->cx, Efault); unsafe_put_user(regs->ax, &sc->ax, Efault); -#ifdef CONFIG_X86_64 unsafe_put_user(regs->r8, &sc->r8, Efault); unsafe_put_user(regs->r9, &sc->r9, Efault); unsafe_put_user(regs->r10, &sc->r10, Efault); @@ -189,23 +161,15 @@ __unsafe_setup_sigcontext(struct sigcontext __user *s= c, void __user *fpstate, unsafe_put_user(regs->r13, &sc->r13, Efault); unsafe_put_user(regs->r14, &sc->r14, Efault); unsafe_put_user(regs->r15, &sc->r15, Efault); -#endif /* CONFIG_X86_64 */ =20 unsafe_put_user(current->thread.trap_nr, &sc->trapno, Efault); unsafe_put_user(current->thread.error_code, &sc->err, Efault); unsafe_put_user(regs->ip, &sc->ip, Efault); -#ifdef CONFIG_X86_32 - unsafe_put_user(regs->cs, (unsigned int __user *)&sc->cs, Efault); - unsafe_put_user(regs->flags, &sc->flags, Efault); - unsafe_put_user(regs->sp, &sc->sp_at_signal, Efault); - unsafe_put_user(regs->ss, (unsigned int __user *)&sc->ss, Efault); -#else /* !CONFIG_X86_32 */ unsafe_put_user(regs->flags, &sc->flags, Efault); unsafe_put_user(regs->cs, &sc->cs, Efault); unsafe_put_user(0, &sc->gs, Efault); unsafe_put_user(0, &sc->fs, Efault); unsafe_put_user(regs->ss, &sc->ss, Efault); -#endif /* CONFIG_X86_32 */ =20 unsafe_put_user(fpstate, (unsigned long __user *)&sc->fpstate, Efault); =20 @@ -228,6 +192,8 @@ do { \ (__u64 __user *)&(frame)->uc.uc_sigmask, \ label) =20 +#endif /* CONFIG_X86_64 */ + /* * Set up a signal frame. */ @@ -313,148 +279,7 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *re= gs, size_t frame_size, return (void __user *)sp; } =20 -#ifdef CONFIG_X86_32 -static const struct { - u16 poplmovl; - u32 val; - u16 int80; -} __attribute__((packed)) retcode =3D { - 0xb858, /* popl %eax; movl $..., %eax */ - __NR_sigreturn, - 0x80cd, /* int $0x80 */ -}; - -static const struct { - u8 movl; - u32 val; - u16 int80; - u8 pad; -} __attribute__((packed)) rt_retcode =3D { - 0xb8, /* movl $..., %eax */ - __NR_rt_sigreturn, - 0x80cd, /* int $0x80 */ - 0 -}; - -int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs) -{ - sigset_t *set =3D sigmask_to_save(); - struct sigframe __user *frame; - void __user *restorer; - void __user *fp =3D NULL; - - frame =3D get_sigframe(ksig, regs, sizeof(*frame), &fp); - - if (!user_access_begin(frame, sizeof(*frame))) - return -EFAULT; - - unsafe_put_user(ksig->sig, &frame->sig, Efault); - unsafe_put_sigcontext(&frame->sc, fp, regs, set, Efault); - unsafe_put_user(set->sig[1], &frame->extramask[0], Efault); - if (current->mm->context.vdso) - restorer =3D current->mm->context.vdso + - vdso_image_32.sym___kernel_sigreturn; - else - restorer =3D &frame->retcode; - if (ksig->ka.sa.sa_flags & SA_RESTORER) - restorer =3D ksig->ka.sa.sa_restorer; - - /* Set up to return from userspace. */ - unsafe_put_user(restorer, &frame->pretcode, Efault); - - /* - * This is popl %eax ; movl $__NR_sigreturn, %eax ; int $0x80 - * - * WE DO NOT USE IT ANY MORE! It's only left here for historical - * reasons and because gdb uses it as a signature to notice - * signal handler stack frames. - */ - unsafe_put_user(*((u64 *)&retcode), (u64 *)frame->retcode, Efault); - user_access_end(); - - /* Set up registers for signal handler */ - regs->sp =3D (unsigned long)frame; - regs->ip =3D (unsigned long)ksig->ka.sa.sa_handler; - regs->ax =3D (unsigned long)ksig->sig; - regs->dx =3D 0; - regs->cx =3D 0; - - regs->ds =3D __USER_DS; - regs->es =3D __USER_DS; - regs->ss =3D __USER_DS; - regs->cs =3D __USER_CS; - - return 0; - -Efault: - user_access_end(); - return -EFAULT; -} - -int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) -{ - sigset_t *set =3D sigmask_to_save(); - struct rt_sigframe __user *frame; - void __user *restorer; - void __user *fp =3D NULL; - - frame =3D get_sigframe(ksig, regs, sizeof(*frame), &fp); - - if (!user_access_begin(frame, sizeof(*frame))) - return -EFAULT; - - unsafe_put_user(ksig->sig, &frame->sig, Efault); - unsafe_put_user(&frame->info, &frame->pinfo, Efault); - unsafe_put_user(&frame->uc, &frame->puc, Efault); - - /* Create the ucontext. */ - if (static_cpu_has(X86_FEATURE_XSAVE)) - unsafe_put_user(UC_FP_XSTATE, &frame->uc.uc_flags, Efault); - else - unsafe_put_user(0, &frame->uc.uc_flags, Efault); - unsafe_put_user(0, &frame->uc.uc_link, Efault); - unsafe_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); - - /* Set up to return from userspace. */ - restorer =3D current->mm->context.vdso + - vdso_image_32.sym___kernel_rt_sigreturn; - if (ksig->ka.sa.sa_flags & SA_RESTORER) - restorer =3D ksig->ka.sa.sa_restorer; - unsafe_put_user(restorer, &frame->pretcode, Efault); - - /* - * This is movl $__NR_rt_sigreturn, %ax ; int $0x80 - * - * WE DO NOT USE IT ANY MORE! It's only left here for historical - * reasons and because gdb uses it as a signature to notice - * signal handler stack frames. - */ - unsafe_put_user(*((u64 *)&rt_retcode), (u64 *)frame->retcode, Efault); - unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault); - unsafe_put_sigmask(set, frame, Efault); - user_access_end(); -=09 - if (copy_siginfo_to_user(&frame->info, &ksig->info)) - return -EFAULT; - - /* Set up registers for signal handler */ - regs->sp =3D (unsigned long)frame; - regs->ip =3D (unsigned long)ksig->ka.sa.sa_handler; - regs->ax =3D (unsigned long)ksig->sig; - regs->dx =3D (unsigned long)&frame->info; - regs->cx =3D (unsigned long)&frame->uc; - - regs->ds =3D __USER_DS; - regs->es =3D __USER_DS; - regs->ss =3D __USER_DS; - regs->cs =3D __USER_CS; - - return 0; -Efault: - user_access_end(); - return -EFAULT; -} -#else /* !CONFIG_X86_32 */ +#ifdef CONFIG_X86_64 static unsigned long frame_uc_flags(struct pt_regs *regs) { unsigned long flags; @@ -545,7 +370,6 @@ int x64_setup_rt_frame(struct ksignal *ksig, struct pt_= regs *regs) user_access_end(); return -EFAULT; } -#endif /* CONFIG_X86_32 */ =20 #ifdef CONFIG_X86_X32_ABI static int x32_copy_siginfo_to_user(struct compat_siginfo __user *to, @@ -631,38 +455,6 @@ int x32_setup_rt_frame(struct ksignal *ksig, struct pt= _regs *regs) /* * Do a signal return; undo the signal stack. */ -#ifdef CONFIG_X86_32 -SYSCALL_DEFINE0(sigreturn) -{ - struct pt_regs *regs =3D current_pt_regs(); - struct sigframe __user *frame; - sigset_t set; - - frame =3D (struct sigframe __user *)(regs->sp - 8); - - if (!access_ok(frame, sizeof(*frame))) - goto badframe; - if (__get_user(set.sig[0], &frame->sc.oldmask) || - __get_user(set.sig[1], &frame->extramask[0])) - goto badframe; - - set_current_blocked(&set); - - /* - * x86_32 has no uc_flags bits relevant to restore_sigcontext. - * Save a few cycles by skipping the __get_user. - */ - if (!restore_sigcontext(regs, &frame->sc, 0)) - goto badframe; - return regs->ax; - -badframe: - signal_fault(regs, frame, "sigreturn"); - - return 0; -} -#endif /* CONFIG_X86_32 */ - SYSCALL_DEFINE0(rt_sigreturn) { struct pt_regs *regs =3D current_pt_regs(); @@ -692,6 +484,7 @@ SYSCALL_DEFINE0(rt_sigreturn) signal_fault(regs, frame, "rt_sigreturn"); return 0; } +#endif /* CONFIG_X86_64 */ =20 /* * There are four different struct types for signal frame: sigframe_ia32, diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/kernel/signal_32.c similarity index 86% rename from arch/x86/ia32/ia32_signal.c rename to arch/x86/kernel/signal_32.c index e28421f53d44..2553136cf39b 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/kernel/signal_32.c @@ -1,7 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 /* - * linux/arch/x86_64/ia32/ia32_signal.c - * * Copyright (C) 1991, 1992 Linus Torvalds * * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson @@ -26,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +32,9 @@ #include #include =20 +#ifdef CONFIG_IA32_EMULATION +#include + static inline void reload_segments(struct sigcontext_32 *sc) { unsigned int cur; @@ -53,6 +53,21 @@ static inline void reload_segments(struct sigcontext_32 = *sc) loadsegment(es, sc->es | 0x03); } =20 +#define sigset32_t compat_sigset_t +#define restore_altstack32 compat_restore_altstack +#define unsafe_save_altstack32 unsafe_compat_save_altstack + +#else + +#define sigset32_t sigset_t +#define __NR_ia32_sigreturn __NR_sigreturn +#define __NR_ia32_rt_sigreturn __NR_rt_sigreturn +#define restore_altstack32 restore_altstack +#define unsafe_save_altstack32 unsafe_save_altstack +#define __copy_siginfo_to_user32 copy_siginfo_to_user + +#endif + /* * Do a signal return; undo the signal stack. */ @@ -86,6 +101,7 @@ static bool ia32_restore_sigcontext(struct pt_regs *regs, /* disable syscall checks */ regs->orig_ax =3D -1; =20 +#ifdef CONFIG_IA32_EMULATION /* * Reload fs and gs if they have changed in the signal * handler. This does not handle long fs/gs base changes in @@ -93,10 +109,17 @@ static bool ia32_restore_sigcontext(struct pt_regs *re= gs, * normal case. */ reload_segments(&sc); +#else + loadsegment(gs, sc.gs); + regs->fs =3D sc.fs; + regs->es =3D sc.es; + regs->ds =3D sc.ds; +#endif + return fpu__restore_sig(compat_ptr(sc.fpstate), 1); } =20 -COMPAT_SYSCALL_DEFINE0(sigreturn) +SYSCALL32_DEFINE0(sigreturn) { struct pt_regs *regs =3D current_pt_regs(); struct sigframe_ia32 __user *frame =3D (struct sigframe_ia32 __user *)(re= gs->sp-8); @@ -119,7 +142,7 @@ COMPAT_SYSCALL_DEFINE0(sigreturn) return 0; } =20 -COMPAT_SYSCALL_DEFINE0(rt_sigreturn) +SYSCALL32_DEFINE0(rt_sigreturn) { struct pt_regs *regs =3D current_pt_regs(); struct rt_sigframe_ia32 __user *frame; @@ -129,7 +152,7 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) =20 if (!access_ok(frame, sizeof(*frame))) goto badframe; - if (__get_user(set.sig[0], (__u64 __user *)&frame->uc.uc_sigmask)) + if (__get_user(*(__u64 *)&set, (__u64 __user *)&frame->uc.uc_sigmask)) goto badframe; =20 set_current_blocked(&set); @@ -137,7 +160,7 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) if (!ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; =20 - if (compat_restore_altstack(&frame->uc.uc_stack)) + if (restore_altstack32(&frame->uc.uc_stack)) goto badframe; =20 return regs->ax; @@ -159,9 +182,15 @@ __unsafe_setup_sigcontext32(struct sigcontext_32 __use= r *sc, struct pt_regs *regs, unsigned int mask) { unsafe_put_user(get_user_seg(gs), (unsigned int __user *)&sc->gs, Efault); +#ifdef CONFIG_IA32_EMULATION unsafe_put_user(get_user_seg(fs), (unsigned int __user *)&sc->fs, Efault); unsafe_put_user(get_user_seg(ds), (unsigned int __user *)&sc->ds, Efault); unsafe_put_user(get_user_seg(es), (unsigned int __user *)&sc->es, Efault); +#else + unsafe_put_user(regs->fs, (unsigned int __user *)&sc->fs, Efault); + unsafe_put_user(regs->es, (unsigned int __user *)&sc->es, Efault); + unsafe_put_user(regs->ds, (unsigned int __user *)&sc->ds, Efault); +#endif =20 unsafe_put_user(regs->di, &sc->di, Efault); unsafe_put_user(regs->si, &sc->si, Efault); @@ -198,7 +227,7 @@ do { \ =20 int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs) { - compat_sigset_t *set =3D (compat_sigset_t *) sigmask_to_save(); + sigset32_t *set =3D (sigset32_t *) sigmask_to_save(); struct sigframe_ia32 __user *frame; void __user *restorer; void __user *fp =3D NULL; @@ -250,8 +279,13 @@ int ia32_setup_frame(struct ksignal *ksig, struct pt_r= egs *regs) regs->dx =3D 0; regs->cx =3D 0; =20 +#ifdef CONFIG_IA32_EMULATION loadsegment(ds, __USER_DS); loadsegment(es, __USER_DS); +#else + regs->ds =3D __USER_DS; + regs->es =3D __USER_DS; +#endif =20 regs->cs =3D __USER32_CS; regs->ss =3D __USER_DS; @@ -264,7 +298,7 @@ int ia32_setup_frame(struct ksignal *ksig, struct pt_re= gs *regs) =20 int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { - compat_sigset_t *set =3D (compat_sigset_t *) sigmask_to_save(); + sigset32_t *set =3D (sigset32_t *) sigmask_to_save(); struct rt_sigframe_ia32 __user *frame; void __user *restorer; void __user *fp =3D NULL; @@ -297,7 +331,7 @@ int ia32_setup_rt_frame(struct ksignal *ksig, struct pt= _regs *regs) else unsafe_put_user(0, &frame->uc.uc_flags, Efault); unsafe_put_user(0, &frame->uc.uc_link, Efault); - unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); + unsafe_save_altstack32(&frame->uc.uc_stack, regs->sp, Efault); =20 if (ksig->ka.sa.sa_flags & SA_RESTORER) restorer =3D ksig->ka.sa.sa_restorer; @@ -327,8 +361,13 @@ int ia32_setup_rt_frame(struct ksignal *ksig, struct p= t_regs *regs) regs->dx =3D (unsigned long) &frame->info; regs->cx =3D (unsigned long) &frame->uc; =20 +#ifdef CONFIG_IA32_EMULATION loadsegment(ds, __USER_DS); loadsegment(es, __USER_DS); +#else + regs->ds =3D __USER_DS; + regs->es =3D __USER_DS; +#endif =20 regs->cs =3D __USER32_CS; regs->ss =3D __USER_DS; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index a34b0f9a9972..33a0ee3bcb2e 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -264,6 +264,7 @@ static inline int is_syscall_trace_event(struct trace_e= vent_call *tp_event) #define SC_VAL64(type, name) ((type) name##_hi << 32 | name##_lo) =20 #ifdef CONFIG_COMPAT +#define SYSCALL32_DEFINE0 COMPAT_SYSCALL_DEFINE0 #define SYSCALL32_DEFINE1 COMPAT_SYSCALL_DEFINE1 #define SYSCALL32_DEFINE2 COMPAT_SYSCALL_DEFINE2 #define SYSCALL32_DEFINE3 COMPAT_SYSCALL_DEFINE3 @@ -271,6 +272,7 @@ static inline int is_syscall_trace_event(struct trace_e= vent_call *tp_event) #define SYSCALL32_DEFINE5 COMPAT_SYSCALL_DEFINE5 #define SYSCALL32_DEFINE6 COMPAT_SYSCALL_DEFINE6 #else +#define SYSCALL32_DEFINE0 SYSCALL_DEFINE0 #define SYSCALL32_DEFINE1 SYSCALL_DEFINE1 #define SYSCALL32_DEFINE2 SYSCALL_DEFINE2 #define SYSCALL32_DEFINE3 SYSCALL_DEFINE3 --=20 2.35.3 From nobody Thu Apr 30 09:38:02 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29745C43334 for ; Mon, 6 Jun 2022 20:43:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233341AbiFFUnq (ORCPT ); Mon, 6 Jun 2022 16:43:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40706 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234263AbiFFUmv (ORCPT ); Mon, 6 Jun 2022 16:42:51 -0400 Received: from mail-oo1-xc30.google.com (mail-oo1-xc30.google.com [IPv6:2607:f8b0:4864:20::c30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3955EC31C for ; Mon, 6 Jun 2022 13:38:57 -0700 (PDT) Received: by mail-oo1-xc30.google.com with SMTP id e13-20020a4a884d000000b004154e612440so3010349ooi.0 for ; Mon, 06 Jun 2022 13:38:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=sKYToXk2NDc2jt1jMBno/tluKiVDdIv48HFtD+x8bb8=; b=HlEdGiS7qsT7DYF1JCL+GSdItgNvhNvjZbPZOrutrcimLZZ/lr3D/KnaDAcq16LRty Dkj73OPhpUnA8l7Uw1sT2NWg/VQpFpn9AdEdQ9tHMjLrbdAaHiSeumbrJLkPhdbLJrZx nYiqBZ3N55FrxdjqBYFLZm8gVrmRM/YydpiFxNH/Tcv+MPZgmAR2owMvUgqdQaTC5zm5 P1emcMMiBh7AX7xiZEgZyMgdc7sQvbHQDopmGJLm4Ta3RDk6/68U+RN8T8mQZqFEzfa5 5BAz428E2oUod875w9R8DGzsI2P0sN97cpkzokCPblqFXNdjgKSRy4jMcB9g8u43taMU uusg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=sKYToXk2NDc2jt1jMBno/tluKiVDdIv48HFtD+x8bb8=; b=eGdYRkIyn5FWg1PBv0Nmcrpsijkc45/RfnaWLGJBKmcQelQYaWgfpL2jP/sWJxMw92 JwKn30XGrmREIav4Np0laCkaQ+xpP5NTWMggia7n6+EVn7KeZ+5fW2ZdLW9/+t7J6Ejk Nf91nbkwCkhmJibzZmFX+pHW/TS4e2jKYtZmKKKNNcH1UDHoTv5II05ElDDxD1S0PwxG PCEdAFAdToYK32IFWxnG17aMx3RG7ZluQvYTJMKRE+LnOrwoavHG6m4LX0bpEihZ/Qp/ yWnznB4Sw9tai33ixr3+hnBAM+9x0qLRY8qIxdWBIwxLv6uJ1htxys1r9luRY8Gynd8x mW5A== X-Gm-Message-State: AOAM5339KuaqjIZ99ZKnLDOOwhrGcGyFMOZ2d4hUpX6OXgPCF6EVN6k+ XhNWLh13wEI1OWw07+jx1AyavfaQAQ== X-Google-Smtp-Source: ABdhPJzGj9fZmYfoCniYhFjh4gtRS6U1WF86DztSKj85OSsbeDqW1sbKGaBQ5earSKCoV81HvasE4A== X-Received: by 2002:a4a:942b:0:b0:33a:39e0:b908 with SMTP id h40-20020a4a942b000000b0033a39e0b908mr10879321ooi.62.1654547936263; Mon, 06 Jun 2022 13:38:56 -0700 (PDT) Received: from citadel.. (174-084-153-250.res.spectrum.com. [174.84.153.250]) by smtp.gmail.com with ESMTPSA id j22-20020a056808035600b0032e3cca8561sm4327188oie.21.2022.06.06.13.38.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jun 2022 13:38:55 -0700 (PDT) From: Brian Gerst To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Thomas Gleixner , Andy Lutomirski , Borislav Petkov , "H . Peter Anvin" , Peter Zijlstra , "Eric W . Biederman" , Brian Gerst Subject: [PATCH 8/8] x86/signal/64: Move 64-bit signal code to its own file Date: Mon, 6 Jun 2022 16:38:02 -0400 Message-Id: <20220606203802.158958-9-brgerst@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220606203802.158958-1-brgerst@gmail.com> References: <20220606203802.158958-1-brgerst@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Signed-off-by: Brian Gerst Acked-by: "Eric W. Biederman" --- arch/x86/kernel/Makefile | 4 +- arch/x86/kernel/signal.c | 376 ----------------------------------- arch/x86/kernel/signal_64.c | 383 ++++++++++++++++++++++++++++++++++++ 3 files changed, 385 insertions(+), 378 deletions(-) create mode 100644 arch/x86/kernel/signal_64.c diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 4aa1bd55a362..a1bb527a02f5 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -48,7 +48,7 @@ KCOV_INSTRUMENT :=3D n =20 CFLAGS_irq.o :=3D -I $(srctree)/$(src)/../include/asm/trace =20 -obj-y :=3D process_$(BITS).o signal.o +obj-y :=3D process_$(BITS).o signal.o signal_$(BITS).o obj-$(CONFIG_COMPAT) +=3D signal_compat.o obj-y +=3D traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y +=3D time.o ioport.o dumpstack.o nmi.o @@ -57,7 +57,7 @@ obj-y +=3D setup.o x86_init.o i8259.o irqinit.o obj-$(CONFIG_JUMP_LABEL) +=3D jump_label.o obj-$(CONFIG_IRQ_WORK) +=3D irq_work.o obj-y +=3D probe_roms.o -obj-$(CONFIG_X86_32) +=3D sys_ia32.o signal_32.o +obj-$(CONFIG_X86_32) +=3D sys_ia32.o obj-$(CONFIG_IA32_EMULATION) +=3D sys_ia32.o signal_32.o obj-$(CONFIG_X86_64) +=3D sys_x86_64.o obj-$(CONFIG_X86_ESPFIX64) +=3D espfix_64.o diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 962cfd835c90..1504eb8d25aa 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -37,13 +37,6 @@ #include #include =20 -#ifdef CONFIG_X86_64 -#include -#include -#include -#include -#endif /* CONFIG_X86_64 */ - #include #include #include @@ -65,135 +58,6 @@ static inline int is_x32_frame(struct ksignal *ksig) ksig->ka.sa.sa_flags & SA_X32_ABI; } =20 -#ifdef CONFIG_X86_64 -/* - * If regs->ss will cause an IRET fault, change it. Otherwise leave it - * alone. Using this generally makes no sense unless - * user_64bit_mode(regs) would return true. - */ -static void force_valid_ss(struct pt_regs *regs) -{ - u32 ar; - asm volatile ("lar %[old_ss], %[ar]\n\t" - "jz 1f\n\t" /* If invalid: */ - "xorl %[ar], %[ar]\n\t" /* set ar =3D 0 */ - "1:" - : [ar] "=3Dr" (ar) - : [old_ss] "rm" ((u16)regs->ss)); - - /* - * For a valid 64-bit user context, we need DPL 3, type - * read-write data or read-write exp-down data, and S and P - * set. We can't use VERW because VERW doesn't check the - * P bit. - */ - ar &=3D AR_DPL_MASK | AR_S | AR_P | AR_TYPE_MASK; - if (ar !=3D (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA) && - ar !=3D (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA_EXPDOWN)) - regs->ss =3D __USER_DS; -} - -static bool restore_sigcontext(struct pt_regs *regs, - struct sigcontext __user *usc, - unsigned long uc_flags) -{ - struct sigcontext sc; - - /* Always make any pending restarted system calls return -EINTR */ - current->restart_block.fn =3D do_no_restart_syscall; - - if (copy_from_user(&sc, usc, offsetof(struct sigcontext, reserved1))) - return false; - - regs->bx =3D sc.bx; - regs->cx =3D sc.cx; - regs->dx =3D sc.dx; - regs->si =3D sc.si; - regs->di =3D sc.di; - regs->bp =3D sc.bp; - regs->ax =3D sc.ax; - regs->sp =3D sc.sp; - regs->ip =3D sc.ip; - regs->r8 =3D sc.r8; - regs->r9 =3D sc.r9; - regs->r10 =3D sc.r10; - regs->r11 =3D sc.r11; - regs->r12 =3D sc.r12; - regs->r13 =3D sc.r13; - regs->r14 =3D sc.r14; - regs->r15 =3D sc.r15; - - /* Get CS/SS and force CPL3 */ - regs->cs =3D sc.cs | 0x03; - regs->ss =3D sc.ss | 0x03; - - regs->flags =3D (regs->flags & ~FIX_EFLAGS) | (sc.flags & FIX_EFLAGS); - /* disable syscall checks */ - regs->orig_ax =3D -1; - - /* - * Fix up SS if needed for the benefit of old DOSEMU and - * CRIU. - */ - if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && user_64bit_mode(regs))) - force_valid_ss(regs); - - return fpu__restore_sig((void __user *)sc.fpstate, 0); -} - -static __always_inline int -__unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpsta= te, - struct pt_regs *regs, unsigned long mask) -{ - unsafe_put_user(regs->di, &sc->di, Efault); - unsafe_put_user(regs->si, &sc->si, Efault); - unsafe_put_user(regs->bp, &sc->bp, Efault); - unsafe_put_user(regs->sp, &sc->sp, Efault); - unsafe_put_user(regs->bx, &sc->bx, Efault); - unsafe_put_user(regs->dx, &sc->dx, Efault); - unsafe_put_user(regs->cx, &sc->cx, Efault); - unsafe_put_user(regs->ax, &sc->ax, Efault); - unsafe_put_user(regs->r8, &sc->r8, Efault); - unsafe_put_user(regs->r9, &sc->r9, Efault); - unsafe_put_user(regs->r10, &sc->r10, Efault); - unsafe_put_user(regs->r11, &sc->r11, Efault); - unsafe_put_user(regs->r12, &sc->r12, Efault); - unsafe_put_user(regs->r13, &sc->r13, Efault); - unsafe_put_user(regs->r14, &sc->r14, Efault); - unsafe_put_user(regs->r15, &sc->r15, Efault); - - unsafe_put_user(current->thread.trap_nr, &sc->trapno, Efault); - unsafe_put_user(current->thread.error_code, &sc->err, Efault); - unsafe_put_user(regs->ip, &sc->ip, Efault); - unsafe_put_user(regs->flags, &sc->flags, Efault); - unsafe_put_user(regs->cs, &sc->cs, Efault); - unsafe_put_user(0, &sc->gs, Efault); - unsafe_put_user(0, &sc->fs, Efault); - unsafe_put_user(regs->ss, &sc->ss, Efault); - - unsafe_put_user(fpstate, (unsigned long __user *)&sc->fpstate, Efault); - - /* non-iBCS2 extensions.. */ - unsafe_put_user(mask, &sc->oldmask, Efault); - unsafe_put_user(current->thread.cr2, &sc->cr2, Efault); - return 0; -Efault: - return -EFAULT; -} - -#define unsafe_put_sigcontext(sc, fp, regs, set, label) \ -do { \ - if (__unsafe_setup_sigcontext(sc, fp, regs, set->sig[0])) \ - goto label; \ -} while(0); - -#define unsafe_put_sigmask(set, frame, label) \ - unsafe_put_user(*(__u64 *)(set), \ - (__u64 __user *)&(frame)->uc.uc_sigmask, \ - label) - -#endif /* CONFIG_X86_64 */ - /* * Set up a signal frame. */ @@ -279,213 +143,6 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *re= gs, size_t frame_size, return (void __user *)sp; } =20 -#ifdef CONFIG_X86_64 -static unsigned long frame_uc_flags(struct pt_regs *regs) -{ - unsigned long flags; - - if (boot_cpu_has(X86_FEATURE_XSAVE)) - flags =3D UC_FP_XSTATE | UC_SIGCONTEXT_SS; - else - flags =3D UC_SIGCONTEXT_SS; - - if (likely(user_64bit_mode(regs))) - flags |=3D UC_STRICT_RESTORE_SS; - - return flags; -} - -int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) -{ - sigset_t *set =3D sigmask_to_save(); - struct rt_sigframe __user *frame; - void __user *fp =3D NULL; - unsigned long uc_flags; - - /* x86-64 should always use SA_RESTORER. */ - if (!(ksig->ka.sa.sa_flags & SA_RESTORER)) - return -EFAULT; - - frame =3D get_sigframe(ksig, regs, sizeof(struct rt_sigframe), &fp); - uc_flags =3D frame_uc_flags(regs); - - if (!user_access_begin(frame, sizeof(*frame))) - return -EFAULT; - - /* Create the ucontext. */ - unsafe_put_user(uc_flags, &frame->uc.uc_flags, Efault); - unsafe_put_user(0, &frame->uc.uc_link, Efault); - unsafe_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); - - /* Set up to return from userspace. If provided, use a stub - already in userspace. */ - unsafe_put_user(ksig->ka.sa.sa_restorer, &frame->pretcode, Efault); - unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault); - unsafe_put_sigmask(set, frame, Efault); - user_access_end(); - - if (ksig->ka.sa.sa_flags & SA_SIGINFO) { - if (copy_siginfo_to_user(&frame->info, &ksig->info)) - return -EFAULT; - } - - /* Set up registers for signal handler */ - regs->di =3D ksig->sig; - /* In case the signal handler was declared without prototypes */ - regs->ax =3D 0; - - /* This also works for non SA_SIGINFO handlers because they expect the - next argument after the signal number on the stack. */ - regs->si =3D (unsigned long)&frame->info; - regs->dx =3D (unsigned long)&frame->uc; - regs->ip =3D (unsigned long) ksig->ka.sa.sa_handler; - - regs->sp =3D (unsigned long)frame; - - /* - * Set up the CS and SS registers to run signal handlers in - * 64-bit mode, even if the handler happens to be interrupting - * 32-bit or 16-bit code. - * - * SS is subtle. In 64-bit mode, we don't need any particular - * SS descriptor, but we do need SS to be valid. It's possible - * that the old SS is entirely bogus -- this can happen if the - * signal we're trying to deliver is #GP or #SS caused by a bad - * SS value. We also have a compatibility issue here: DOSEMU - * relies on the contents of the SS register indicating the - * SS value at the time of the signal, even though that code in - * DOSEMU predates sigreturn's ability to restore SS. (DOSEMU - * avoids relying on sigreturn to restore SS; instead it uses - * a trampoline.) So we do our best: if the old SS was valid, - * we keep it. Otherwise we replace it. - */ - regs->cs =3D __USER_CS; - - if (unlikely(regs->ss !=3D __USER_DS)) - force_valid_ss(regs); - - return 0; - -Efault: - user_access_end(); - return -EFAULT; -} - -#ifdef CONFIG_X86_X32_ABI -static int x32_copy_siginfo_to_user(struct compat_siginfo __user *to, - const struct kernel_siginfo *from) -{ - struct compat_siginfo new; - - copy_siginfo_to_external32(&new, from); - if (from->si_signo =3D=3D SIGCHLD) { - new._sifields._sigchld_x32._utime =3D from->si_utime; - new._sifields._sigchld_x32._stime =3D from->si_stime; - } - if (copy_to_user(to, &new, sizeof(struct compat_siginfo))) - return -EFAULT; - return 0; -} - -int copy_siginfo_to_user32(struct compat_siginfo __user *to, - const struct kernel_siginfo *from) -{ - if (in_x32_syscall()) - return x32_copy_siginfo_to_user(to, from); - return __copy_siginfo_to_user32(to, from); -} - -int x32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) -{ - compat_sigset_t *set =3D (compat_sigset_t *) sigmask_to_save(); - struct rt_sigframe_x32 __user *frame; - unsigned long uc_flags; - void __user *restorer; - void __user *fp =3D NULL; - - if (!(ksig->ka.sa.sa_flags & SA_RESTORER)) - return -EFAULT; - - frame =3D get_sigframe(ksig, regs, sizeof(*frame), &fp); - - uc_flags =3D frame_uc_flags(regs); - - if (!user_access_begin(frame, sizeof(*frame))) - return -EFAULT; - - /* Create the ucontext. */ - unsafe_put_user(uc_flags, &frame->uc.uc_flags, Efault); - unsafe_put_user(0, &frame->uc.uc_link, Efault); - unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); - unsafe_put_user(0, &frame->uc.uc__pad0, Efault); - restorer =3D ksig->ka.sa.sa_restorer; - unsafe_put_user(restorer, (unsigned long __user *)&frame->pretcode, Efaul= t); - unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault); - unsafe_put_sigmask(set, frame, Efault); - user_access_end(); - - if (ksig->ka.sa.sa_flags & SA_SIGINFO) { - if (x32_copy_siginfo_to_user(&frame->info, &ksig->info)) - return -EFAULT; - } - - /* Set up registers for signal handler */ - regs->sp =3D (unsigned long) frame; - regs->ip =3D (unsigned long) ksig->ka.sa.sa_handler; - - /* We use the x32 calling convention here... */ - regs->di =3D ksig->sig; - regs->si =3D (unsigned long) &frame->info; - regs->dx =3D (unsigned long) &frame->uc; - - loadsegment(ds, __USER_DS); - loadsegment(es, __USER_DS); - - regs->cs =3D __USER_CS; - regs->ss =3D __USER_DS; - - return 0; - -Efault: - user_access_end(); - return -EFAULT; -} -#endif /* CONFIG_X86_X32_ABI */ - -/* - * Do a signal return; undo the signal stack. - */ -SYSCALL_DEFINE0(rt_sigreturn) -{ - struct pt_regs *regs =3D current_pt_regs(); - struct rt_sigframe __user *frame; - sigset_t set; - unsigned long uc_flags; - - frame =3D (struct rt_sigframe __user *)(regs->sp - sizeof(long)); - if (!access_ok(frame, sizeof(*frame))) - goto badframe; - if (__get_user(*(__u64 *)&set, (__u64 __user *)&frame->uc.uc_sigmask)) - goto badframe; - if (__get_user(uc_flags, &frame->uc.uc_flags)) - goto badframe; - - set_current_blocked(&set); - - if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags)) - goto badframe; - - if (restore_altstack(&frame->uc.uc_stack)) - goto badframe; - - return regs->ax; - -badframe: - signal_fault(regs, frame, "rt_sigreturn"); - return 0; -} -#endif /* CONFIG_X86_64 */ - /* * There are four different struct types for signal frame: sigframe_ia32, * rt_sigframe_ia32, rt_sigframe_x32, and rt_sigframe. Use the worst case @@ -749,36 +406,3 @@ bool sigaltstack_size_valid(size_t ss_size) return true; } #endif /* CONFIG_DYNAMIC_SIGFRAME */ - -#ifdef CONFIG_X86_X32_ABI -COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn) -{ - struct pt_regs *regs =3D current_pt_regs(); - struct rt_sigframe_x32 __user *frame; - sigset_t set; - unsigned long uc_flags; - - frame =3D (struct rt_sigframe_x32 __user *)(regs->sp - 8); - - if (!access_ok(frame, sizeof(*frame))) - goto badframe; - if (__get_user(set.sig[0], (__u64 __user *)&frame->uc.uc_sigmask)) - goto badframe; - if (__get_user(uc_flags, &frame->uc.uc_flags)) - goto badframe; - - set_current_blocked(&set); - - if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags)) - goto badframe; - - if (compat_restore_altstack(&frame->uc.uc_stack)) - goto badframe; - - return regs->ax; - -badframe: - signal_fault(regs, frame, "x32 rt_sigreturn"); - return 0; -} -#endif diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c new file mode 100644 index 000000000000..ff9c55064223 --- /dev/null +++ b/arch/x86/kernel/signal_64.c @@ -0,0 +1,383 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +/* + * If regs->ss will cause an IRET fault, change it. Otherwise leave it + * alone. Using this generally makes no sense unless + * user_64bit_mode(regs) would return true. + */ +static void force_valid_ss(struct pt_regs *regs) +{ + u32 ar; + asm volatile ("lar %[old_ss], %[ar]\n\t" + "jz 1f\n\t" /* If invalid: */ + "xorl %[ar], %[ar]\n\t" /* set ar =3D 0 */ + "1:" + : [ar] "=3Dr" (ar) + : [old_ss] "rm" ((u16)regs->ss)); + + /* + * For a valid 64-bit user context, we need DPL 3, type + * read-write data or read-write exp-down data, and S and P + * set. We can't use VERW because VERW doesn't check the + * P bit. + */ + ar &=3D AR_DPL_MASK | AR_S | AR_P | AR_TYPE_MASK; + if (ar !=3D (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA) && + ar !=3D (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA_EXPDOWN)) + regs->ss =3D __USER_DS; +} + +static bool restore_sigcontext(struct pt_regs *regs, + struct sigcontext __user *usc, + unsigned long uc_flags) +{ + struct sigcontext sc; + + /* Always make any pending restarted system calls return -EINTR */ + current->restart_block.fn =3D do_no_restart_syscall; + + if (copy_from_user(&sc, usc, offsetof(struct sigcontext, reserved1))) + return false; + + regs->bx =3D sc.bx; + regs->cx =3D sc.cx; + regs->dx =3D sc.dx; + regs->si =3D sc.si; + regs->di =3D sc.di; + regs->bp =3D sc.bp; + regs->ax =3D sc.ax; + regs->sp =3D sc.sp; + regs->ip =3D sc.ip; + regs->r8 =3D sc.r8; + regs->r9 =3D sc.r9; + regs->r10 =3D sc.r10; + regs->r11 =3D sc.r11; + regs->r12 =3D sc.r12; + regs->r13 =3D sc.r13; + regs->r14 =3D sc.r14; + regs->r15 =3D sc.r15; + + /* Get CS/SS and force CPL3 */ + regs->cs =3D sc.cs | 0x03; + regs->ss =3D sc.ss | 0x03; + + regs->flags =3D (regs->flags & ~FIX_EFLAGS) | (sc.flags & FIX_EFLAGS); + /* disable syscall checks */ + regs->orig_ax =3D -1; + + /* + * Fix up SS if needed for the benefit of old DOSEMU and + * CRIU. + */ + if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && user_64bit_mode(regs))) + force_valid_ss(regs); + + return fpu__restore_sig((void __user *)sc.fpstate, 0); +} + +static __always_inline int +__unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpsta= te, + struct pt_regs *regs, unsigned long mask) +{ + unsafe_put_user(regs->di, &sc->di, Efault); + unsafe_put_user(regs->si, &sc->si, Efault); + unsafe_put_user(regs->bp, &sc->bp, Efault); + unsafe_put_user(regs->sp, &sc->sp, Efault); + unsafe_put_user(regs->bx, &sc->bx, Efault); + unsafe_put_user(regs->dx, &sc->dx, Efault); + unsafe_put_user(regs->cx, &sc->cx, Efault); + unsafe_put_user(regs->ax, &sc->ax, Efault); + unsafe_put_user(regs->r8, &sc->r8, Efault); + unsafe_put_user(regs->r9, &sc->r9, Efault); + unsafe_put_user(regs->r10, &sc->r10, Efault); + unsafe_put_user(regs->r11, &sc->r11, Efault); + unsafe_put_user(regs->r12, &sc->r12, Efault); + unsafe_put_user(regs->r13, &sc->r13, Efault); + unsafe_put_user(regs->r14, &sc->r14, Efault); + unsafe_put_user(regs->r15, &sc->r15, Efault); + + unsafe_put_user(current->thread.trap_nr, &sc->trapno, Efault); + unsafe_put_user(current->thread.error_code, &sc->err, Efault); + unsafe_put_user(regs->ip, &sc->ip, Efault); + unsafe_put_user(regs->flags, &sc->flags, Efault); + unsafe_put_user(regs->cs, &sc->cs, Efault); + unsafe_put_user(0, &sc->gs, Efault); + unsafe_put_user(0, &sc->fs, Efault); + unsafe_put_user(regs->ss, &sc->ss, Efault); + + unsafe_put_user(fpstate, (unsigned long __user *)&sc->fpstate, Efault); + + /* non-iBCS2 extensions.. */ + unsafe_put_user(mask, &sc->oldmask, Efault); + unsafe_put_user(current->thread.cr2, &sc->cr2, Efault); + return 0; +Efault: + return -EFAULT; +} + +#define unsafe_put_sigcontext(sc, fp, regs, set, label) \ +do { \ + if (__unsafe_setup_sigcontext(sc, fp, regs, set->sig[0])) \ + goto label; \ +} while(0); + +#define unsafe_put_sigmask(set, frame, label) \ + unsafe_put_user(*(__u64 *)(set), \ + (__u64 __user *)&(frame)->uc.uc_sigmask, \ + label) + +static unsigned long frame_uc_flags(struct pt_regs *regs) +{ + unsigned long flags; + + if (boot_cpu_has(X86_FEATURE_XSAVE)) + flags =3D UC_FP_XSTATE | UC_SIGCONTEXT_SS; + else + flags =3D UC_SIGCONTEXT_SS; + + if (likely(user_64bit_mode(regs))) + flags |=3D UC_STRICT_RESTORE_SS; + + return flags; +} + +int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) +{ + sigset_t *set =3D sigmask_to_save(); + struct rt_sigframe __user *frame; + void __user *fp =3D NULL; + unsigned long uc_flags; + + /* x86-64 should always use SA_RESTORER. */ + if (!(ksig->ka.sa.sa_flags & SA_RESTORER)) + return -EFAULT; + + frame =3D get_sigframe(ksig, regs, sizeof(struct rt_sigframe), &fp); + uc_flags =3D frame_uc_flags(regs); + + if (!user_access_begin(frame, sizeof(*frame))) + return -EFAULT; + + /* Create the ucontext. */ + unsafe_put_user(uc_flags, &frame->uc.uc_flags, Efault); + unsafe_put_user(0, &frame->uc.uc_link, Efault); + unsafe_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + unsafe_put_user(ksig->ka.sa.sa_restorer, &frame->pretcode, Efault); + unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault); + unsafe_put_sigmask(set, frame, Efault); + user_access_end(); + + if (ksig->ka.sa.sa_flags & SA_SIGINFO) { + if (copy_siginfo_to_user(&frame->info, &ksig->info)) + return -EFAULT; + } + + /* Set up registers for signal handler */ + regs->di =3D ksig->sig; + /* In case the signal handler was declared without prototypes */ + regs->ax =3D 0; + + /* This also works for non SA_SIGINFO handlers because they expect the + next argument after the signal number on the stack. */ + regs->si =3D (unsigned long)&frame->info; + regs->dx =3D (unsigned long)&frame->uc; + regs->ip =3D (unsigned long) ksig->ka.sa.sa_handler; + + regs->sp =3D (unsigned long)frame; + + /* + * Set up the CS and SS registers to run signal handlers in + * 64-bit mode, even if the handler happens to be interrupting + * 32-bit or 16-bit code. + * + * SS is subtle. In 64-bit mode, we don't need any particular + * SS descriptor, but we do need SS to be valid. It's possible + * that the old SS is entirely bogus -- this can happen if the + * signal we're trying to deliver is #GP or #SS caused by a bad + * SS value. We also have a compatibility issue here: DOSEMU + * relies on the contents of the SS register indicating the + * SS value at the time of the signal, even though that code in + * DOSEMU predates sigreturn's ability to restore SS. (DOSEMU + * avoids relying on sigreturn to restore SS; instead it uses + * a trampoline.) So we do our best: if the old SS was valid, + * we keep it. Otherwise we replace it. + */ + regs->cs =3D __USER_CS; + + if (unlikely(regs->ss !=3D __USER_DS)) + force_valid_ss(regs); + + return 0; + +Efault: + user_access_end(); + return -EFAULT; +} + +/* + * Do a signal return; undo the signal stack. + */ +SYSCALL_DEFINE0(rt_sigreturn) +{ + struct pt_regs *regs =3D current_pt_regs(); + struct rt_sigframe __user *frame; + sigset_t set; + unsigned long uc_flags; + + frame =3D (struct rt_sigframe __user *)(regs->sp - sizeof(long)); + if (!access_ok(frame, sizeof(*frame))) + goto badframe; + if (__get_user(*(__u64 *)&set, (__u64 __user *)&frame->uc.uc_sigmask)) + goto badframe; + if (__get_user(uc_flags, &frame->uc.uc_flags)) + goto badframe; + + set_current_blocked(&set); + + if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags)) + goto badframe; + + if (restore_altstack(&frame->uc.uc_stack)) + goto badframe; + + return regs->ax; + +badframe: + signal_fault(regs, frame, "rt_sigreturn"); + return 0; +} + +#ifdef CONFIG_X86_X32_ABI +static int x32_copy_siginfo_to_user(struct compat_siginfo __user *to, + const struct kernel_siginfo *from) +{ + struct compat_siginfo new; + + copy_siginfo_to_external32(&new, from); + if (from->si_signo =3D=3D SIGCHLD) { + new._sifields._sigchld_x32._utime =3D from->si_utime; + new._sifields._sigchld_x32._stime =3D from->si_stime; + } + if (copy_to_user(to, &new, sizeof(struct compat_siginfo))) + return -EFAULT; + return 0; +} + +int copy_siginfo_to_user32(struct compat_siginfo __user *to, + const struct kernel_siginfo *from) +{ + if (in_x32_syscall()) + return x32_copy_siginfo_to_user(to, from); + return __copy_siginfo_to_user32(to, from); +} + +int x32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) +{ + compat_sigset_t *set =3D (compat_sigset_t *) sigmask_to_save(); + struct rt_sigframe_x32 __user *frame; + unsigned long uc_flags; + void __user *restorer; + void __user *fp =3D NULL; + + if (!(ksig->ka.sa.sa_flags & SA_RESTORER)) + return -EFAULT; + + frame =3D get_sigframe(ksig, regs, sizeof(*frame), &fp); + + uc_flags =3D frame_uc_flags(regs); + + if (!user_access_begin(frame, sizeof(*frame))) + return -EFAULT; + + /* Create the ucontext. */ + unsafe_put_user(uc_flags, &frame->uc.uc_flags, Efault); + unsafe_put_user(0, &frame->uc.uc_link, Efault); + unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); + unsafe_put_user(0, &frame->uc.uc__pad0, Efault); + restorer =3D ksig->ka.sa.sa_restorer; + unsafe_put_user(restorer, (unsigned long __user *)&frame->pretcode, Efaul= t); + unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault); + unsafe_put_sigmask(set, frame, Efault); + user_access_end(); + + if (ksig->ka.sa.sa_flags & SA_SIGINFO) { + if (x32_copy_siginfo_to_user(&frame->info, &ksig->info)) + return -EFAULT; + } + + /* Set up registers for signal handler */ + regs->sp =3D (unsigned long) frame; + regs->ip =3D (unsigned long) ksig->ka.sa.sa_handler; + + /* We use the x32 calling convention here... */ + regs->di =3D ksig->sig; + regs->si =3D (unsigned long) &frame->info; + regs->dx =3D (unsigned long) &frame->uc; + + loadsegment(ds, __USER_DS); + loadsegment(es, __USER_DS); + + regs->cs =3D __USER_CS; + regs->ss =3D __USER_DS; + + return 0; + +Efault: + user_access_end(); + return -EFAULT; +} + +COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn) +{ + struct pt_regs *regs =3D current_pt_regs(); + struct rt_sigframe_x32 __user *frame; + sigset_t set; + unsigned long uc_flags; + + frame =3D (struct rt_sigframe_x32 __user *)(regs->sp - 8); + + if (!access_ok(frame, sizeof(*frame))) + goto badframe; + if (__get_user(set.sig[0], (__u64 __user *)&frame->uc.uc_sigmask)) + goto badframe; + if (__get_user(uc_flags, &frame->uc.uc_flags)) + goto badframe; + + set_current_blocked(&set); + + if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags)) + goto badframe; + + if (compat_restore_altstack(&frame->uc.uc_stack)) + goto badframe; + + return regs->ax; + +badframe: + signal_fault(regs, frame, "x32 rt_sigreturn"); + return 0; +} +#endif /* CONFIG_X86_X32_ABI */ --=20 2.35.3