summaryrefslogtreecommitdiffstats
path: root/scripts/mod/devicetable-offsets.c
diff options
context:
space:
mode:
authorXie Yuanbin <xieyuanbin1@huawei.com>2026-07-28 03:16:42 +0100
committerRussell King <rmk+kernel@armlinux.org.uk>2026-08-05 16:15:51 +0100
commit1039bffd6ae9c75b42b7d148d6c1106134107b66 (patch)
treee8ee4ac80f87e2ad1b6b0c877eccbb62b0915c02 /scripts/mod/devicetable-offsets.c
downloadlinux-stable-1039bffd6ae9c75b42b7d148d6c1106134107b66.tar.gz
linux-stable-1039bffd6ae9c75b42b7d148d6c1106134107b66.zip
ARM: 9485/1: mm: acquire mmap write lock around show_pte() for user faultsgrafted
When CONFIG_DEBUG_USER=y, and cmdline "user_debug=31" is set, a user fault may trigger show_pte() without any lock. If another thread in the same process concurrently calls munmap(), the page table pages may be freed while show_pte() is still traversing them, causing a use-after-free in show_pte(). If CONFIG_ARM_LPAE=y, this may cause a kernel panic if the pages table of PMD are freed when show_pte() is running. Acquire mmap_write_lock() around show_pte() for user faults to fix the contention. For user faults, additionally restrict that show_pte() is called only when the addr is a user-space address (addr < TASK_SIZE). This is because the lock of tsk->mm only protects the virtual memory of user address space, furthermore, dumping the page tables of a kernel-space address for user faults is unnecessary and may have security implications. Keep everything unchanged for kernel faults, because the kernel is already in the "oops" state, acquiring a lock may risk a deadlock. Co-developed-by: Qi Xi <xiqi2@huawei.com> Fixes: 6d021b724481 ("ARM: dump pgd, pmd and pte states on unhandled data abort faults") Link: https://lore.kernel.org/20260716014022.2823-1-xieyuanbin1@huawei.com Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Reviewed-by: Linus Walleij <linusw@kernel.org> Signed-off-by: Qi Xi <xiqi2@huawei.com> Signed-off-by: Xie Yuanbin <xieyuanbin1@huawei.com> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'scripts/mod/devicetable-offsets.c')
-rw-r--r--scripts/mod/devicetable-offsets.c288
1 files changed, 288 insertions, 0 deletions
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
new file mode 100644
index 000000000..b4178c42d
--- /dev/null
+++ b/scripts/mod/devicetable-offsets.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0
+#define COMPILE_OFFSETS
+#include <linux/kbuild.h>
+#include <linux/mod_devicetable.h>
+
+#define DEVID(devid) DEFINE(SIZE_##devid, sizeof(struct devid))
+#define DEVID_FIELD(devid, field) \
+ DEFINE(OFF_##devid##_##field, offsetof(struct devid, field))
+
+int main(void)
+{
+ DEVID(usb_device_id);
+ DEVID_FIELD(usb_device_id, match_flags);
+ DEVID_FIELD(usb_device_id, idVendor);
+ DEVID_FIELD(usb_device_id, idProduct);
+ DEVID_FIELD(usb_device_id, bcdDevice_lo);
+ DEVID_FIELD(usb_device_id, bcdDevice_hi);
+ DEVID_FIELD(usb_device_id, bDeviceClass);
+ DEVID_FIELD(usb_device_id, bDeviceSubClass);
+ DEVID_FIELD(usb_device_id, bDeviceProtocol);
+ DEVID_FIELD(usb_device_id, bInterfaceClass);
+ DEVID_FIELD(usb_device_id, bInterfaceSubClass);
+ DEVID_FIELD(usb_device_id, bInterfaceProtocol);
+ DEVID_FIELD(usb_device_id, bInterfaceNumber);
+
+ DEVID(hid_device_id);
+ DEVID_FIELD(hid_device_id, bus);
+ DEVID_FIELD(hid_device_id, group);
+ DEVID_FIELD(hid_device_id, vendor);
+ DEVID_FIELD(hid_device_id, product);
+
+ DEVID(ieee1394_device_id);
+ DEVID_FIELD(ieee1394_device_id, match_flags);
+ DEVID_FIELD(ieee1394_device_id, vendor_id);
+ DEVID_FIELD(ieee1394_device_id, model_id);
+ DEVID_FIELD(ieee1394_device_id, specifier_id);
+ DEVID_FIELD(ieee1394_device_id, version);
+
+ DEVID(pci_device_id);
+ DEVID_FIELD(pci_device_id, vendor);
+ DEVID_FIELD(pci_device_id, device);
+ DEVID_FIELD(pci_device_id, subvendor);
+ DEVID_FIELD(pci_device_id, subdevice);
+ DEVID_FIELD(pci_device_id, class);
+ DEVID_FIELD(pci_device_id, class_mask);
+ DEVID_FIELD(pci_device_id, override_only);
+
+ DEVID(ccw_device_id);
+ DEVID_FIELD(ccw_device_id, match_flags);
+ DEVID_FIELD(ccw_device_id, cu_type);
+ DEVID_FIELD(ccw_device_id, cu_model);
+ DEVID_FIELD(ccw_device_id, dev_type);
+ DEVID_FIELD(ccw_device_id, dev_model);
+
+ DEVID(ap_device_id);
+ DEVID_FIELD(ap_device_id, dev_type);
+
+ DEVID(css_device_id);
+ DEVID_FIELD(css_device_id, type);
+
+ DEVID(serio_device_id);
+ DEVID_FIELD(serio_device_id, type);
+ DEVID_FIELD(serio_device_id, proto);
+ DEVID_FIELD(serio_device_id, id);
+ DEVID_FIELD(serio_device_id, extra);
+
+ DEVID(acpi_device_id);
+ DEVID_FIELD(acpi_device_id, id);
+ DEVID_FIELD(acpi_device_id, cls);
+ DEVID_FIELD(acpi_device_id, cls_msk);
+
+ DEVID(pnp_device_id);
+ DEVID_FIELD(pnp_device_id, id);
+
+ DEVID(pnp_card_device_id);
+ DEVID_FIELD(pnp_card_device_id, devs);
+
+ DEVID(pcmcia_device_id);
+ DEVID_FIELD(pcmcia_device_id, match_flags);
+ DEVID_FIELD(pcmcia_device_id, manf_id);
+ DEVID_FIELD(pcmcia_device_id, card_id);
+ DEVID_FIELD(pcmcia_device_id, func_id);
+ DEVID_FIELD(pcmcia_device_id, function);
+ DEVID_FIELD(pcmcia_device_id, device_no);
+ DEVID_FIELD(pcmcia_device_id, prod_id_hash);
+
+ DEVID(of_device_id);
+ DEVID_FIELD(of_device_id, name);
+ DEVID_FIELD(of_device_id, type);
+ DEVID_FIELD(of_device_id, compatible);
+
+ DEVID(vio_device_id);
+ DEVID_FIELD(vio_device_id, type);
+ DEVID_FIELD(vio_device_id, compat);
+
+ DEVID(input_device_id);
+ DEVID_FIELD(input_device_id, flags);
+ DEVID_FIELD(input_device_id, bustype);
+ DEVID_FIELD(input_device_id, vendor);
+ DEVID_FIELD(input_device_id, product);
+ DEVID_FIELD(input_device_id, version);
+ DEVID_FIELD(input_device_id, evbit);
+ DEVID_FIELD(input_device_id, keybit);
+ DEVID_FIELD(input_device_id, relbit);
+ DEVID_FIELD(input_device_id, absbit);
+ DEVID_FIELD(input_device_id, mscbit);
+ DEVID_FIELD(input_device_id, ledbit);
+ DEVID_FIELD(input_device_id, sndbit);
+ DEVID_FIELD(input_device_id, ffbit);
+ DEVID_FIELD(input_device_id, swbit);
+
+ DEVID(eisa_device_id);
+ DEVID_FIELD(eisa_device_id, sig);
+
+ DEVID(parisc_device_id);
+ DEVID_FIELD(parisc_device_id, hw_type);
+ DEVID_FIELD(parisc_device_id, hversion);
+ DEVID_FIELD(parisc_device_id, hversion_rev);
+ DEVID_FIELD(parisc_device_id, sversion);
+
+ DEVID(sdio_device_id);
+ DEVID_FIELD(sdio_device_id, class);
+ DEVID_FIELD(sdio_device_id, vendor);
+ DEVID_FIELD(sdio_device_id, device);
+
+ DEVID(ssb_device_id);
+ DEVID_FIELD(ssb_device_id, vendor);
+ DEVID_FIELD(ssb_device_id, coreid);
+ DEVID_FIELD(ssb_device_id, revision);
+
+ DEVID(bcma_device_id);
+ DEVID_FIELD(bcma_device_id, manuf);
+ DEVID_FIELD(bcma_device_id, id);
+ DEVID_FIELD(bcma_device_id, rev);
+ DEVID_FIELD(bcma_device_id, class);
+
+ DEVID(virtio_device_id);
+ DEVID_FIELD(virtio_device_id, device);
+ DEVID_FIELD(virtio_device_id, vendor);
+
+ DEVID(hv_vmbus_device_id);
+ DEVID_FIELD(hv_vmbus_device_id, guid);
+
+ DEVID(rpmsg_device_id);
+ DEVID_FIELD(rpmsg_device_id, name);
+
+ DEVID(i2c_device_id);
+ DEVID_FIELD(i2c_device_id, name);
+
+ DEVID(i3c_device_id);
+ DEVID_FIELD(i3c_device_id, match_flags);
+ DEVID_FIELD(i3c_device_id, dcr);
+ DEVID_FIELD(i3c_device_id, manuf_id);
+ DEVID_FIELD(i3c_device_id, part_id);
+ DEVID_FIELD(i3c_device_id, extra_info);
+
+ DEVID(slim_device_id);
+ DEVID_FIELD(slim_device_id, manf_id);
+ DEVID_FIELD(slim_device_id, prod_code);
+
+ DEVID(spi_device_id);
+ DEVID_FIELD(spi_device_id, name);
+
+ DEVID(dmi_system_id);
+ DEVID_FIELD(dmi_system_id, matches);
+
+ DEVID(platform_device_id);
+ DEVID_FIELD(platform_device_id, name);
+
+ DEVID(mdio_device_id);
+ DEVID_FIELD(mdio_device_id, phy_id);
+ DEVID_FIELD(mdio_device_id, phy_id_mask);
+
+ DEVID(zorro_device_id);
+ DEVID_FIELD(zorro_device_id, id);
+
+ DEVID(isapnp_device_id);
+ DEVID_FIELD(isapnp_device_id, vendor);
+ DEVID_FIELD(isapnp_device_id, function);
+
+ DEVID(ipack_device_id);
+ DEVID_FIELD(ipack_device_id, format);
+ DEVID_FIELD(ipack_device_id, vendor);
+ DEVID_FIELD(ipack_device_id, device);
+
+ DEVID(amba_id);
+ DEVID_FIELD(amba_id, id);
+ DEVID_FIELD(amba_id, mask);
+
+ DEVID(mips_cdmm_device_id);
+ DEVID_FIELD(mips_cdmm_device_id, type);
+
+ DEVID(x86_cpu_id);
+ DEVID_FIELD(x86_cpu_id, feature);
+ DEVID_FIELD(x86_cpu_id, family);
+ DEVID_FIELD(x86_cpu_id, model);
+ DEVID_FIELD(x86_cpu_id, vendor);
+
+ DEVID(cpu_feature);
+ DEVID_FIELD(cpu_feature, feature);
+
+ DEVID(mcb_device_id);
+ DEVID_FIELD(mcb_device_id, device);
+
+ DEVID(mei_cl_device_id);
+ DEVID_FIELD(mei_cl_device_id, name);
+ DEVID_FIELD(mei_cl_device_id, uuid);
+ DEVID_FIELD(mei_cl_device_id, version);
+
+ DEVID(rio_device_id);
+ DEVID_FIELD(rio_device_id, did);
+ DEVID_FIELD(rio_device_id, vid);
+ DEVID_FIELD(rio_device_id, asm_did);
+ DEVID_FIELD(rio_device_id, asm_vid);
+
+ DEVID(ulpi_device_id);
+ DEVID_FIELD(ulpi_device_id, vendor);
+ DEVID_FIELD(ulpi_device_id, product);
+
+ DEVID(hda_device_id);
+ DEVID_FIELD(hda_device_id, vendor_id);
+ DEVID_FIELD(hda_device_id, rev_id);
+ DEVID_FIELD(hda_device_id, api_version);
+
+ DEVID(sdw_device_id);
+ DEVID_FIELD(sdw_device_id, mfg_id);
+ DEVID_FIELD(sdw_device_id, part_id);
+ DEVID_FIELD(sdw_device_id, sdw_version);
+ DEVID_FIELD(sdw_device_id, class_id);
+
+ DEVID(fsl_mc_device_id);
+ DEVID_FIELD(fsl_mc_device_id, vendor);
+ DEVID_FIELD(fsl_mc_device_id, obj_type);
+
+ DEVID(tb_service_id);
+ DEVID_FIELD(tb_service_id, match_flags);
+ DEVID_FIELD(tb_service_id, protocol_key);
+ DEVID_FIELD(tb_service_id, protocol_id);
+ DEVID_FIELD(tb_service_id, protocol_version);
+ DEVID_FIELD(tb_service_id, protocol_revision);
+
+ DEVID(typec_device_id);
+ DEVID_FIELD(typec_device_id, svid);
+
+ DEVID(tee_client_device_id);
+ DEVID_FIELD(tee_client_device_id, uuid);
+
+ DEVID(wmi_device_id);
+ DEVID_FIELD(wmi_device_id, guid_string);
+
+ DEVID(mhi_device_id);
+ DEVID_FIELD(mhi_device_id, chan);
+
+ DEVID(auxiliary_device_id);
+ DEVID_FIELD(auxiliary_device_id, name);
+
+ DEVID(ssam_device_id);
+ DEVID_FIELD(ssam_device_id, match_flags);
+ DEVID_FIELD(ssam_device_id, domain);
+ DEVID_FIELD(ssam_device_id, category);
+ DEVID_FIELD(ssam_device_id, target);
+ DEVID_FIELD(ssam_device_id, instance);
+ DEVID_FIELD(ssam_device_id, function);
+
+ DEVID(dfl_device_id);
+ DEVID_FIELD(dfl_device_id, type);
+ DEVID_FIELD(dfl_device_id, feature_id);
+
+ DEVID(ishtp_device_id);
+ DEVID_FIELD(ishtp_device_id, guid);
+
+ DEVID(cdx_device_id);
+ DEVID_FIELD(cdx_device_id, vendor);
+ DEVID_FIELD(cdx_device_id, device);
+ DEVID_FIELD(cdx_device_id, subvendor);
+ DEVID_FIELD(cdx_device_id, subdevice);
+ DEVID_FIELD(cdx_device_id, class);
+ DEVID_FIELD(cdx_device_id, class_mask);
+ DEVID_FIELD(cdx_device_id, override_only);
+
+ DEVID(vchiq_device_id);
+ DEVID_FIELD(vchiq_device_id, name);
+
+ DEVID(coreboot_device_id);
+ DEVID_FIELD(coreboot_device_id, tag);
+
+ return 0;
+}