1
0

initial commit

imported from https://salsa.debian.org/kernel-team/linux.git
commit 9d5cc9d9d6501d7f1dd7e194d4b245bd0b6c6a22
version 6.11.4-1
This commit is contained in:
2024-10-23 12:12:30 +03:00
commit c3d09a3e94
1108 changed files with 137488 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
Date: Tue, 13 Mar 2018 18:38:02 +0800
Subject: [PATCH 3/4] MODSIGN: checking the blacklisted hash before loading a
kernel module
Origin: https://lore.kernel.org/patchwork/patch/933175/
This patch adds the logic for checking the kernel module's hash
base on blacklist. The hash must be generated by sha256 and enrolled
to dbx/mokx.
For example:
sha256sum sample.ko
mokutil --mokx --import-hash $HASH_RESULT
Whether the signature on ko file is stripped or not, the hash can be
compared by kernel.
Cc: David Howells <dhowells@redhat.com>
Cc: Josh Boyer <jwboyer@fedoraproject.org>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
[Rebased by Luca Boccassi]
[bwh: Forward-ported to 5.19:
- The type parameter to is_hash_blacklisted() is now an enumeration
rather than a string
- Adjust filename, context]
---
kernel/module/signing.c | 59 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 2 deletions(-)
--- a/kernel/module/signing.c
+++ b/kernel/module/signing.c
@@ -13,6 +13,8 @@
#include <linux/verification.h>
#include <linux/security.h>
#include <crypto/public_key.h>
+#include <crypto/hash.h>
+#include <keys/system_keyring.h>
#include <uapi/linux/module.h>
#include "internal.h"
@@ -37,13 +39,60 @@
sig_enforce = true;
}
+static int mod_is_hash_blacklisted(const void *mod, size_t verifylen)
+{
+ struct crypto_shash *tfm;
+ struct shash_desc *desc;
+ size_t digest_size, desc_size;
+ u8 *digest;
+ int ret;
+
+ tfm = crypto_alloc_shash("sha256", 0, 0);
+ if (IS_ERR(tfm)) {
+ ret = PTR_ERR(tfm);
+ goto error_return;
+ }
+
+ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+ digest_size = crypto_shash_digestsize(tfm);
+ digest = kzalloc(digest_size + desc_size, GFP_KERNEL);
+ if (!digest) {
+ pr_err("digest memory buffer allocate fail\n");
+ ret = -ENOMEM;
+ goto error_digest;
+ }
+ desc = (void *)digest + digest_size;
+ desc->tfm = tfm;
+ ret = crypto_shash_init(desc);
+ if (ret < 0)
+ goto error_shash;
+
+ ret = crypto_shash_finup(desc, mod, verifylen, digest);
+ if (ret < 0)
+ goto error_shash;
+
+ pr_debug("%ld digest: %*phN\n", verifylen, (int) digest_size, digest);
+
+ ret = is_hash_blacklisted(digest, digest_size, BLACKLIST_HASH_BINARY);
+ if (ret == -EKEYREJECTED)
+ pr_err("Module hash %*phN is blacklisted\n",
+ (int) digest_size, digest);
+
+error_shash:
+ kfree(digest);
+error_digest:
+ crypto_free_shash(tfm);
+error_return:
+ return ret;
+}
+
/*
* Verify the signature on a module.
*/
int mod_verify_sig(const void *mod, struct load_info *info)
{
struct module_signature ms;
- size_t sig_len, modlen = info->len;
+ size_t sig_len, modlen = info->len, wholelen;
int ret;
pr_devel("==>%s(,%zu)\n", __func__, modlen);
@@ -51,6 +100,7 @@
if (modlen <= sizeof(ms))
return -EBADMSG;
+ wholelen = modlen + sizeof(MODULE_SIG_STRING) - 1;
memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms));
ret = mod_check_sig(&ms, modlen, "module");
@@ -61,10 +111,17 @@
modlen -= sig_len + sizeof(ms);
info->len = modlen;
- return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
VERIFY_USE_SECONDARY_KEYRING,
VERIFYING_MODULE_SIGNATURE,
NULL, NULL);
+ pr_devel("verify_pkcs7_signature() = %d\n", ret);
+
+ /* checking hash of module is in blacklist */
+ if (!ret)
+ ret = mod_is_hash_blacklisted(mod, wholelen);
+
+ return ret;
}
int module_sig_check(struct load_info *info, int flags)

View File

@@ -0,0 +1,33 @@
From: Robert Holmes <robeholmes@gmail.com>
Date: Tue, 23 Apr 2019 07:39:29 +0000
Subject: [PATCH] KEYS: Make use of platform keyring for module signature
verify
Bug-Debian: https://bugs.debian.org/935945
Bug-Debian: https://bugs.debian.org/1030200
Origin: https://src.fedoraproject.org/rpms/kernel/raw/master/f/KEYS-Make-use-of-platform-keyring-for-module-signature.patch
Forwarded: https://lore.kernel.org/linux-modules/qvgp2il2co4iyxkzxvcs4p2bpyilqsbfgcprtpfrsajwae2etc@3z2s2o52i3xg/t/#u
This allows a cert in DB to be used to sign modules,
in addition to certs in the MoK and built-in keyrings.
Signed-off-by: Robert Holmes <robeholmes@gmail.com>
Signed-off-by: Jeremy Cline <jcline@redhat.com>
[bwh: Forward-ported to 5.19: adjust filename]
[наб: reinstate for 6.1, re-write description]
---
--- a/kernel/module/signing.c
+++ b/kernel/module/signing.c
@@ -116,6 +116,13 @@ int mod_verify_sig(const void *mod, stru
VERIFYING_MODULE_SIGNATURE,
NULL, NULL);
pr_devel("verify_pkcs7_signature() = %d\n", ret);
+ if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) {
+ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+ VERIFY_USE_PLATFORM_KEYRING,
+ VERIFYING_MODULE_SIGNATURE,
+ NULL, NULL);
+ pr_devel("verify_pkcs7_signature() = %d\n", ret);
+ }
/* checking hash of module is in blacklist */
if (!ret)

