diff mbox series

arm64: Introduce sysctl to disable pointer authentication

Message ID 20200707173232.5535-1-steve.capper@arm.com (mailing list archive)
State New, archived
Headers show
Series arm64: Introduce sysctl to disable pointer authentication | expand

Commit Message

Steve Capper July 7, 2020, 5:32 p.m. UTC
Pointer authentication is a mandatory feature in the Armv8.3
architecture that provides protection against return oriented
programming attacks. (meaning that all Arm CPUs targetting at least
Armv8.3 will have this feature).

Once CONFIG_ARM64_PTR_AUTH=y, any systems with the hardware support for
pointer authentication will automatically have it enabled by the kernel.

There are, however, situations where end users may want to disable
pointer authentication. One could be tracking down/working around a bug
in userspace relating to pointer auth. Also, one may wish to quantify
the performance overhead of pointer auth by running a workload
with/without it.

Linux distributions operate a single binary policy wherever possible,
meaning any mechanism to disable pointer authentication as a parameter
would be preferred greatly over building/supporting multiple kernels.

For hardware with pointer auth, this patch introduces the sysctl:
abi.ptrauth_disabled=1
which will disable pointer authentication for any new processes that are
exec'ed. (Reverting to 0 will then re-enable pointer authentication for
new processes).

One can set this sysctl on the kernel command line:
sysctl.abi.ptrauth_disabled=1
And this will ensure that pointer authentication is disabled for the init
process onwards.

Note that when pointer authentication is disabled by sysctl, the
capabilities are still exposed to userspace and pointer authentication
instructions can execute (it will just be as NOPs).

Signed-off-by: Steve Capper <steve.capper@arm.com>
---
 .../arm64/pointer-authentication.rst          | 32 ++++++++++++++++
 arch/arm64/include/asm/asm_pointer_auth.h     | 37 +++++++++++++++++++
 arch/arm64/include/asm/pointer_auth.h         | 10 +++--
 arch/arm64/include/asm/processor.h            |  1 +
 arch/arm64/kernel/asm-offsets.c               |  1 +
 arch/arm64/kernel/entry.S                     |  3 ++
 arch/arm64/kernel/process.c                   | 31 +++++++++++++++-
 7 files changed, 111 insertions(+), 4 deletions(-)

Comments

Will Deacon July 8, 2020, 7:36 a.m. UTC | #1
On Tue, Jul 07, 2020 at 06:32:32PM +0100, Steve Capper wrote:
> Pointer authentication is a mandatory feature in the Armv8.3
> architecture that provides protection against return oriented
> programming attacks. (meaning that all Arm CPUs targetting at least
> Armv8.3 will have this feature).
> 
> Once CONFIG_ARM64_PTR_AUTH=y, any systems with the hardware support for
> pointer authentication will automatically have it enabled by the kernel.
> 
> There are, however, situations where end users may want to disable
> pointer authentication. One could be tracking down/working around a bug
> in userspace relating to pointer auth. Also, one may wish to quantify
> the performance overhead of pointer auth by running a workload
> with/without it.

If you're debugging userspace, just recompile your userspace application
without ptr auth, in the same way that you might recompile with -g.

The performance argument sucks; this stuff needs to be fast otherwise it's
pointless. If you really need that last bit of speed, try Gentoo ;)

Will
Steve Capper July 8, 2020, 1:46 p.m. UTC | #2
Hi Will,

On Wed, Jul 08, 2020 at 08:36:21AM +0100, Will Deacon wrote:
> On Tue, Jul 07, 2020 at 06:32:32PM +0100, Steve Capper wrote:
> > Pointer authentication is a mandatory feature in the Armv8.3
> > architecture that provides protection against return oriented
> > programming attacks. (meaning that all Arm CPUs targetting at least
> > Armv8.3 will have this feature).
> > 
> > Once CONFIG_ARM64_PTR_AUTH=y, any systems with the hardware support for
> > pointer authentication will automatically have it enabled by the kernel.
> > 
> > There are, however, situations where end users may want to disable
> > pointer authentication. One could be tracking down/working around a bug
> > in userspace relating to pointer auth. Also, one may wish to quantify
> > the performance overhead of pointer auth by running a workload
> > with/without it.
> 
> If you're debugging userspace, just recompile your userspace application
> without ptr auth, in the same way that you might recompile with -g.
> 
> The performance argument sucks; this stuff needs to be fast otherwise it's
> pointless. If you really need that last bit of speed, try Gentoo ;)

