Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'modules-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux

Pull modules updates from Luis Chamberlain:
"Summary of the changes worth highlighting from most interesting to
boring below:

- Christoph Hellwig's symbol_get() fix to Nvidia's efforts to
circumvent the protection he put in place in year 2020 to prevent
proprietary modules from using GPL only symbols, and also ensuring
proprietary modules which export symbols grandfather their taint.

That was done through year 2020 commit 262e6ae7081d ("modules:
inherit TAINT_PROPRIETARY_MODULE"). Christoph's new fix is done by
clarifing __symbol_get() was only ever intended to prevent module
reference loops by Linux kernel modules and so making it only find
symbols exported via EXPORT_SYMBOL_GPL(). The circumvention tactic
used by Nvidia was to use symbol_get() to purposely swift through
proprietary module symbols and completely bypass our traditional
EXPORT_SYMBOL*() annotations and community agreed upon
restrictions.

A small set of preamble patches fix up a few symbols which just
needed adjusting for this on two modules, the rtc ds1685 and the
networking enetc module. Two other modules just needed some build
fixing and removal of use of __symbol_get() as they can't ever be
modular, as was done by Arnd on the ARM pxa module and Christoph
did on the mmc au1xmmc driver.

This is a good reminder to us that symbol_get() is just a hack to
address things which should be fixed through Kconfig at build time
as was done in the later patches, and so ultimately it should just
go.

- Extremely late minor fix for old module layout 055f23b74b20
("module: check for exit sections in layout_sections() instead of
module_init_section()") by James Morse for arm64. Note that this
layout thing is old, it is *not* Song Liu's commit ac3b43283923
("module: replace module_layout with module_memory"). The issue
however is very odd to run into and so there was no hurry to get
this in fast.

- Although the fix did not go through the modules tree I'd like to
highlight the fix by Peter Zijlstra in commit 54097309620e
("x86/static_call: Fix __static_call_fixup()") now merged in your
tree which came out of what was originally suspected to be a
fallout of the the newer module layout changes by Song Liu commit
ac3b43283923 ("module: replace module_layout with module_memory")
instead of module_init_section()"). Thanks to the report by
Christian Bricart and the debugging by Song Liu & Peter that turned
to be noted as a kernel regression in place since v5.19 through
commit ee88d363d156 ("x86,static_call: Use alternative RET
encoding").

I highlight this to reflect and clarify that we haven't seen more
fallout from ac3b43283923 ("module: replace module_layout with
module_memory").

- RISC-V toolchain got mapping symbol support which prefix symbols
with "$" to help with alignment considerations for disassembly.

This is used to differentiate between incompatible instruction
encodings when disassembling. RISC-V just matches what ARM/AARCH64
did for alignment considerations and Palmer Dabbelt extended
is_mapping_symbol() to accept these symbols for RISC-V. We already
had support for this for all architectures but it also checked for
the second character, the RISC-V check Dabbelt added was just for
the "$". After a bit of testing and fallout on linux-next and based
on feedback from Masahiro Yamada it was decided to simplify the
check and treat the first char "$" as unique for all architectures,
and so we no make is_mapping_symbol() for all archs if the symbol
starts with "$".

The most relevant commit for this for RISC-V on binutils was:

https://sourceware.org/pipermail/binutils/2021-July/117350.html

- A late fix by Andrea Righi (today) to make module zstd
decompression use vmalloc() instead of kmalloc() to account for
large compressed modules. I suspect we'll see similar things for
other decompression algorithms soon.

- samples/hw_breakpoint minor fixes by Rong Tao, Arnd Bergmann and
Chen Jiahao"

* tag 'modules-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux:
module/decompress: use vmalloc() for zstd decompression workspace
kallsyms: Add more debug output for selftest
ARM: module: Use module_init_layout_section() to spot init sections
arm64: module: Use module_init_layout_section() to spot init sections
module: Expose module_init_layout_section()
modules: only allow symbol_get of EXPORT_SYMBOL_GPL modules
rtc: ds1685: use EXPORT_SYMBOL_GPL for ds1685_rtc_poweroff
net: enetc: use EXPORT_SYMBOL_GPL for enetc_phc_index
mmc: au1xmmc: force non-modular build and remove symbol_get usage
ARM: pxa: remove use of symbol_get()
samples/hw_breakpoint: mark sample_hbp as static
samples/hw_breakpoint: fix building without module unloading
samples/hw_breakpoint: Fix kernel BUG 'invalid opcode: 0000'
modpost, kallsyms: Treat add '$'-prefixed symbols as mapping symbols
kernel: params: Remove unnecessary ‘0’ values from err
module: Ignore RISC-V mapping symbols too

+55 -70
+1 -1
arch/arm/kernel/module-plts.c
··· 251 251 /* sort by type and symbol index */ 252 252 sort(rels, numrels, sizeof(Elf32_Rel), cmp_rel, NULL); 253 253 254 - if (strncmp(secstrings + dstsec->sh_name, ".init", 5) != 0) 254 + if (!module_init_layout_section(secstrings + dstsec->sh_name)) 255 255 core_plts += count_plts(syms, dstsec->sh_addr, rels, 256 256 numrels, s->sh_info); 257 257 else
-2
arch/arm/mach-pxa/sharpsl_pm.c
··· 216 216 { 217 217 schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125)); 218 218 } 219 - EXPORT_SYMBOL(sharpsl_battery_kick); 220 - 221 219 222 220 static void sharpsl_battery_thread(struct work_struct *private_) 223 221 {
+1 -13
arch/arm/mach-pxa/spitz.c
··· 9 9 */ 10 10 11 11 #include <linux/kernel.h> 12 - #include <linux/module.h> /* symbol_get ; symbol_put */ 13 12 #include <linux/platform_device.h> 14 13 #include <linux/delay.h> 15 14 #include <linux/gpio_keys.h> ··· 517 518 }, 518 519 }; 519 520 520 - static void spitz_bl_kick_battery(void) 521 - { 522 - void (*kick_batt)(void); 523 - 524 - kick_batt = symbol_get(sharpsl_battery_kick); 525 - if (kick_batt) { 526 - kick_batt(); 527 - symbol_put(sharpsl_battery_kick); 528 - } 529 - } 530 - 531 521 static struct gpiod_lookup_table spitz_lcdcon_gpio_table = { 532 522 .dev_id = "spi2.1", 533 523 .table = { ··· 544 556 .max_intensity = 0x2f, 545 557 .default_intensity = 0x1f, 546 558 .limit_mask = 0x0b, 547 - .kick_battery = spitz_bl_kick_battery, 559 + .kick_battery = sharpsl_battery_kick, 548 560 }; 549 561 550 562 static struct spi_board_info spitz_spi_devices[] = {
+1 -1
arch/arm64/kernel/module-plts.c
··· 339 339 if (nents) 340 340 sort(rels, nents, sizeof(Elf64_Rela), cmp_rela, NULL); 341 341 342 - if (!str_has_prefix(secstrings + dstsec->sh_name, ".init")) 342 + if (!module_init_layout_section(secstrings + dstsec->sh_name)) 343 343 core_plts += count_plts(syms, rels, numrels, 344 344 sechdrs[i].sh_info, dstsec); 345 345 else
+1 -7
arch/mips/alchemy/devboards/db1000.c
··· 14 14 #include <linux/interrupt.h> 15 15 #include <linux/leds.h> 16 16 #include <linux/mmc/host.h> 17 - #include <linux/module.h> 18 17 #include <linux/platform_device.h> 19 18 #include <linux/pm.h> 20 19 #include <linux/spi/spi.h> ··· 166 167 167 168 static irqreturn_t db1100_mmc_cd(int irq, void *ptr) 168 169 { 169 - void (*mmc_cd)(struct mmc_host *, unsigned long); 170 - /* link against CONFIG_MMC=m */ 171 - mmc_cd = symbol_get(mmc_detect_change); 172 - mmc_cd(ptr, msecs_to_jiffies(500)); 173 - symbol_put(mmc_detect_change); 174 - 170 + mmc_detect_change(ptr, msecs_to_jiffies(500)); 175 171 return IRQ_HANDLED; 176 172 } 177 173
+2 -17
arch/mips/alchemy/devboards/db1200.c
··· 10 10 #include <linux/gpio.h> 11 11 #include <linux/i2c.h> 12 12 #include <linux/init.h> 13 - #include <linux/module.h> 14 13 #include <linux/interrupt.h> 15 14 #include <linux/io.h> 16 15 #include <linux/leds.h> ··· 339 340 340 341 static irqreturn_t db1200_mmc_cdfn(int irq, void *ptr) 341 342 { 342 - void (*mmc_cd)(struct mmc_host *, unsigned long); 343 - 344 - /* link against CONFIG_MMC=m */ 345 - mmc_cd = symbol_get(mmc_detect_change); 346 - if (mmc_cd) { 347 - mmc_cd(ptr, msecs_to_jiffies(200)); 348 - symbol_put(mmc_detect_change); 349 - } 343 + mmc_detect_change(ptr, msecs_to_jiffies(200)); 350 344 351 345 msleep(100); /* debounce */ 352 346 if (irq == DB1200_SD0_INSERT_INT) ··· 423 431 424 432 static irqreturn_t pb1200_mmc1_cdfn(int irq, void *ptr) 425 433 { 426 - void (*mmc_cd)(struct mmc_host *, unsigned long); 427 - 428 - /* link against CONFIG_MMC=m */ 429 - mmc_cd = symbol_get(mmc_detect_change); 430 - if (mmc_cd) { 431 - mmc_cd(ptr, msecs_to_jiffies(200)); 432 - symbol_put(mmc_detect_change); 433 - } 434 + mmc_detect_change(ptr, msecs_to_jiffies(200)); 434 435 435 436 msleep(100); /* debounce */ 436 437 if (irq == PB1200_SD1_INSERT_INT)
+1 -9
arch/mips/alchemy/devboards/db1300.c
··· 17 17 #include <linux/interrupt.h> 18 18 #include <linux/ata_platform.h> 19 19 #include <linux/mmc/host.h> 20 - #include <linux/module.h> 21 20 #include <linux/mtd/mtd.h> 22 21 #include <linux/mtd/platnand.h> 23 22 #include <linux/platform_device.h> ··· 458 459 459 460 static irqreturn_t db1300_mmc_cdfn(int irq, void *ptr) 460 461 { 461 - void (*mmc_cd)(struct mmc_host *, unsigned long); 462 - 463 - /* link against CONFIG_MMC=m. We can only be called once MMC core has 464 - * initialized the controller, so symbol_get() should always succeed. 465 - */ 466 - mmc_cd = symbol_get(mmc_detect_change); 467 - mmc_cd(ptr, msecs_to_jiffies(200)); 468 - symbol_put(mmc_detect_change); 462 + mmc_detect_change(ptr, msecs_to_jiffies(200)); 469 463 470 464 msleep(100); /* debounce */ 471 465 if (irq == DB1300_SD1_INSERT_INT)
+3 -2
drivers/mmc/host/Kconfig
··· 526 526 of Alcor Micro PCI-E card reader 527 527 528 528 config MMC_AU1X 529 - tristate "Alchemy AU1XX0 MMC Card Interface support" 529 + bool "Alchemy AU1XX0 MMC Card Interface support" 530 530 depends on MIPS_ALCHEMY 531 + depends on MMC=y 531 532 help 532 533 This selects the AMD Alchemy(R) Multimedia card interface. 533 - If you have a Alchemy platform with a MMC slot, say Y or M here. 534 + If you have a Alchemy platform with a MMC slot, say Y here. 534 535 535 536 If unsure, say N. 536 537
+1 -1
drivers/net/ethernet/freescale/enetc/enetc_ptp.c
··· 8 8 #include "enetc.h" 9 9 10 10 int enetc_phc_index = -1; 11 - EXPORT_SYMBOL(enetc_phc_index); 11 + EXPORT_SYMBOL_GPL(enetc_phc_index); 12 12 13 13 static struct ptp_clock_info enetc_ptp_caps = { 14 14 .owner = THIS_MODULE,
+1 -1
drivers/rtc/rtc-ds1685.c
··· 1432 1432 unreachable(); 1433 1433 } 1434 1434 } 1435 - EXPORT_SYMBOL(ds1685_rtc_poweroff); 1435 + EXPORT_SYMBOL_GPL(ds1685_rtc_poweroff); 1436 1436 /* ----------------------------------------------------------------------- */ 1437 1437 1438 1438
+1 -3
include/linux/module_symbol.h
··· 9 9 return true; 10 10 if (str[0] == 'L' && str[1] == '0') 11 11 return true; 12 - return str[0] == '$' && 13 - (str[1] == 'a' || str[1] == 'd' || str[1] == 't' || str[1] == 'x') 14 - && (str[2] == '\0' || str[2] == '.'); 12 + return str[0] == '$'; 15 13 } 16 14 17 15 #endif /* _LINUX_MODULE_SYMBOL_H */
+5
include/linux/moduleloader.h
··· 42 42 */ 43 43 bool module_exit_section(const char *name); 44 44 45 + /* Describes whether within_module_init() will consider this an init section 46 + * or not. This behaviour changes with CONFIG_MODULE_UNLOAD. 47 + */ 48 + bool module_init_layout_section(const char *sname); 49 + 45 50 /* 46 51 * Apply the given relocation to the (simplified) ELF. Return -error 47 52 * or 0.
+18 -4
kernel/kallsyms_selftest.c
··· 341 341 ret = lookup_symbol_name(addr, namebuf); 342 342 if (unlikely(ret)) { 343 343 namebuf[0] = 0; 344 + pr_info("%d: lookup_symbol_name(%lx) failed\n", i, addr); 344 345 goto failed; 345 346 } 346 347 ··· 368 367 if (stat->addr != stat2->addr || 369 368 stat->real_cnt != stat2->real_cnt || 370 369 memcmp(stat->addrs, stat2->addrs, 371 - stat->save_cnt * sizeof(stat->addrs[0]))) 370 + stat->save_cnt * sizeof(stat->addrs[0]))) { 371 + pr_info("%s: mismatch between kallsyms_on_each_symbol() and kallsyms_on_each_match_symbol()\n", 372 + namebuf); 372 373 goto failed; 374 + } 373 375 374 376 /* 375 377 * The average of random increments is 128, that is, one of ··· 383 379 } 384 380 385 381 /* Need to be found at least once */ 386 - if (!stat->real_cnt) 382 + if (!stat->real_cnt) { 383 + pr_info("%s: Never found\n", namebuf); 387 384 goto failed; 385 + } 388 386 389 387 /* 390 388 * kallsyms_lookup_name() returns the address of the first 391 389 * symbol found and cannot be NULL. 392 390 */ 393 - if (!lookup_addr || lookup_addr != stat->addrs[0]) 391 + if (!lookup_addr) { 392 + pr_info("%s: NULL lookup_addr?!\n", namebuf); 394 393 goto failed; 394 + } 395 + if (lookup_addr != stat->addrs[0]) { 396 + pr_info("%s: lookup_addr != stat->addrs[0]\n", namebuf); 397 + goto failed; 398 + } 395 399 396 400 /* 397 401 * If the addresses of all matching symbols are recorded, the ··· 411 399 break; 412 400 } 413 401 414 - if (j == stat->save_cnt) 402 + if (j == stat->save_cnt) { 403 + pr_info("%s: j == save_cnt?!\n", namebuf); 415 404 goto failed; 405 + } 416 406 } 417 407 } 418 408
+2 -2
kernel/module/decompress.c
··· 241 241 } 242 242 243 243 wksp_size = zstd_dstream_workspace_bound(header.windowSize); 244 - wksp = kmalloc(wksp_size, GFP_KERNEL); 244 + wksp = vmalloc(wksp_size); 245 245 if (!wksp) { 246 246 retval = -ENOMEM; 247 247 goto out; ··· 284 284 retval = new_size; 285 285 286 286 out: 287 - kfree(wksp); 287 + vfree(wksp); 288 288 return retval; 289 289 } 290 290 #else
+12 -4
kernel/module/main.c
··· 1295 1295 }; 1296 1296 1297 1297 preempt_disable(); 1298 - if (!find_symbol(&fsa) || strong_try_module_get(fsa.owner)) { 1299 - preempt_enable(); 1300 - return NULL; 1298 + if (!find_symbol(&fsa)) 1299 + goto fail; 1300 + if (fsa.license != GPL_ONLY) { 1301 + pr_warn("failing symbol_get of non-GPLONLY symbol %s.\n", 1302 + symbol); 1303 + goto fail; 1301 1304 } 1305 + if (strong_try_module_get(fsa.owner)) 1306 + goto fail; 1302 1307 preempt_enable(); 1303 1308 return (void *)kernel_symbol_value(fsa.sym); 1309 + fail: 1310 + preempt_enable(); 1311 + return NULL; 1304 1312 } 1305 1313 EXPORT_SYMBOL_GPL(__symbol_get); 1306 1314 ··· 1492 1484 return offset | mask; 1493 1485 } 1494 1486 1495 - static bool module_init_layout_section(const char *sname) 1487 + bool module_init_layout_section(const char *sname) 1496 1488 { 1497 1489 #ifndef CONFIG_MODULE_UNLOAD 1498 1490 if (module_exit_section(sname))
+1 -1
kernel/params.c
··· 331 331 332 332 int param_set_bool_enable_only(const char *val, const struct kernel_param *kp) 333 333 { 334 - int err = 0; 334 + int err; 335 335 bool new_value; 336 336 bool orig_value = *(bool *)kp->arg; 337 337 struct kernel_param dummy_kp = *kp;
+4 -2
samples/hw_breakpoint/data_breakpoint.c
··· 21 21 #include <linux/perf_event.h> 22 22 #include <linux/hw_breakpoint.h> 23 23 24 - struct perf_event * __percpu *sample_hbp; 24 + static struct perf_event * __percpu *sample_hbp; 25 25 26 26 static char ksym_name[KSYM_NAME_LEN] = "jiffies"; 27 27 module_param_string(ksym, ksym_name, KSYM_NAME_LEN, S_IRUGO); ··· 70 70 static void __exit hw_break_module_exit(void) 71 71 { 72 72 unregister_wide_hw_breakpoint(sample_hbp); 73 - symbol_put(ksym_name); 73 + #ifdef CONFIG_MODULE_UNLOAD 74 + __symbol_put(ksym_name); 75 + #endif 74 76 printk(KERN_INFO "HW Breakpoint for %s write uninstalled\n", ksym_name); 75 77 } 76 78