[PATCH v2 1/4] x86: Introduce CONFIG_IA32_EMULATION_DEFAULT_DISABLED Kconfig option

From: Nikolay Borisov
Date: Fri Jun 09 2023 - 07:13:23 EST


Distributions would like to reduce their attack surface as much as
possible but at the same time they have to cater to a wide variety of
legacy software. One such avenue where distros have to strike a balance
is the support for 32bit syscalls on a 64bit kernel. Ideally
distributions would have a way to set that policy in their kernel config
files and at the same time users should also have the ability to
override this decision. Introduce such mechanism in the face of
CONFIG_IA32_EMULATION_DEFAULT_DISABLED compile time option, which
defaults to 'N' i.e retains current behavio in case
CONFIG_IA32_EMULATION is enabled. If, however, a distributor would like
to change this policy they can do so via the newly introduced
CONFIG_IA32_EMULATION_DEFAULT_DISABLED. As a final note allow users to
override the decision via the ia32_mode boot time parameter.

Signed-off-by: Nikolay Borisov <nik.borisov@xxxxxxxx>
---
Documentation/admin-guide/kernel-parameters.txt | 4 ++++
arch/x86/Kconfig | 5 +++++
arch/x86/entry/common.c | 16 ++++++++++++++++
arch/x86/include/asm/traps.h | 4 ++++
4 files changed, 29 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 9e5bab29685f..7c01ab8bcd56 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1865,6 +1865,10 @@
0 -- machine default
1 -- force brightness inversion

+ ia32_mode= [X86-64]
+ Format: ia32_mode=disabled, ia32_mode=enabled
+ Allows to override the compile-time IA32_EMULATION option at boot time
+
icn= [HW,ISDN]
Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 53bab123a8ee..9c32fd720701 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -3038,6 +3038,11 @@ config IA32_EMULATION
64-bit kernel. You should likely turn this on, unless you're
100% sure that you don't have any 32-bit programs left.

+config IA32_EMULATION_DEFAULT_DISABLED
+ bool "IA32 Emulation default disabled"
+ default n
+ depends on IA32_EMULATION
+
config X86_X32_ABI
bool "x32 ABI for 64-bit mode"
depends on X86_64
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 6c2826417b33..6da89575e03e 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -19,6 +19,7 @@
#include <linux/nospec.h>
#include <linux/syscalls.h>
#include <linux/uaccess.h>
+#include <linux/init.h>

#ifdef CONFIG_XEN_PV
#include <xen/xen-ops.h>
@@ -96,6 +97,21 @@ static __always_inline int syscall_32_enter(struct pt_regs *regs)
return (int)regs->orig_ax;
}

+#ifdef CONFIG_IA32_EMULATION
+bool ia32_disabled = IS_ENABLED(CONFIG_IA32_EMULATION_DEFAULT_DISABLED);
+
+static int ia32_mode_override_cmdline(char *arg)
+{
+ if (!strcmp(arg, "disabled"))
+ ia32_disabled = true;
+ else if (!strcmp(arg, "enabled"))
+ ia32_disabled = false;
+
+ return 1;
+}
+__setup("ia32_mode=", ia32_mode_override_cmdline);
+#endif
+
/*
* Invoke a 32-bit syscall. Called with IRQs on in CONTEXT_KERNEL.
*/
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 47ecfff2c83d..dd93aac3718b 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -20,6 +20,10 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *e

extern bool ibt_selftest(void);

+#ifdef CONFIG_IA32_EMULATION
+extern bool ia32_disabled;
+#endif
+
#ifdef CONFIG_X86_F00F_BUG
/* For handling the FOOF bug */
void handle_invalid_op(struct pt_regs *regs);
--
2.34.1