I've tried Gentoo, and I liked it :-).

Apologies, I could have done a better job with the commit log...

I am trying to enable pointer authentication in distros. One concern I have
is that a pointer auth bug could slip through the cracks (with a lot of
hardware not yet supporting pointer auth), and then affect an end user.

Also, I have had interest from distros in the performance cost of pointer
auth, and there will very likely be folk switching it off/on again in
order to perform tests.

One approach to deploying this could be to have pointer auth disabled in
the kernel completely (via kconfig) and interested parties could then
switch kernels. Trouble with this is that distros ship single binaries so
it would be up to the end user to build/install another kernel + modules.
So this could be a barrier to adoption.

Having a mechanism in the kernel that an end user can employ to activate/
de-activate pointer auth would help with deployment greatly, and that is
what I was trying to achieve with this patch.

Another way to approach this could be via a kernel command line that
completely disables pointer auth? (i.e. kernel not activating pointer auth
at all, and userspace not seeing the feature)

Cheers,
Will Deacon July 8, 2020, 10:08 p.m. UTC | #3
Hi Steve,

On Wed, Jul 08, 2020 at 02:46:52PM +0100, Steve Capper wrote:
> On Wed, Jul 08, 2020 at 08:36:21AM +0100, Will Deacon wrote:
> > On Tue, Jul 07, 2020 at 06:32:32PM +0100, Steve Capper wrote:
> > > Pointer authentication is a mandatory feature in the Armv8.3
> > > architecture that provides protection against return oriented
> > > programming attacks. (meaning that all Arm CPUs targetting at least
> > > Armv8.3 will have this feature).
> > > 
> > > Once CONFIG_ARM64_PTR_AUTH=y, any systems with the hardware support for
> > > pointer authentication will automatically have it enabled by the kernel.
> > > 
> > > There are, however, situations where end users may want to disable
> > > pointer authentication. One could be tracking down/working around a bug
> > > in userspace relating to pointer auth. Also, one may wish to quantify
> > > the performance overhead of pointer auth by running a workload
> > > with/without it.
> > 
> > If you're debugging userspace, just recompile your userspace application
> > without ptr auth, in the same way that you might recompile with -g.
> > 
> > The performance argument sucks; this stuff needs to be fast otherwise it's
> > pointless. If you really need that last bit of speed, try Gentoo ;)
> 
> I've tried Gentoo, and I liked it :-).

In fact, I used to use it as well but it's a total bugger if you forget
to update for a week or so. I remember an awful program called revdep-rebuild
or something. Dreadful stuff, but good fun (and, incidentally, what got me
interested in the kernel).

> Apologies, I could have done a better job with the commit log...

I've got to be honest, but the commit log smells of "I'm doing this because
somebody asked me to, not because I think it's a good idea"... Maybe I'm
wrong.

> I am trying to enable pointer authentication in distros. One concern I have
> is that a pointer auth bug could slip through the cracks (with a lot of
> hardware not yet supporting pointer auth), and then affect an end user.

Why is that different to any other feature we expose to userspace? Bugs
happen, and we deal with them.

> Also, I have had interest from distros in the performance cost of pointer
> auth, and there will very likely be folk switching it off/on again in
> order to perform tests.

And they can do that with the compiler at the same time as they pass
-funsafe-math -Ofast.

> One approach to deploying this could be to have pointer auth disabled in
> the kernel completely (via kconfig) and interested parties could then
> switch kernels. Trouble with this is that distros ship single binaries so
> it would be up to the end user to build/install another kernel + modules.
> So this could be a barrier to adoption.

Shipping multiple kernels is a non-starter, but I fail to see why that
is even a consideration given that this really isn't a kernel problem
afaict.

> Having a mechanism in the kernel that an end user can employ to activate/
> de-activate pointer auth would help with deployment greatly, and that is
> what I was trying to achieve with this patch.
> 
> Another way to approach this could be via a kernel command line that
> completely disables pointer auth? (i.e. kernel not activating pointer auth
> at all, and userspace not seeing the feature)