View File

@@ -0,0 +1,29 @@
From 585cbcb982bffc4a8cee2f3d8d099fc64f9a74b9 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bluca@debian.org>
Date: Fri, 14 Oct 2022 00:22:06 +0200
Subject: [PATCH] trust machine keyring (MoK) by default
Forwarded: not-needed
Debian always trusted keys in MoK by default. Upstream made it
conditional on a new EFI variable being set.
To keep backward compatibility skip this check.
---
security/integrity/platform_certs/machine_keyring.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/security/integrity/platform_certs/machine_keyring.c b/security/integrity/platform_certs/machine_keyring.c
index a401640a63cd..0627f14eacbe 100644
--- a/security/integrity/platform_certs/machine_keyring.c
+++ b/security/integrity/platform_certs/machine_keyring.c
@@ -68,10 +68,7 @@ static bool __init trust_moklist(void)
if (!initialized) {
initialized = true;
- trust_mok = false;
-
- if (uefi_check_trust_mok_keys())
- trust_mok = true;
+ trust_mok = true;
}
return trust_mok;

View File

@@ -0,0 +1,149 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Mon, 24 Aug 2009 23:19:58 +0100
Subject: af9005: Use request_firmware() to load register init script
Forwarded: no
Read the register init script from the Windows driver. This is sick
but should avoid the potential copyright infringement in distributing
a version of the script which is directly derived from the driver.
---
drivers/media/dvb/dvb-usb/Kconfig | 2 +-
drivers/media/dvb/dvb-usb/af9005-fe.c | 66 ++++++++++++++++++++++++++------
2 files changed, 54 insertions(+), 14 deletions(-)
Index: debian-kernel/drivers/media/usb/dvb-usb/Kconfig
===================================================================
--- debian-kernel.orig/drivers/media/usb/dvb-usb/Kconfig
+++ debian-kernel/drivers/media/usb/dvb-usb/Kconfig
@@ -260,10 +260,10 @@ config DVB_USB_OPERA1
config DVB_USB_AF9005
tristate "Afatech AF9005 DVB-T USB1.1 support"
- depends on BROKEN
depends on DVB_USB
select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
+ select FW_LOADER
help
Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
and the TerraTec Cinergy T USB XE (Rev.1)
Index: debian-kernel/drivers/media/usb/dvb-usb/af9005-fe.c
===================================================================
--- debian-kernel.orig/drivers/media/usb/dvb-usb/af9005-fe.c
+++ debian-kernel/drivers/media/usb/dvb-usb/af9005-fe.c
@@ -9,10 +9,26 @@
* see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
*/
#include "af9005.h"
-#include "af9005-script.h"
#include "mt2060.h"
#include "qt1010.h"
#include <asm/div64.h>
+#include <linux/firmware.h>
+
+/* Register initialisation script to be extracted from the Windows driver */
+
+typedef struct {
+ __le16 reg;
+ u8 pos;
+ u8 len;
+ u8 val;
+ u8 pad;
+} __packed RegDesc;
+
+#define WIN_DRV_NAME "AF05BDA.sys"
+#define WIN_DRV_VERSION "6.3.2.1"
+#define WIN_DRV_SIZE 133504
+#define WIN_DRV_SCRIPT_OFFSET 88316
+#define WIN_DRV_SCRIPT_SIZE 1110
struct af9005_fe_state {
struct dvb_usb_device *d;
@@ -804,6 +820,8 @@ static int af9005_fe_init(struct dvb_fro
{
struct af9005_fe_state *state = fe->demodulator_priv;
struct dvb_usb_adapter *adap = fe->dvb->priv;
+ const struct firmware *fw;
+ const RegDesc *script;
int ret, i, scriptlen;
u8 temp, temp0 = 0, temp1 = 0, temp2 = 0;
u8 buf[2];
@@ -956,37 +974,55 @@ static int af9005_fe_init(struct dvb_fro
if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01)))
return ret;
- /* load init script */
- deb_info("load init script\n");
- scriptlen = sizeof(script) / sizeof(RegDesc);
+ /* load and validate init script */
+ deb_info("load init script from Windows driver\n");
+ ret = request_firmware(&fw, WIN_DRV_NAME, &state->d->udev->dev);
+ if (ret)
+ return ret;
+ BUILD_BUG_ON(sizeof(RegDesc) != 6);
+ if (fw->size != WIN_DRV_SIZE ||
+ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET,
+ "\x80\xa1\x00\x08\x0a\x00", 6) ||
+ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET + WIN_DRV_SCRIPT_SIZE - 6,
+ "\x49\xa3\x00\x06\x02\x00", 6)) {
+ err("%s is invalid - should be version %s, size %u bytes\n",
+ WIN_DRV_NAME, WIN_DRV_VERSION, WIN_DRV_SIZE);
+ ret = -EINVAL;
+ goto fail_release;
+ }
+
+ script = (const RegDesc *)(fw->data + WIN_DRV_SCRIPT_OFFSET);
+ scriptlen = WIN_DRV_SCRIPT_SIZE / sizeof(RegDesc);
for (i = 0; i < scriptlen; i++) {
+ u16 reg = le16_to_cpu(script[i].reg);
if ((ret =
- af9005_write_register_bits(state->d, script[i].reg,
+ af9005_write_register_bits(state->d, reg,
script[i].pos,
script[i].len, script[i].val)))
- return ret;
+ goto fail_release;
/* save 3 bytes of original fcw */
- if (script[i].reg == 0xae18)
+ if (reg == 0xae18)
temp2 = script[i].val;
- if (script[i].reg == 0xae19)
+ if (reg == 0xae19)
temp1 = script[i].val;
- if (script[i].reg == 0xae1a)
+ if (reg == 0xae1a)
temp0 = script[i].val;
/* save original unplug threshold */
- if (script[i].reg == xd_p_reg_unplug_th)
+ if (reg == xd_p_reg_unplug_th)
state->original_if_unplug_th = script[i].val;
- if (script[i].reg == xd_p_reg_unplug_rf_gain_th)
+ if (reg == xd_p_reg_unplug_rf_gain_th)
state->original_rf_unplug_th = script[i].val;
- if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th)
+ if (reg == xd_p_reg_unplug_dtop_if_gain_th)
state->original_dtop_if_unplug_th = script[i].val;
- if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th)
+ if (reg == xd_p_reg_unplug_dtop_rf_gain_th)
state->original_dtop_rf_unplug_th = script[i].val;
}
state->original_fcw =
((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0;
+ release_firmware(fw);
/* save original TOPs */
deb_info("save original TOPs\n");
@@ -1066,6 +1102,10 @@ static int af9005_fe_init(struct dvb_fro
deb_info("profit!\n");
return 0;
+
+fail_release:
+ release_firmware(fw);
+ return ret;
}
static int af9005_fe_sleep(struct dvb_frontend *fe)

View File

@@ -0,0 +1,153 @@
From: Linn Crosetto <linn@hpe.com>
Date: Tue, 30 Aug 2016 11:54:38 -0600
Subject: arm64: add kernel config option to lock down when in Secure Boot mode
Bug-Debian: https://bugs.debian.org/831827
Forwarded: no
Add a kernel configuration option to lock down the kernel, to restrict
userspace's ability to modify the running kernel when UEFI Secure Boot is
enabled. Based on the x86 patch by Matthew Garrett.
Determine the state of Secure Boot in the EFI stub and pass this to the
kernel using the FDT.
Signed-off-by: Linn Crosetto <linn@hpe.com>
[bwh: Forward-ported to 4.10: adjust context]
[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream]
[bwh: Forward-ported to 4.15 and lockdown patch set:
- Pass result of efi_get_secureboot() in stub through to
efi_set_secure_boot() in main kernel
- Use lockdown API and naming]
[bwh: Forward-ported to 4.19.3: adjust context in update_fdt()]
[dannf: Moved init_lockdown() call after uefi_init(), fixing SB detection]
[bwh: Drop call to init_lockdown(), as efi_set_secure_boot() now calls this]
[bwh: Forward-ported to 5.6: efi_get_secureboot() no longer takes a
sys_table parameter]
[bwh: Forward-ported to 5.7: EFI initialisation from FDT was rewritten, so:
- Add Secure Boot mode to the parameter enumeration in fdtparams.c
- Add a parameter to efi_get_fdt_params() to return the Secure Boot mode
- Since Xen does not have a property name defined for Secure Boot mode,
change efi_get_fdt_prop() to handle a missing property name by clearing
the output variable]
[Salvatore Bonaccorso: Forward-ported to 5.10: f30f242fb131 ("efi: Rename
arm-init to efi-init common for all arch") renamed arm-init.c to efi-init.c]
---
drivers/firmware/efi/efi-init.c | 5 ++++-
drivers/firmware/efi/fdtparams.c | 12 +++++++++++-
drivers/firmware/efi/libstub/fdt.c | 6 ++++++
include/linux/efi.h | 3 ++-
4 files changed, 23 insertions(+), 3 deletions(-)
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -210,9 +210,10 @@ void __init efi_init(void)
{
struct efi_memory_map_data data;
u64 efi_system_table;
+ u32 secure_boot;
/* Grab UEFI information placed in FDT by stub */
- efi_system_table = efi_get_fdt_params(&data);
+ efi_system_table = efi_get_fdt_params(&data, &secure_boot);
if (!efi_system_table)
return;
@@ -234,6 +235,8 @@ void __init efi_init(void)
return;
}
+ efi_set_secure_boot(secure_boot);
+
reserve_regions();
/*
* For memblock manipulation, the cap should come after the memblock_add().
--- a/drivers/firmware/efi/fdtparams.c
+++ b/drivers/firmware/efi/fdtparams.c
@@ -16,6 +16,7 @@ enum {
MMSIZE,
DCSIZE,
DCVERS,
+ SBMODE,
PARAMCOUNT
};
@@ -26,6 +27,7 @@ static __initconst const char name[][22]
[MMSIZE] = "MemMap Size ",
[DCSIZE] = "MemMap Desc. Size ",
[DCVERS] = "MemMap Desc. Version ",
+ [SBMODE] = "Secure Boot Enabled ",
};
static __initconst const struct {
@@ -41,6 +43,7 @@ static __initconst const struct {
[MMSIZE] = "xen,uefi-mmap-size",
[DCSIZE] = "xen,uefi-mmap-desc-size",
[DCVERS] = "xen,uefi-mmap-desc-ver",
+ [SBMODE] = "",
}
}, {
#endif
@@ -51,6 +54,7 @@ static __initconst const struct {
[MMSIZE] = "linux,uefi-mmap-size",
[DCSIZE] = "linux,uefi-mmap-desc-size",
[DCVERS] = "linux,uefi-mmap-desc-ver",
+ [SBMODE] = "linux,uefi-secure-boot",
}
}
};
@@ -62,6 +66,11 @@ static int __init efi_get_fdt_prop(const
int len;
u64 val;
+ if (!pname[0]) {
+ memset(var, 0, size);
+ return 0;
+ }
+
prop = fdt_getprop(fdt, node, pname, &len);
if (!prop)
return 1;
@@ -79,7 +88,7 @@ static int __init efi_get_fdt_prop(const
return 0;
}
-u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm)
+u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm, u32 *secure_boot)
{
const void *fdt = initial_boot_params;
unsigned long systab;
@@ -93,6 +102,7 @@ u64 __init efi_get_fdt_params(struct efi
[MMSIZE] = { &mm->size, sizeof(mm->size) },
[DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) },
[DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) },
+ [SBMODE] = { secure_boot, sizeof(*secure_boot) },
};
BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name));
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -148,6 +148,12 @@ static efi_status_t update_fdt(void *ori
}
}
+ fdt_val32 = cpu_to_fdt32(efi_get_secureboot());
+ status = fdt_setprop(fdt, node, "linux,uefi-secure-boot",
+ &fdt_val32, sizeof(fdt_val32));
+ if (status)
+ goto fdt_set_fail;
+
/* Shrink the FDT back to its minimum size: */
fdt_pack(fdt);
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -662,7 +662,8 @@ extern void efi_mem_reserve(phys_addr_t
extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size);
extern void efi_initialize_iomem_resources(struct resource *code_resource,
struct resource *data_resource, struct resource *bss_resource);
-extern u64 efi_get_fdt_params(struct efi_memory_map_data *data);
+extern u64 efi_get_fdt_params(struct efi_memory_map_data *data,
+ u32 *secure_boot);
extern struct kobject *efi_kobj;
extern int efi_reboot_quirk_mode;

View File

@@ -0,0 +1,153 @@
From: David Howells <dhowells@redhat.com>
Date: Mon, 18 Feb 2019 12:45:03 +0000
Subject: [28/30] efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode
Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a5d70c55c603233c192b375f72116a395909da28
UEFI machines can be booted in Secure Boot mode. Add an EFI_SECURE_BOOT
flag that can be passed to efi_enabled() to find out whether secure boot is
enabled.
Move the switch-statement in x86's setup_arch() that inteprets the
secure_boot boot parameter to generic code and set the bit there.
Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
cc: linux-efi@vger.kernel.org
[rperier: Forward-ported to 5.5:
- Use pr_warn()
- Adjust context]
[bwh: Forward-ported to 5.6: adjust context]
[bwh: Forward-ported to 5.7:
- Use the next available bit in efi.flags
- Adjust context]
---
arch/x86/kernel/setup.c | 14 +----------
drivers/firmware/efi/Makefile | 1 +
drivers/firmware/efi/secureboot.c | 39 +++++++++++++++++++++++++++++++
include/linux/efi.h | 16 ++++++++-----
4 files changed, 51 insertions(+), 19 deletions(-)
create mode 100644 drivers/firmware/efi/secureboot.c
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1193,19 +1193,7 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);
- if (efi_enabled(EFI_BOOT)) {
- switch (boot_params.secure_boot) {
- case efi_secureboot_mode_disabled:
- pr_info("Secure boot disabled\n");
- break;
- case efi_secureboot_mode_enabled:
- pr_info("Secure boot enabled\n");
- break;
- default:
- pr_info("Secure boot could not be determined\n");
- break;
- }
- }
+ efi_set_secure_boot(boot_params.secure_boot);
reserve_initrd();
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_m
obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o
obj-$(CONFIG_EFI_TEST) += test/
obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o
+obj-$(CONFIG_EFI) += secureboot.o
obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o
obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o
obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o
--- /dev/null
+++ b/drivers/firmware/efi/secureboot.c
@@ -0,0 +1,39 @@
+
+/* Core kernel secure boot support.
+ *
+ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/efi.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+
+/*
+ * Decide what to do when UEFI secure boot mode is enabled.
+ */
+void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
+{
+ if (efi_enabled(EFI_BOOT)) {
+ switch (mode) {
+ case efi_secureboot_mode_disabled:
+ pr_info("Secure boot disabled\n");
+ break;
+ case efi_secureboot_mode_enabled:
+ set_bit(EFI_SECURE_BOOT, &efi.flags);
+ pr_info("Secure boot enabled\n");
+ break;
+ default:
+ pr_warn("Secure boot could not be determined (mode %u)\n",
+ mode);
+ break;
+ }
+ }
+}
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -871,6 +871,14 @@ extern int __init efi_setup_pcdp_console
#define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
#define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */
#define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */
+#define EFI_SECURE_BOOT 13 /* Are we in Secure Boot mode? */
+
+enum efi_secureboot_mode {
+ efi_secureboot_mode_unset,
+ efi_secureboot_mode_unknown,
+ efi_secureboot_mode_disabled,
+ efi_secureboot_mode_enabled,
+};
#ifdef CONFIG_EFI
/*
@@ -895,6 +903,7 @@ static inline bool efi_rt_services_suppo
return (efi.runtime_supported_mask & mask) == mask;
}
extern void efi_find_mirror(void);
+extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode);
#else
static inline bool efi_enabled(int feature)
{
@@ -914,6 +923,7 @@ static inline bool efi_rt_services_suppo
}
static inline void efi_find_mirror(void) {}
+static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {}
#endif
extern int efi_status_to_err(efi_status_t status);
@@ -1133,13 +1143,6 @@ static inline bool efi_runtime_disabled(
extern void efi_call_virt_check_flags(unsigned long flags, const void *caller);
extern unsigned long efi_call_virt_save_flags(void);
-enum efi_secureboot_mode {
- efi_secureboot_mode_unset,
- efi_secureboot_mode_unknown,
- efi_secureboot_mode_disabled,
- efi_secureboot_mode_enabled,
-};
-
static inline
enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var)
{

View File

@@ -0,0 +1,121 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Tue, 10 Sep 2019 11:54:28 +0100
Subject: efi: Lock down the kernel if booted in secure boot mode
Based on an earlier patch by David Howells, who wrote the following
description:
> UEFI Secure Boot provides a mechanism for ensuring that the firmware will
> only load signed bootloaders and kernels. Certain use cases may also
> require that all kernel modules also be signed. Add a configuration option
> that to lock down the kernel - which includes requiring validly signed
> modules - if the kernel is secure-booted.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
[Salvatore Bonaccorso: After fixing https://bugs.debian.org/956197 the
help text for LOCK_DOWN_IN_EFI_SECURE_BOOT was adjusted to mention that
lockdown is triggered in integrity mode (https://bugs.debian.org/1025417)]
Signed-off-by: Salvatore Bonaccorso <carnil@debian.org>
---
arch/x86/kernel/setup.c | 4 ++--
drivers/firmware/efi/secureboot.c | 3 +++
include/linux/security.h | 6 ++++++
security/lockdown/Kconfig | 15 +++++++++++++++
security/lockdown/lockdown.c | 2 +-
5 files changed, 27 insertions(+), 3 deletions(-)
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -900,6 +900,8 @@ void __init setup_arch(char **cmdline_p)
if (efi_enabled(EFI_BOOT))
efi_init();
+ efi_set_secure_boot(boot_params.secure_boot);
+
reserve_ibft_region();
x86_init.resources.dmi_setup();
@@ -1061,8 +1063,6 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);
- efi_set_secure_boot(boot_params.secure_boot);
-
reserve_initrd();
acpi_table_upgrade();
--- a/drivers/firmware/efi/secureboot.c
+++ b/drivers/firmware/efi/secureboot.c
@@ -15,6 +15,7 @@
#include <linux/efi.h>
#include <linux/kernel.h>
#include <linux/printk.h>
+#include <linux/security.h>
/*
* Decide what to do when UEFI secure boot mode is enabled.
@@ -28,6 +29,10 @@ void __init efi_set_secure_boot(enum efi
break;
case efi_secureboot_mode_enabled:
set_bit(EFI_SECURE_BOOT, &efi.flags);
+#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
+ lock_kernel_down("EFI Secure Boot",
+ LOCKDOWN_INTEGRITY_MAX);
+#endif
pr_info("Secure boot enabled\n");
break;
default:
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -509,6 +509,7 @@ int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
int security_locked_down(enum lockdown_reason what);
int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len,
void *val, size_t val_len, u64 id, u64 flags);
+int lock_kernel_down(const char *where, enum lockdown_reason level);
#else /* CONFIG_SECURITY */
static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -1483,6 +1484,11 @@ static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx,
{
return -EOPNOTSUPP;
}
+static inline int
+lock_kernel_down(const char *where, enum lockdown_reason level)
+{
+ return -EOPNOTSUPP;
+}
#endif /* CONFIG_SECURITY */
#if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
--- a/security/lockdown/Kconfig
+++ b/security/lockdown/Kconfig
@@ -45,3 +45,18 @@ config LOCK_DOWN_KERNEL_FORCE_CONFIDENTI
disabled.
endchoice
+
+config LOCK_DOWN_IN_EFI_SECURE_BOOT
+ bool "Lock down the kernel in EFI Secure Boot mode"
+ default n
+ depends on SECURITY_LOCKDOWN_LSM
+ depends on EFI
+ select SECURITY_LOCKDOWN_LSM_EARLY
+ help
+ UEFI Secure Boot provides a mechanism for ensuring that the firmware
+ will only load signed bootloaders and kernels. Secure boot mode may
+ be determined from EFI variables provided by the system firmware if
+ not indicated by the boot parameters.
+
+ Enabling this option results in kernel lockdown being
+ triggered in integrity mode if EFI Secure Boot is set.
--- a/security/lockdown/lockdown.c
+++ b/security/lockdown/lockdown.c
@@ -24,7 +24,7 @@ static const enum lockdown_reason lockdo
/*
* Put the kernel into lock-down mode.
*/
-static int lock_kernel_down(const char *where, enum lockdown_reason level)
+int lock_kernel_down(const char *where, enum lockdown_reason level)
{
if (kernel_locked_down >= level)
return -EPERM;

View File

@@ -0,0 +1,75 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Fri, 30 Aug 2019 15:54:24 +0100
Subject: mtd: phram,slram: Disable when the kernel is locked down
Forwarded: https://lore.kernel.org/linux-security-module/20190830154720.eekfjt6c4jzvlbfz@decadent.org.uk/
These drivers allow mapping arbitrary memory ranges as MTD devices.
This should be disabled to preserve the kernel's integrity when it is
locked down.
* Add the HWPARAM flag to the module parameters
* When slram is built-in, it uses __setup() to read kernel parameters,
so add an explicit check security_locked_down() check
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Cc: Matthew Garrett <mjg59@google.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Joern Engel <joern@lazybastard.org>
Cc: linux-mtd@lists.infradead.org
---
drivers/mtd/devices/phram.c | 6 +++++-
drivers/mtd/devices/slram.c | 9 ++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -364,7 +364,11 @@ static int phram_param_call(const char *
#endif
}
-module_param_call(phram, phram_param_call, NULL, NULL, 0200);
+static const struct kernel_param_ops phram_param_ops = {
+ .set = phram_param_call
+};
+__module_param_call(MODULE_PARAM_PREFIX, phram, &phram_param_ops, NULL,
+ 0200, -1, KERNEL_PARAM_FL_HWPARAM | hwparam_iomem);
MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>[,<erasesize>]\"");
#ifdef CONFIG_OF
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -43,6 +43,7 @@
#include <linux/ioctl.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/security.h>
#include <linux/mtd/mtd.h>
@@ -65,7 +66,7 @@ typedef struct slram_mtd_list {
#ifdef MODULE
static char *map[SLRAM_MAX_DEVICES_PARAMS];
-module_param_array(map, charp, NULL, 0);
+module_param_hw_array(map, charp, iomem, NULL, 0);
MODULE_PARM_DESC(map, "List of memory regions to map. \"map=<name>, <start>, <length / end>\"");
#else
static char *map;
@@ -281,11 +282,17 @@ static int __init init_slram(void)
#ifndef MODULE
char *devstart;
char *devlength;
+ int ret;
if (!map) {
E("slram: not enough parameters.\n");
return(-EINVAL);
}
+
+ ret = security_locked_down(LOCKDOWN_MODULE_PARAMETERS);
+ if (ret)
+ return ret;
+
while (map) {
devname = devstart = devlength = NULL;

View File

@@ -0,0 +1,80 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Mon, 11 Jan 2016 15:23:55 +0000
Subject: security,perf: Allow further restriction of perf_event_open
Forwarded: https://lore.kernel.org/all/20160111152355.GS28542@decadent.org.uk/
When kernel.perf_event_open is set to 3 (or greater), disallow all
access to performance events by users without CAP_SYS_ADMIN.
Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that
makes this value the default.
This is based on a similar feature in grsecurity
(CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making
the variable read-only. It also allows enabling further restriction
at run-time regardless of whether the default is changed.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
include/linux/perf_event.h | 5 +++++
kernel/events/core.c | 8 ++++++++
security/Kconfig | 9 +++++++++
3 files changed, 22 insertions(+)
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1589,6 +1589,11 @@ int perf_cpu_time_max_percent_handler(co
int perf_event_max_stack_handler(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos);
+static inline bool perf_paranoid_any(void)
+{
+ return sysctl_perf_event_paranoid > 2;
+}
+
/* Access to perf_event_open(2) syscall. */
#define PERF_SECURITY_OPEN 0
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -419,8 +419,13 @@ static struct kmem_cache *perf_event_cac
* 0 - disallow raw tracepoint access for unpriv
* 1 - disallow cpu events for unpriv
* 2 - disallow kernel profiling for unpriv
+ * 3 - disallow all unpriv perf event use
*/
+#ifdef CONFIG_SECURITY_PERF_EVENTS_RESTRICT
+int sysctl_perf_event_paranoid __read_mostly = 3;
+#else
int sysctl_perf_event_paranoid __read_mostly = 2;
+#endif
/* Minimum for 512 kiB + 1 user control page */
int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */
@@ -12506,6 +12511,9 @@ SYSCALL_DEFINE5(perf_event_open,
if (err)
return err;
+ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
/* Do we allow access to perf_event_open(2) ? */
err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
if (err)
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -51,6 +51,15 @@ config PROC_MEM_NO_FORCE
endchoice
+config SECURITY_PERF_EVENTS_RESTRICT
+ bool "Restrict unprivileged use of performance events"
+ depends on PERF_EVENTS
+ help
+ If you say Y here, the kernel.perf_event_paranoid sysctl
+ will be set to 3 by default, and no unprivileged use of the
+ perf_event_open syscall will be permitted unless it is
+ changed.
+
config SECURITY
bool "Enable different security models"
depends on SYSFS

View File

@@ -0,0 +1,74 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Wed, 21 Aug 2019 00:32:16 +0100
Subject: intel-iommu: Add Kconfig option to exclude iGPU by default
Bug-Debian: https://bugs.debian.org/935270
Bug-Kali: https://bugs.kali.org/view.php?id=5644
There is still laptop firmware that touches the integrated GPU behind
the operating system's back, and doesn't say so in the RMRR table.
Enabling the IOMMU for all devices causes breakage.
Replace CONFIG_INTEL_IOMMU_DEFAULT_ON with a 3-way choice
corresponding to "on", "off", and "on,intgpu_off".
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/drivers/iommu/intel/Kconfig
+++ b/drivers/iommu/intel/Kconfig
@@ -57,13 +57,24 @@ config INTEL_IOMMU_SVM
to access DMA resources through process address space by
means of a Process Address Space ID (PASID).
-config INTEL_IOMMU_DEFAULT_ON
- bool "Enable Intel DMA Remapping Devices by default"
- default y
+choice
+ prompt "Default state of Intel DMA Remapping Devices"
+ default INTEL_IOMMU_DEFAULT_ON
help
- Selecting this option will enable a DMAR device at boot time if
- one is found. If this option is not selected, DMAR support can
- be enabled by passing intel_iommu=on to the kernel.
+ Choose whether Intel DMA Remapping Devices should be enabled
+ by default. This can be overridden at boot time using the
+ intel_iommu= kernel parameter.
+
+config INTEL_IOMMU_DEFAULT_ON
+ bool "Enable"
+
+config INTEL_IOMMU_DEFAULT_ON_INTGPU_OFF
+ bool "Enable, excluding integrated GPU"
+
+config INTEL_IOMMU_DEFAULT_OFF
+ bool "Disable"
+
+endchoice
config INTEL_IOMMU_FLOPPY_WA
def_bool y
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -218,13 +218,13 @@ static LIST_HEAD(dmar_satc_units);
static void intel_iommu_domain_free(struct iommu_domain *domain);
-int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
+int dmar_disabled = IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_OFF);
int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
int intel_iommu_enabled = 0;
EXPORT_SYMBOL_GPL(intel_iommu_enabled);
-static int dmar_map_intgpu = 1;
+static int dmar_map_intgpu = IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
static int intel_iommu_superpage = 1;
static int iommu_identity_mapping;
static int iommu_skip_te_disable;
@@ -263,6 +263,7 @@ static int __init intel_iommu_setup(char
while (*str) {
if (!strncmp(str, "on", 2)) {
dmar_disabled = 0;
+ dmar_map_intgpu = 1;
pr_info("IOMMU enabled\n");
} else if (!strncmp(str, "off", 3)) {
dmar_disabled = 1;

View File

@@ -0,0 +1,90 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Wed, 21 Aug 2019 00:05:30 +0100
Subject: intel-iommu: Add option to exclude integrated GPU only
Bug-Debian: https://bugs.debian.org/935270
Bug-Kali: https://bugs.kali.org/view.php?id=5644
There is still laptop firmware that touches the integrated GPU behind
the operating system's back, and doesn't say so in the RMRR table.
Enabling the IOMMU for all devices causes breakage, but turning it off
for all graphics devices seems like a major weakness.
Add an option, intel_iommu=intgpu_off, to exclude only integrated GPUs
from remapping. This is a narrower exclusion than igfx_off: it only
affects Intel devices on the root bus. Devices attached through an
external port (Thunderbolt or ExpressCard) won't be on the root bus.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
Documentation/admin-guide/kernel-parameters.txt | 2 ++
drivers/iommu/intel/iommu.c | 14 ++++++++++++++
2 files changed, 16 insertions(+)
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2174,6 +2174,8 @@
bypassed by not enabling DMAR with this option. In
this case, gfx device will use physical address for
DMA.
+ intgpu_off [Default Off]
+ Bypass the DMAR unit for an integrated GPU only.
strict [Default Off]
Deprecated, equivalent to iommu.strict=1.
sp_off [Default Off]
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -35,6 +35,9 @@
#define CONTEXT_SIZE VTD_PAGE_SIZE
#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
+#define IS_INTGPU_DEVICE(pdev) (IS_GFX_DEVICE(pdev) && \
+ (pdev)->vendor == 0x8086 && \
+ pci_is_root_bus((pdev)->bus))
#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
@@ -221,12 +224,14 @@ int intel_iommu_sm = IS_ENABLED(CONFIG_I
int intel_iommu_enabled = 0;
EXPORT_SYMBOL_GPL(intel_iommu_enabled);
+static int dmar_map_intgpu = 1;
static int intel_iommu_superpage = 1;
static int iommu_identity_mapping;
static int iommu_skip_te_disable;
static int disable_igfx_iommu;
#define IDENTMAP_AZALIA 4
+#define IDENTMAP_INTGPU 8
const struct iommu_ops intel_iommu_ops;
static const struct iommu_dirty_ops intel_dirty_ops;
@@ -266,6 +271,9 @@ static int __init intel_iommu_setup(char
} else if (!strncmp(str, "igfx_off", 8)) {
disable_igfx_iommu = 1;
pr_info("Disable GFX device mapping\n");
+ } else if (!strncmp(str, "intgpu_off", 10)) {
+ dmar_map_intgpu = 0;
+ pr_info("Disable integrated GPU device mapping\n");
} else if (!strncmp(str, "forcedac", 8)) {
pr_warn("intel_iommu=forcedac deprecated; use iommu.forcedac instead\n");
iommu_dma_forcedac = true;
@@ -2401,6 +2409,9 @@ static int device_def_domain_type(struct
if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
return IOMMU_DOMAIN_IDENTITY;
+
+ if ((iommu_identity_mapping & IDENTMAP_INTGPU) && IS_INTGPU_DEVICE(pdev))
+ return IOMMU_DOMAIN_IDENTITY;
}
return 0;
@@ -2701,6 +2712,9 @@ static int __init init_dmars(void)
iommu_set_root_entry(iommu);
}
+ if (!dmar_map_intgpu)
+ iommu_identity_mapping |= IDENTMAP_INTGPU;
+
check_tylersburg_isoch();
ret = si_domain_init(hw_pass_through);

View File

@@ -0,0 +1,180 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Mon, 12 Feb 2018 23:59:26 +0000
Subject: x86: Make x32 syscall support conditional on a kernel parameter
Bug-Debian: https://bugs.debian.org/708070
Forwarded: https://lore.kernel.org/lkml/1415245982.3398.53.camel@decadent.org.uk/T/#u
Enabling x32 in the standard amd64 kernel would increase its attack
surface while provide no benefit to the vast majority of its users.
No-one seems interested in regularly checking for vulnerabilities
specific to x32 (at least no-one with a white hat).
Still, adding another flavour just to turn on x32 seems wasteful. And
the only differences on syscall entry are a few instructions that mask
out the x32 flag and compare the syscall number.
Use a static key to control whether x32 syscalls are really enabled, a
Kconfig parameter to set its default value and a kernel parameter
"syscall.x32" to change it at boot time.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
.../admin-guide/kernel-parameters.txt | 4 ++
arch/x86/Kconfig | 8 ++++
arch/x86/entry/common.c | 3 +-
arch/x86/entry/syscall_64.c | 46 +++++++++++++++++++
arch/x86/include/asm/elf.h | 6 ++-
arch/x86/include/asm/syscall.h | 13 ++++++
6 files changed, 78 insertions(+), 2 deletions(-)
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -6498,6 +6498,10 @@
later by a loaded module cannot be set this way.
Example: sysctl.vm.swappiness=40
+ syscall.x32= [KNL,x86_64] Enable/disable use of x32 syscalls on
+ an x86_64 kernel where CONFIG_X86_X32 is enabled.
+ Default depends on CONFIG_X86_X32_DISABLED.
+
sysrq_always_enabled
[KNL]
Ignore sysrq setting - this boot parameter will
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -3058,6 +3058,14 @@ config COMPAT_32
select HAVE_UID16
select OLD_SIGSUSPEND3
+config X86_X32_DISABLED
+ bool "x32 ABI disabled by default"
+ depends on X86_X32_ABI
+ default n
+ help
+ Disable the x32 ABI unless explicitly enabled using the
+ kernel paramter "syscall.x32=y".
+
config COMPAT
def_bool y
depends on IA32_EMULATION || X86_X32_ABI
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -64,7 +64,7 @@ static __always_inline bool do_syscall_x
*/
unsigned int xnr = nr - __X32_SYSCALL_BIT;
- if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(xnr < X32_NR_syscalls)) {
+ if (IS_ENABLED(CONFIG_X86_X32_ABI) && unlikely(x32_enabled) && likely(xnr < X32_NR_syscalls)) {
xnr = array_index_nospec(xnr, X32_NR_syscalls);
regs->ax = x32_sys_call(regs, xnr);
return true;
--- a/arch/x86/entry/syscall_x32.c
+++ b/arch/x86/entry/syscall_x32.c
@@ -4,6 +4,9 @@
#include <linux/linkage.h>
#include <linux/sys.h>
#include <linux/cache.h>
+#include <linux/moduleparam.h>
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX "syscall."
#include <linux/syscalls.h>
#include <asm/syscall.h>
@@ -20,3 +23,46 @@
default: return __x64_sys_ni_syscall(regs);
}
};
+
+/* Maybe enable x32 syscalls */
+
+#if defined(CONFIG_X86_X32_DISABLED)
+DEFINE_STATIC_KEY_FALSE(x32_enabled_skey);
+#else
+DEFINE_STATIC_KEY_TRUE(x32_enabled_skey);
+#endif
+
+static int __init x32_param_set(const char *val, const struct kernel_param *p)
+{
+ bool enabled;
+ int ret;
+
+ ret = kstrtobool(val, &enabled);
+ if (ret)
+ return ret;
+ if (IS_ENABLED(CONFIG_X86_X32_DISABLED)) {
+ if (enabled) {
+ static_key_enable(&x32_enabled_skey.key);
+ pr_info("Enabled x32 syscalls\n");
+ }
+ } else {
+ if (!enabled) {
+ static_key_disable(&x32_enabled_skey.key);
+ pr_info("Disabled x32 syscalls\n");
+ }
+ }
+ return 0;
+}
+
+static int x32_param_get(char *buffer, const struct kernel_param *p)
+{
+ return sprintf(buffer, "%c\n",
+ static_key_enabled(&x32_enabled_skey) ? 'Y' : 'N');
+}
+
+static const struct kernel_param_ops x32_param_ops = {
+ .set = x32_param_set,
+ .get = x32_param_get,
+};
+
+arch_param_cb(x32, &x32_param_ops, NULL, 0444);
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -12,6 +12,9 @@
#include <asm/user.h>
#include <asm/auxvec.h>
#include <asm/fsgsbase.h>
+#ifndef COMPILE_OFFSETS /* avoid a circular dependency on asm-offsets.h */
+#include <asm/syscall.h>
+#endif
typedef unsigned long elf_greg_t;
@@ -151,7 +154,8 @@ do { \
#define compat_elf_check_arch(x) \
((elf_check_arch_ia32(x) && ia32_enabled_verbose()) || \
- (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64))
+ (IS_ENABLED(CONFIG_X86_X32_ABI) && x32_enabled && \
+ (x)->e_machine == EM_X86_64))
static inline void elf_common_init(struct thread_struct *t,
struct pt_regs *regs, const u16 ds)
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -13,6 +13,7 @@
#include <uapi/linux/audit.h>
#include <linux/sched.h>
#include <linux/err.h>
+#include <linux/jump_label.h>
#include <asm/thread_info.h> /* for TS_COMPAT */
#include <asm/unistd.h>
@@ -28,6 +29,18 @@ extern const sys_call_ptr_t ia32_sys_cal
extern long x32_sys_call(const struct pt_regs *, unsigned int nr);
extern long x64_sys_call(const struct pt_regs *, unsigned int nr);
+#if defined(CONFIG_X86_X32_ABI)
+#if defined(CONFIG_X86_X32_DISABLED)
+DECLARE_STATIC_KEY_FALSE(x32_enabled_skey);
+#define x32_enabled static_branch_unlikely(&x32_enabled_skey)
+#else
+DECLARE_STATIC_KEY_TRUE(x32_enabled_skey);
+#define x32_enabled static_branch_likely(&x32_enabled_skey)
+#endif
+#else
+#define x32_enabled 0
+#endif
+
/*
* Only the low 32 bits of orig_ax are meaningful, so we return int.
* This importantly ignores the high bits on 64-bit, so comparisons

View File

@@ -0,0 +1,28 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Mon, 5 Dec 2011 04:00:58 +0000
Subject: x86: memtest: WARN if bad RAM found
Bug-Debian: https://bugs.debian.org/613321
Forwarded: https://lore.kernel.org/all/20120402150522.GA4980@burratino/
Since this is not a particularly thorough test, if we find any bad
bits of RAM then there is a fair chance that there are other bad bits
we fail to detect.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
mm/memtest.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
--- a/mm/memtest.c
+++ b/mm/memtest.c
@@ -26,6 +26,10 @@ static u64 patterns[] __initdata = {
static void __init reserve_bad_mem(u64 pattern, phys_addr_t start_bad, phys_addr_t end_bad)
{
+#ifdef CONFIG_X86
+ WARN_ONCE(1, "Bad RAM detected. Use memtest86+ to perform a thorough test\n"
+ "and the memmap= parameter to reserve the bad areas.");
+#endif
pr_info(" %016llx bad mem addr %pa - %pa reserved\n",
cpu_to_be64(pattern), &start_bad, &end_bad);
memblock_reserve(start_bad, end_bad - start_bad);