I did wonder briefly about overriding the sanitised ID registers on the
command-line, but I think it opens a door that we'll regret opening later
on.

Will
Jeremy Linton July 9, 2020, 2:34 p.m. UTC | #4
Hi,

On 7/8/20 5:08 PM, Will Deacon wrote:
> Hi Steve,
> 
> On Wed, Jul 08, 2020 at 02:46:52PM +0100, Steve Capper wrote:
>> On Wed, Jul 08, 2020 at 08:36:21AM +0100, Will Deacon wrote:
>>> On Tue, Jul 07, 2020 at 06:32:32PM +0100, Steve Capper wrote:
>>>> Pointer authentication is a mandatory feature in the Armv8.3
>>>> architecture that provides protection against return oriented
>>>> programming attacks. (meaning that all Arm CPUs targetting at least
>>>> Armv8.3 will have this feature).
>>>>
>>>> Once CONFIG_ARM64_PTR_AUTH=y, any systems with the hardware support for
>>>> pointer authentication will automatically have it enabled by the kernel.
>>>>
>>>> There are, however, situations where end users may want to disable
>>>> pointer authentication. One could be tracking down/working around a bug
>>>> in userspace relating to pointer auth. Also, one may wish to quantify
>>>> the performance overhead of pointer auth by running a workload
>>>> with/without it.
>>>
>>> If you're debugging userspace, just recompile your userspace application
>>> without ptr auth, in the same way that you might recompile with -g >>>
>>> The performance argument sucks; this stuff needs to be fast otherwise it's
>>> pointless. If you really need that last bit of speed, try Gentoo ;)
>>
>> I've tried Gentoo, and I liked it :-).
> 
> In fact, I used to use it as well but it's a total bugger if you forget
> to update for a week or so. I remember an awful program called revdep-rebuild
> or something. Dreadful stuff, but good fun (and, incidentally, what got me
> interested in the kernel).
> 
>> Apologies, I could have done a better job with the commit log...
> 
> I've got to be honest, but the commit log smells of "I'm doing this because
> somebody asked me to, not because I think it's a good idea"... Maybe I'm
> wrong. >
>> I am trying to enable pointer authentication in distros. One concern I have
>> is that a pointer auth bug could slip through the cracks (with a lot of
>> hardware not yet supporting pointer auth), and then affect an end user.
> 
> Why is that different to any other feature we expose to userspace? Bugs
> happen, and we deal with them.
> 
>> Also, I have had interest from distros in the performance cost of pointer
>> auth, and there will very likely be folk switching it off/on again in
>> order to perform tests.
> 
> And they can do that with the compiler at the same time as they pass
> -funsafe-math -Ofast.

So, a bit of background. Pointer auth has been accepted as a systemwide 
change for Fedora 33. That acceptance requires contingency planning for 
what to do if the feature is causing ship blocking/etc defects. While we 
are going to do our best to test it before release, as your aware, the 
8.3+ machines are in short supply. Most of the community testing & 
debugging will simply be to assure that we don't break anything on v8.0 
machines. Which means that its quite likely that the bugs are going to 
be reported by end users with 8.3+ hardware who don't compile their own 
packages, nor debug them (and the idea that we can get any kind of 
coverage on tens of thousands of packages is crazy). Given many of the 
bugs so far have been subtle glibc/gcc/etc they are also far ranging. 
So, being able to give the end user a simple way to a->b test whether a 
problem goes away helps us to triage whether we are looking at a generic 
bug, or one related to pointer auth (or for that matter an active 
attack). Further, should it happen to something during the boot process 
(which is significantly more complex on fedora than the usual 
kernel+busybox+disk image) then we need a straightforward method to boot 
the end users machines so they can in-place install/upgrade/test.

In summary I see this sort of similar to selinux=0, a flag that no one 
should be using, but is still frequently used because its required just 
to boot a machine in order to fix a problem.

> 
>> One approach to deploying this could be to have pointer auth disabled in
>> the kernel completely (via kconfig) and interested parties could then
>> switch kernels. Trouble with this is that distros ship single binaries so
>> it would be up to the end user to build/install another kernel + modules.
>> So this could be a barrier to adoption.
> 
> Shipping multiple kernels is a non-starter, but I fail to see why that
> is even a consideration given that this really isn't a kernel problem
> afaict.

We need a way to ship all the PAC enabled binary artifacts but assure 
they can be quickly/easily reverted to pre 8.3 pointer auth code paths, 
which have been more heavily tested. Rebuilding the entire distro to 
globally disable pointer auth is a non starter, particularly after it 
has shipped.


> 
>> Having a mechanism in the kernel that an end user can employ to activate/
>> de-activate pointer auth would help with deployment greatly, and that is
>> what I was trying to achieve with this patch.
>>
>> Another way to approach this could be via a kernel command line that
>> completely disables pointer auth? (i.e. kernel not activating pointer auth
>> at all, and userspace not seeing the feature)
> 
> I did wonder briefly about overriding the sanitised ID registers on the
> command-line, but I think it opens a door that we'll regret opening later
> on.
> 
> Will
>
Catalin Marinas July 14, 2020, 5:52 p.m. UTC | #5
On Wed, Jul 08, 2020 at 11:08:06PM +0100, Will Deacon wrote:
> On Wed, Jul 08, 2020 at 02:46:52PM +0100, Steve Capper wrote:
> > On Wed, Jul 08, 2020 at 08:36:21AM +0100, Will Deacon wrote:
> > > On Tue, Jul 07, 2020 at 06:32:32PM +0100, Steve Capper wrote:
> > > > Pointer authentication is a mandatory feature in the Armv8.3
> > > > architecture that provides protection against return oriented
> > > > programming attacks. (meaning that all Arm CPUs targetting at least
> > > > Armv8.3 will have this feature).
> > > > 
> > > > Once CONFIG_ARM64_PTR_AUTH=y, any systems with the hardware support for
> > > > pointer authentication will automatically have it enabled by the kernel.
> > > > 
> > > > There are, however, situations where end users may want to disable
> > > > pointer authentication. One could be tracking down/working around a bug
> > > > in userspace relating to pointer auth. Also, one may wish to quantify
> > > > the performance overhead of pointer auth by running a workload
> > > > with/without it.
[...]
> > Having a mechanism in the kernel that an end user can employ to activate/
> > de-activate pointer auth would help with deployment greatly, and that is
> > what I was trying to achieve with this patch.
> > 
> > Another way to approach this could be via a kernel command line that
> > completely disables pointer auth? (i.e. kernel not activating pointer auth
> > at all, and userspace not seeing the feature)
> 
> I did wonder briefly about overriding the sanitised ID registers on the
> command-line, but I think it opens a door that we'll regret opening later
> on.

I had attempted it in these two patches (together with the DT support):

https://lore.kernel.org/linux-arm-kernel/20200515171612.1020-24-catalin.marinas@arm.com/
https://lore.kernel.org/linux-arm-kernel/20200515171612.1020-25-catalin.marinas@arm.com/

(both patches now dropped; we have a way to disable the tagged addr ABI
already and reject the prctl() call)

Overriding the ID regs disables the feature for both user and kernel.
IIUC, Steve only wanted this disabled for user.

A light concern with this patch is that it still keeps the HWCAP around,
only that it makes this instructions behave as NOPs. So that would be a
deviation from what the HWCAP bit actually implies. From this
perspective, a big knob may be a cleaner option.

Anyway, I agree that opening the door would lead to more such requests
in the future. We should only do this if there is a high risk of the
feature going terribly wrong in the user space out there. AFAICT, that's
not entirely clear at the moment. Distros could carry such patch
temporarily and, if proven useful in the long run, we can revisit the
upstreaming story.
diff mbox series

Patch

diff --git a/Documentation/arm64/pointer-authentication.rst b/Documentation/arm64/pointer-authentication.rst
index 30b2ab06526b..e8bc8336bbf2 100644
--- a/Documentation/arm64/pointer-authentication.rst
+++ b/Documentation/arm64/pointer-authentication.rst
@@ -107,3 +107,35 @@  filter out the Pointer Authentication system key registers from
 KVM_GET/SET_REG_* ioctls and mask those features from cpufeature ID
 register. Any attempt to use the Pointer Authentication instructions will
 result in an UNDEFINED exception being injected into the guest.
+
+
+Disabling Pointer Authentication
+--------------------------------
+There are situations where end users may want to disable pointer
+authentication. One could be tracking down/working around a bug in
+userspace relating to pointer authentication. Also, one may wish to
+quantify the performance overhead of pointer authentication by running a
+workload with/without it.
+
+For hardware with pointer auth, there is the following sysctl:
+
+.. code-block:: none
+
+        abi.ptrauth_disabled=1
+
+which will disable pointer authentication for any new processes that are
+exec'ed. (Reverting to 0 will then re-enable pointer authentication for
+any new processes).
+
+One can also set this sysctl on the kernel command line:
+
+.. code-block:: none
+
+        sysctl.abi.ptrauth_disabled=1
+
+And this will ensure that pointer authentication is disabled for the init
+process onwards.
+
+Note that when pointer authentication is disabled by sysctl, the
+capabilities are still exposed to userspace and pointer authentication
+instructions can execute (it will just be as NOPs).
diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
index 52dead2a8640..29fdd379bf1c 100644
--- a/arch/arm64/include/asm/asm_pointer_auth.h
+++ b/arch/arm64/include/asm/asm_pointer_auth.h
@@ -82,6 +82,38 @@  alternative_else_nop_endif
 .Lno_addr_auth\@:
 	.endm
 
+	.macro ptrauth_switch_to_user tsk, tmp1, tmp2, tmpw
+alternative_if_not ARM64_HAS_ADDRESS_AUTH
+	b	.Ldont_disable\@
+alternative_else_nop_endif
+	mov	\tmp2, #THREAD_PTRAUTH_DISABLED
+	ldr	\tmpw, [\tsk, \tmp2]
+	cbz	\tmpw, .Ldont_disable\@
+	mrs	\tmp1, sctlr_el1
+	mov_q	\tmp2, ~(SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
+			SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
+	and	\tmp1, \tmp1, \tmp2
+	msr	sctlr_el1, \tmp1
+		// about to drop to EL0 which will give us an implicit isb
+.Ldont_disable\@:
+	.endm
+
+	.macro ptrauth_switch_to_kernel tsk, tmp1, tmp2, tmpw
+alternative_if_not ARM64_HAS_ADDRESS_AUTH
+	b	.Ldont_reenable\@
+alternative_else_nop_endif
+	mov	\tmp2, #THREAD_PTRAUTH_DISABLED
+	ldr	\tmpw, [\tsk, \tmp2]
+	cbz	\tmpw, .Ldont_reenable\@
+	mrs	\tmp1, sctlr_el1
+	mov_q	\tmp2, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
+			SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
+	orr	\tmp1, \tmp1, \tmp2
+	msr	sctlr_el1, \tmp1
+	isb	// already in kernel mode, need context synchronising event
+.Ldont_reenable\@:
+	.endm
+
 #else /* CONFIG_ARM64_PTR_AUTH */
 
 	.macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
@@ -93,6 +125,11 @@  alternative_else_nop_endif
 	.macro ptrauth_keys_install_kernel tsk, tmp1, tmp2, tmp3
 	.endm
 
+	.macro ptrauth_switch_to_user tsk, tmp1, tmp2, tmpw
+	.endm
+
+	.macro ptrauth_switch_to_kernel tsk, tmp1, tmp2, tmpw
+	.endm
 #endif /* CONFIG_ARM64_PTR_AUTH */
 
 #endif /* __ASM_ASM_POINTER_AUTH_H */
diff --git a/arch/arm64/include/asm/pointer_auth.h b/arch/arm64/include/asm/pointer_auth.h
index c6b4f0603024..82993561ddc4 100644
--- a/arch/arm64/include/asm/pointer_auth.h
+++ b/arch/arm64/include/asm/pointer_auth.h
@@ -76,8 +76,12 @@  static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr)
 	return ptrauth_clear_pac(ptr);
 }
 
-#define ptrauth_thread_init_user(tsk)					\
-	ptrauth_keys_init_user(&(tsk)->thread.keys_user)
+#define ptrauth_thread_init_user(tsk, disabled)					\
+do {										\
+	ptrauth_keys_init_user(&(tsk)->thread.keys_user);			\
+	(tsk)->thread.ptrauth_disabled = disabled;				\
+} while (0)
+
 #define ptrauth_thread_init_kernel(tsk)					\
 	ptrauth_keys_init_kernel(&(tsk)->thread.keys_kernel)
 #define ptrauth_thread_switch_kernel(tsk)				\
@@ -86,7 +90,7 @@  static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr)
 #else /* CONFIG_ARM64_PTR_AUTH */
 #define ptrauth_prctl_reset_keys(tsk, arg)	(-EINVAL)
 #define ptrauth_strip_insn_pac(lr)	(lr)
-#define ptrauth_thread_init_user(tsk)
+#define ptrauth_thread_init_user(tsk, disabled)
 #define ptrauth_thread_init_kernel(tsk)
 #define ptrauth_thread_switch_kernel(tsk)
 #endif /* CONFIG_ARM64_PTR_AUTH */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 240fe5e5b720..bb0b9edb5f9d 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -150,6 +150,7 @@  struct thread_struct {
 #ifdef CONFIG_ARM64_PTR_AUTH
 	struct ptrauth_keys_user	keys_user;
 	struct ptrauth_keys_kernel	keys_kernel;
+	unsigned int			ptrauth_disabled;
 #endif
 };
 
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 0577e2142284..eb686d9cf541 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -47,6 +47,7 @@  int main(void)
 #ifdef CONFIG_ARM64_PTR_AUTH
   DEFINE(THREAD_KEYS_USER,	offsetof(struct task_struct, thread.keys_user));
   DEFINE(THREAD_KEYS_KERNEL,	offsetof(struct task_struct, thread.keys_kernel));
+  DEFINE(THREAD_PTRAUTH_DISABLED,	offsetof(struct task_struct, thread.ptrauth_disabled));
 #endif
   BLANK();
   DEFINE(S_X0,			offsetof(struct pt_regs, regs[0]));
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 5304d193c79d..e3985521f763 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -180,6 +180,7 @@  alternative_cb_end
 	apply_ssbd 1, x22, x23
 
 	ptrauth_keys_install_kernel tsk, x20, x22, x23
+	ptrauth_switch_to_kernel tsk, x20, x22, w23
 
 	scs_load tsk, x20
 	.else
@@ -350,6 +351,7 @@  alternative_else_nop_endif
 
 	/* No kernel C function calls after this as user keys are set. */
 	ptrauth_keys_install_user tsk, x0, x1, x2
+	ptrauth_switch_to_user tsk, x0, x1, w2
 
 	apply_ssbd 0, x0, x1
 	.endif
@@ -920,6 +922,7 @@  SYM_FUNC_START(cpu_switch_to)
 	mov	sp, x9
 	msr	sp_el0, x1
 	ptrauth_keys_install_kernel x1, x8, x9, x10
+	ptrauth_switch_to_kernel x1, x8, x9, w10
 	scs_save x0, x8
 	scs_load x1, x8
 	ret
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 6089638c7d43..781f2b7bd986 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -580,6 +580,8 @@  unsigned long arch_align_stack(unsigned long sp)
 	return sp & ~0xf;
 }
 
+static unsigned int ptrauth_disabled;
+
 /*
  * Called from setup_new_exec() after (COMPAT_)SET_PERSONALITY.
  */
@@ -587,9 +589,36 @@  void arch_setup_new_exec(void)
 {
 	current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0;
 
-	ptrauth_thread_init_user(current);
+	ptrauth_thread_init_user(current, ptrauth_disabled);
+}
+
+#ifdef CONFIG_ARM64_PTR_AUTH
+
+static struct ctl_table ptrauth_disable_sysctl_table[] = {
+	{
+		.procname	= "ptrauth_disabled",
+		.mode		= 0644,
+		.data		= &ptrauth_disabled,
+		.maxlen		= sizeof(ptrauth_disabled),
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= SYSCTL_ONE,
+	},
+	{}
+
+};
+
+static int __init ptrauth_disable_init(void)
+{
+	if (!register_sysctl("abi", ptrauth_disable_sysctl_table))
+		return -EINVAL;
+	return 0;
 }
 
+core_initcall(ptrauth_disable_init);
+
+#endif /* CONFIG_ARM64_PTR_AUTH */
+
 #ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
 /*
  * Control the relaxed ABI allowing tagged user addresses into the kernel.