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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull module updates from Sami Tolvanen:
"Kernel symbol flags:

- Replace the separate *_gpl symbol sections (__ksymtab_gpl and
__kcrctab_gpl) with a unified symbol table and a new __kflagstab
section.

This section stores symbol flags, such as the GPL-only flag, as an
8-bit bitset for each exported symbol. This is a cleanup that
simplifies symbol lookup in the module loader by avoiding table
fragmentation and will allow a cleaner way to add more flags later
if needed.

Module signature UAPI:

- Move struct module_signature to the UAPI headers to allow reuse by
tools outside the kernel proper, such as kmod and
scripts/sign-file.

This also renames a few constants for clarity and drops unused
signature types as preparation for hash-based module integrity
checking work that's in progress.

Sysfs:

- Add a /sys/module/<module>/import_ns sysfs attribute to show the
symbol namespaces imported by loaded modules.

This makes it easier to verify driver API access at runtime on
systems that care about such things (e.g. Android).

Cleanups and fixes:

- Force sh_addr to 0 for all sections in module.lds. This prevents
non-zero section addresses when linking modules with 'ld.bfd -r',
which confused elfutils.

- Fix a memory leak of charp module parameters on module unload when
the kernel is configured with CONFIG_SYSFS=n.

- Override the -EEXIST error code returned by module_init() to
userspace. This prevents confusion with the errno reserved by the
module loader to indicate that a module is already loaded.

- Simplify the warning message and drop the stack dump on positive
returns from module_init().

- Drop unnecessary extern keywords from function declarations and
synchronize parse_args() arguments with their implementation"

* tag 'modules-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux: (23 commits)
module: Simplify warning on positive returns from module_init()
module: Override -EEXIST module return
documentation: remove references to *_gpl sections
module: remove *_gpl sections from vmlinux and modules
module: deprecate usage of *_gpl sections in module loader
module: use kflagstab instead of *_gpl sections
module: populate kflagstab in modpost
module: add kflagstab section to vmlinux and modules
module: define ksym_flags enumeration to represent kernel symbol flags
selftests/bpf: verify_pkcs7_sig: Use 'struct module_signature' from the UAPI headers
sign-file: use 'struct module_signature' from the UAPI headers
tools uapi headers: add linux/module_signature.h
module: Move 'struct module_signature' to UAPI
module: Give MODULE_SIG_STRING a more descriptive name
module: Give 'enum pkey_id_type' a more specific name
module: Drop unused signature types
extract-cert: drop unused definition of PKEY_ID_PKCS7
docs: symbol-namespaces: mention sysfs attribute
module: expose imported namespaces via sysfs
module: Remove extern keyword from param prototypes
...

+368 -255
+9
Documentation/ABI/testing/sysfs-module
··· 48 48 Description: Show the initialization state(live, coming, going) of 49 49 the module. 50 50 51 + What: /sys/module/*/import_ns 52 + Date: January 2026 53 + KernelVersion: 7.1 54 + Contact: linux-modules@vger.kernel.org 55 + Description: List of symbol namespaces imported by this module via 56 + MODULE_IMPORT_NS(). Each namespace appears on a separate line. 57 + This file only exists for modules that import at least one 58 + namespace. 59 + 51 60 What: /sys/module/*/taint 52 61 Date: Jan 2012 53 62 KernelVersion: 3.3
+5
Documentation/core-api/symbol-namespaces.rst
··· 114 114 import_ns: USB_STORAGE 115 115 [...] 116 116 117 + For modules that are currently loaded, imported namespaces are also available 118 + via sysfs:: 119 + 120 + $ cat /sys/module/ums_karma/import_ns 121 + USB_STORAGE 117 122 118 123 It is advisable to add the MODULE_IMPORT_NS() statement close to other module 119 124 metadata definitions like MODULE_AUTHOR() or MODULE_LICENSE().
+6 -5
Documentation/kbuild/modules.rst
··· 426 426 Version Information Formats 427 427 --------------------------- 428 428 429 - Exported symbols have information stored in __ksymtab or __ksymtab_gpl 430 - sections. Symbol names and namespaces are stored in __ksymtab_strings, 431 - using a format similar to the string table used for ELF. If 432 - CONFIG_MODVERSIONS is enabled, the CRCs corresponding to exported 433 - symbols will be added to the __kcrctab or __kcrctab_gpl. 429 + Exported symbols have information stored in the __ksymtab and 430 + __kflagstab sections. Symbol names and namespaces are stored in 431 + __ksymtab_strings section, using a format similar to the string 432 + table used for ELF. If CONFIG_MODVERSIONS is enabled, the CRCs 433 + corresponding to exported symbols will be added to the 434 + __kcrctab section. 434 435 435 436 If CONFIG_BASIC_MODVERSIONS is enabled (default with 436 437 CONFIG_MODVERSIONS), imported symbols will have their symbol name and
+3 -3
arch/s390/kernel/machine_kexec_file.c
··· 28 28 #ifdef CONFIG_KEXEC_SIG 29 29 int s390_verify_sig(const char *kernel, unsigned long kernel_len) 30 30 { 31 - const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; 31 + const unsigned long marker_len = sizeof(MODULE_SIGNATURE_MARKER) - 1; 32 32 struct module_signature *ms; 33 33 unsigned long sig_len; 34 34 int ret; ··· 40 40 if (marker_len > kernel_len) 41 41 return -EKEYREJECTED; 42 42 43 - if (memcmp(kernel + kernel_len - marker_len, MODULE_SIG_STRING, 43 + if (memcmp(kernel + kernel_len - marker_len, MODULE_SIGNATURE_MARKER, 44 44 marker_len)) 45 45 return -EKEYREJECTED; 46 46 kernel_len -= marker_len; ··· 53 53 return -EKEYREJECTED; 54 54 kernel_len -= sig_len; 55 55 56 - if (ms->id_type != PKEY_ID_PKCS7) 56 + if (ms->id_type != MODULE_SIGNATURE_TYPE_PKCS7) 57 57 return -EKEYREJECTED; 58 58 59 59 if (ms->algo != 0 ||
-2
certs/extract-cert.c
··· 33 33 #endif 34 34 #include "ssl-common.h" 35 35 36 - #define PKEY_ID_PKCS7 2 37 - 38 36 static __attribute__((noreturn)) 39 37 void format(void) 40 38 {
+1 -1
include/asm-generic/codetag.lds.h
··· 18 18 IF_MEM_ALLOC_PROFILING(SECTION_WITH_BOUNDARIES(alloc_tags)) 19 19 20 20 #define MOD_SEPARATE_CODETAG_SECTION(_name) \ 21 - .codetag.##_name : { \ 21 + .codetag.##_name 0 : { \ 22 22 SECTION_WITH_BOUNDARIES(_name) \ 23 23 } 24 24
+7 -14
include/asm-generic/vmlinux.lds.h
··· 508 508 \ 509 509 PRINTK_INDEX \ 510 510 \ 511 - /* Kernel symbol table: Normal symbols */ \ 511 + /* Kernel symbol table */ \ 512 512 __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ 513 513 __start___ksymtab = .; \ 514 514 KEEP(*(SORT(___ksymtab+*))) \ 515 515 __stop___ksymtab = .; \ 516 516 } \ 517 517 \ 518 - /* Kernel symbol table: GPL-only symbols */ \ 519 - __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ 520 - __start___ksymtab_gpl = .; \ 521 - KEEP(*(SORT(___ksymtab_gpl+*))) \ 522 - __stop___ksymtab_gpl = .; \ 523 - } \ 524 - \ 525 - /* Kernel symbol table: Normal symbols */ \ 518 + /* Kernel symbol CRC table */ \ 526 519 __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ 527 520 __start___kcrctab = .; \ 528 521 KEEP(*(SORT(___kcrctab+*))) \ 529 522 __stop___kcrctab = .; \ 530 523 } \ 531 524 \ 532 - /* Kernel symbol table: GPL-only symbols */ \ 533 - __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ 534 - __start___kcrctab_gpl = .; \ 535 - KEEP(*(SORT(___kcrctab_gpl+*))) \ 536 - __stop___kcrctab_gpl = .; \ 525 + /* Kernel symbol flags table */ \ 526 + __kflagstab : AT(ADDR(__kflagstab) - LOAD_OFFSET) { \ 527 + __start___kflagstab = .; \ 528 + KEEP(*(SORT(___kflagstab+*))) \ 529 + __stop___kflagstab = .; \ 537 530 } \ 538 531 \ 539 532 /* Kernel symbol table: strings */ \
+18 -10
include/linux/export-internal.h
··· 37 37 * section flag requires it. Use '%progbits' instead of '@progbits' since the 38 38 * former apparently works on all arches according to the binutils source. 39 39 */ 40 - #define __KSYMTAB(name, sym, sec, ns) \ 40 + #define __KSYMTAB(name, sym, ns) \ 41 41 asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1" "\n" \ 42 42 "__kstrtab_" #name ":" "\n" \ 43 43 " .asciz \"" #name "\"" "\n" \ 44 44 "__kstrtabns_" #name ":" "\n" \ 45 45 " .asciz \"" ns "\"" "\n" \ 46 46 " .previous" "\n" \ 47 - " .section \"___ksymtab" sec "+" #name "\", \"a\"" "\n" \ 47 + " .section \"___ksymtab+" #name "\", \"a\"" "\n" \ 48 48 __KSYM_ALIGN "\n" \ 49 49 "__ksymtab_" #name ":" "\n" \ 50 50 __KSYM_REF(sym) "\n" \ ··· 59 59 #define KSYM_FUNC(name) name 60 60 #endif 61 61 62 - #define KSYMTAB_FUNC(name, sec, ns) __KSYMTAB(name, KSYM_FUNC(name), sec, ns) 63 - #define KSYMTAB_DATA(name, sec, ns) __KSYMTAB(name, name, sec, ns) 62 + #define KSYMTAB_FUNC(name, ns) __KSYMTAB(name, KSYM_FUNC(name), ns) 63 + #define KSYMTAB_DATA(name, ns) __KSYMTAB(name, name, ns) 64 64 65 - #define SYMBOL_CRC(sym, crc, sec) \ 66 - asm(".section \"___kcrctab" sec "+" #sym "\",\"a\"" "\n" \ 67 - ".balign 4" "\n" \ 68 - "__crc_" #sym ":" "\n" \ 69 - ".long " #crc "\n" \ 70 - ".previous" "\n") 65 + #define SYMBOL_CRC(sym, crc) \ 66 + asm(" .section \"___kcrctab+" #sym "\",\"a\"" "\n" \ 67 + " .balign 4" "\n" \ 68 + "__crc_" #sym ":" "\n" \ 69 + " .long " #crc "\n" \ 70 + " .previous" "\n" \ 71 + ) 72 + 73 + #define SYMBOL_FLAGS(sym, flags) \ 74 + asm(" .section \"___kflagstab+" #sym "\",\"a\"" "\n" \ 75 + "__flags_" #sym ":" "\n" \ 76 + " .byte " #flags "\n" \ 77 + " .previous" "\n" \ 78 + ) 71 79 72 80 #endif /* __LINUX_EXPORT_INTERNAL_H__ */
+2 -3
include/linux/module.h
··· 413 413 struct module_attribute *modinfo_attrs; 414 414 const char *version; 415 415 const char *srcversion; 416 + const char *imported_namespaces; 416 417 struct kobject *holders_dir; 417 418 418 419 /* Exported symbols */ 419 420 const struct kernel_symbol *syms; 420 421 const u32 *crcs; 422 + const u8 *flagstab; 421 423 unsigned int num_syms; 422 424 423 425 #ifdef CONFIG_ARCH_USES_CFI_TRAPS ··· 435 433 unsigned int num_kp; 436 434 437 435 /* GPL-only exported symbols. */ 438 - unsigned int num_gpl_syms; 439 - const struct kernel_symbol *gpl_syms; 440 - const u32 *gpl_crcs; 441 436 bool using_gplonly_symbols; 442 437 443 438 #ifdef CONFIG_MODULE_SIG
+1 -29
include/linux/module_signature.h
··· 10 10 #define _LINUX_MODULE_SIGNATURE_H 11 11 12 12 #include <linux/types.h> 13 - 14 - /* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */ 15 - #define MODULE_SIG_STRING "~Module signature appended~\n" 16 - 17 - enum pkey_id_type { 18 - PKEY_ID_PGP, /* OpenPGP generated key ID */ 19 - PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ 20 - PKEY_ID_PKCS7, /* Signature in PKCS#7 message */ 21 - }; 22 - 23 - /* 24 - * Module signature information block. 25 - * 26 - * The constituents of the signature section are, in order: 27 - * 28 - * - Signer's name 29 - * - Key identifier 30 - * - Signature data 31 - * - Information block 32 - */ 33 - struct module_signature { 34 - u8 algo; /* Public-key crypto algorithm [0] */ 35 - u8 hash; /* Digest algorithm [0] */ 36 - u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */ 37 - u8 signer_len; /* Length of signer's name [0] */ 38 - u8 key_id_len; /* Length of key identifier [0] */ 39 - u8 __pad[3]; 40 - __be32 sig_len; /* Length of signature data */ 41 - }; 13 + #include <uapi/linux/module_signature.h> 42 14 43 15 int mod_check_sig(const struct module_signature *ms, size_t file_len, 44 16 const char *name);
+5
include/linux/module_symbol.h
··· 2 2 #ifndef _LINUX_MODULE_SYMBOL_H 3 3 #define _LINUX_MODULE_SYMBOL_H 4 4 5 + /* Kernel symbol flags bitset. */ 6 + enum ksym_flags { 7 + KSYM_FLAG_GPL_ONLY = 1 << 0, 8 + }; 9 + 5 10 /* This ignores the intensely annoying "mapping symbols" found in ELF files. */ 6 11 static inline bool is_mapping_symbol(const char *str) 7 12 {
+47 -53
include/linux/moduleparam.h
··· 317 317 name, &__param_ops_##name, arg, perm, -1, 0) 318 318 319 319 #ifdef CONFIG_SYSFS 320 - extern void kernel_param_lock(struct module *mod); 321 - extern void kernel_param_unlock(struct module *mod); 320 + void kernel_param_lock(struct module *mod); 321 + void kernel_param_unlock(struct module *mod); 322 322 #else 323 323 static inline void kernel_param_lock(struct module *mod) 324 324 { ··· 398 398 * Returns: true if the two parameter names are equal. 399 399 * Dashes (-) are considered equal to underscores (_). 400 400 */ 401 - extern bool parameq(const char *name1, const char *name2); 401 + bool parameq(const char *name1, const char *name2); 402 402 403 403 /** 404 404 * parameqn - checks if two parameter names match ··· 412 412 * are equal. 413 413 * Dashes (-) are considered equal to underscores (_). 414 414 */ 415 - extern bool parameqn(const char *name1, const char *name2, size_t n); 415 + bool parameqn(const char *name1, const char *name2, size_t n); 416 416 417 417 typedef int (*parse_unknown_fn)(char *param, char *val, const char *doing, void *arg); 418 418 419 419 /* Called on module insert or kernel boot */ 420 - extern char *parse_args(const char *name, 421 - char *args, 422 - const struct kernel_param *params, 423 - unsigned num, 424 - s16 level_min, 425 - s16 level_max, 426 - void *arg, parse_unknown_fn unknown); 420 + char *parse_args(const char *doing, 421 + char *args, 422 + const struct kernel_param *params, 423 + unsigned int num, 424 + s16 min_level, 425 + s16 max_level, 426 + void *arg, parse_unknown_fn unknown); 427 427 428 428 /* Called by module remove. */ 429 - #ifdef CONFIG_SYSFS 430 - extern void destroy_params(const struct kernel_param *params, unsigned num); 431 - #else 432 - static inline void destroy_params(const struct kernel_param *params, 433 - unsigned num) 434 - { 435 - } 436 - #endif /* !CONFIG_SYSFS */ 429 + #ifdef CONFIG_MODULES 430 + void module_destroy_params(const struct kernel_param *params, unsigned int num); 431 + #endif 437 432 438 433 /* All the helper functions */ 439 434 /* The macros to do compile-time type checking stolen from Jakub ··· 437 442 static inline type __always_unused *__check_##name(void) { return(p); } 438 443 439 444 extern const struct kernel_param_ops param_ops_byte; 440 - extern int param_set_byte(const char *val, const struct kernel_param *kp); 441 - extern int param_get_byte(char *buffer, const struct kernel_param *kp); 445 + int param_set_byte(const char *val, const struct kernel_param *kp); 446 + int param_get_byte(char *buffer, const struct kernel_param *kp); 442 447 #define param_check_byte(name, p) __param_check(name, p, unsigned char) 443 448 444 449 extern const struct kernel_param_ops param_ops_short; 445 - extern int param_set_short(const char *val, const struct kernel_param *kp); 446 - extern int param_get_short(char *buffer, const struct kernel_param *kp); 450 + int param_set_short(const char *val, const struct kernel_param *kp); 451 + int param_get_short(char *buffer, const struct kernel_param *kp); 447 452 #define param_check_short(name, p) __param_check(name, p, short) 448 453 449 454 extern const struct kernel_param_ops param_ops_ushort; 450 - extern int param_set_ushort(const char *val, const struct kernel_param *kp); 451 - extern int param_get_ushort(char *buffer, const struct kernel_param *kp); 455 + int param_set_ushort(const char *val, const struct kernel_param *kp); 456 + int param_get_ushort(char *buffer, const struct kernel_param *kp); 452 457 #define param_check_ushort(name, p) __param_check(name, p, unsigned short) 453 458 454 459 extern const struct kernel_param_ops param_ops_int; 455 - extern int param_set_int(const char *val, const struct kernel_param *kp); 456 - extern int param_get_int(char *buffer, const struct kernel_param *kp); 460 + int param_set_int(const char *val, const struct kernel_param *kp); 461 + int param_get_int(char *buffer, const struct kernel_param *kp); 457 462 #define param_check_int(name, p) __param_check(name, p, int) 458 463 459 464 extern const struct kernel_param_ops param_ops_uint; 460 - extern int param_set_uint(const char *val, const struct kernel_param *kp); 461 - extern int param_get_uint(char *buffer, const struct kernel_param *kp); 465 + int param_set_uint(const char *val, const struct kernel_param *kp); 466 + int param_get_uint(char *buffer, const struct kernel_param *kp); 462 467 int param_set_uint_minmax(const char *val, const struct kernel_param *kp, 463 468 unsigned int min, unsigned int max); 464 469 #define param_check_uint(name, p) __param_check(name, p, unsigned int) 465 470 466 471 extern const struct kernel_param_ops param_ops_long; 467 - extern int param_set_long(const char *val, const struct kernel_param *kp); 468 - extern int param_get_long(char *buffer, const struct kernel_param *kp); 472 + int param_set_long(const char *val, const struct kernel_param *kp); 473 + int param_get_long(char *buffer, const struct kernel_param *kp); 469 474 #define param_check_long(name, p) __param_check(name, p, long) 470 475 471 476 extern const struct kernel_param_ops param_ops_ulong; 472 - extern int param_set_ulong(const char *val, const struct kernel_param *kp); 473 - extern int param_get_ulong(char *buffer, const struct kernel_param *kp); 477 + int param_set_ulong(const char *val, const struct kernel_param *kp); 478 + int param_get_ulong(char *buffer, const struct kernel_param *kp); 474 479 #define param_check_ulong(name, p) __param_check(name, p, unsigned long) 475 480 476 481 extern const struct kernel_param_ops param_ops_ullong; 477 - extern int param_set_ullong(const char *val, const struct kernel_param *kp); 478 - extern int param_get_ullong(char *buffer, const struct kernel_param *kp); 482 + int param_set_ullong(const char *val, const struct kernel_param *kp); 483 + int param_get_ullong(char *buffer, const struct kernel_param *kp); 479 484 #define param_check_ullong(name, p) __param_check(name, p, unsigned long long) 480 485 481 486 extern const struct kernel_param_ops param_ops_hexint; 482 - extern int param_set_hexint(const char *val, const struct kernel_param *kp); 483 - extern int param_get_hexint(char *buffer, const struct kernel_param *kp); 487 + int param_set_hexint(const char *val, const struct kernel_param *kp); 488 + int param_get_hexint(char *buffer, const struct kernel_param *kp); 484 489 #define param_check_hexint(name, p) param_check_uint(name, p) 485 490 486 491 extern const struct kernel_param_ops param_ops_charp; 487 - extern int param_set_charp(const char *val, const struct kernel_param *kp); 488 - extern int param_get_charp(char *buffer, const struct kernel_param *kp); 489 - extern void param_free_charp(void *arg); 492 + int param_set_charp(const char *val, const struct kernel_param *kp); 493 + int param_get_charp(char *buffer, const struct kernel_param *kp); 494 + void param_free_charp(void *arg); 490 495 #define param_check_charp(name, p) __param_check(name, p, char *) 491 496 492 497 /* We used to allow int as well as bool. We're taking that away! */ 493 498 extern const struct kernel_param_ops param_ops_bool; 494 - extern int param_set_bool(const char *val, const struct kernel_param *kp); 495 - extern int param_get_bool(char *buffer, const struct kernel_param *kp); 499 + int param_set_bool(const char *val, const struct kernel_param *kp); 500 + int param_get_bool(char *buffer, const struct kernel_param *kp); 496 501 #define param_check_bool(name, p) __param_check(name, p, bool) 497 502 498 503 extern const struct kernel_param_ops param_ops_bool_enable_only; 499 - extern int param_set_bool_enable_only(const char *val, 500 - const struct kernel_param *kp); 504 + int param_set_bool_enable_only(const char *val, const struct kernel_param *kp); 501 505 /* getter is the same as for the regular bool */ 502 506 #define param_check_bool_enable_only param_check_bool 503 507 504 508 extern const struct kernel_param_ops param_ops_invbool; 505 - extern int param_set_invbool(const char *val, const struct kernel_param *kp); 506 - extern int param_get_invbool(char *buffer, const struct kernel_param *kp); 509 + int param_set_invbool(const char *val, const struct kernel_param *kp); 510 + int param_get_invbool(char *buffer, const struct kernel_param *kp); 507 511 #define param_check_invbool(name, p) __param_check(name, p, bool) 508 512 509 513 /* An int, which can only be set like a bool (though it shows as an int). */ 510 514 extern const struct kernel_param_ops param_ops_bint; 511 - extern int param_set_bint(const char *val, const struct kernel_param *kp); 515 + int param_set_bint(const char *val, const struct kernel_param *kp); 512 516 #define param_get_bint param_get_int 513 517 #define param_check_bint param_check_int 514 518 ··· 614 620 extern const struct kernel_param_ops param_array_ops; 615 621 616 622 extern const struct kernel_param_ops param_ops_string; 617 - extern int param_set_copystring(const char *val, const struct kernel_param *); 618 - extern int param_get_string(char *buffer, const struct kernel_param *kp); 623 + int param_set_copystring(const char *val, const struct kernel_param *kp); 624 + int param_get_string(char *buffer, const struct kernel_param *kp); 619 625 620 626 /* for exporting parameters in /sys/module/.../parameters */ 621 627 622 628 struct module; 623 629 624 630 #if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES) 625 - extern int module_param_sysfs_setup(struct module *mod, 626 - const struct kernel_param *kparam, 627 - unsigned int num_params); 631 + int module_param_sysfs_setup(struct module *mod, 632 + const struct kernel_param *kparam, 633 + unsigned int num_params); 628 634 629 - extern void module_param_sysfs_remove(struct module *mod); 635 + void module_param_sysfs_remove(struct module *mod); 630 636 #else 631 637 static inline int module_param_sysfs_setup(struct module *mod, 632 638 const struct kernel_param *kparam,
+41
include/uapi/linux/module_signature.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ 2 + /* 3 + * Module signature handling. 4 + * 5 + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 6 + * Written by David Howells (dhowells@redhat.com) 7 + */ 8 + 9 + #ifndef _UAPI_LINUX_MODULE_SIGNATURE_H 10 + #define _UAPI_LINUX_MODULE_SIGNATURE_H 11 + 12 + #include <linux/types.h> 13 + 14 + /* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */ 15 + #define MODULE_SIGNATURE_MARKER "~Module signature appended~\n" 16 + 17 + enum module_signature_type { 18 + MODULE_SIGNATURE_TYPE_PKCS7 = 2, /* Signature in PKCS#7 message */ 19 + }; 20 + 21 + /* 22 + * Module signature information block. 23 + * 24 + * The constituents of the signature section are, in order: 25 + * 26 + * - Signer's name 27 + * - Key identifier 28 + * - Signature data 29 + * - Information block 30 + */ 31 + struct module_signature { 32 + __u8 algo; /* Public-key crypto algorithm [0] */ 33 + __u8 hash; /* Digest algorithm [0] */ 34 + __u8 id_type; /* Key identifier type [enum module_signature_type] */ 35 + __u8 signer_len; /* Length of signer's name [0] */ 36 + __u8 key_id_len; /* Length of key identifier [0] */ 37 + __u8 __pad[3]; 38 + __be32 sig_len; /* Length of signature data */ 39 + }; 40 + 41 + #endif /* _UAPI_LINUX_MODULE_SIGNATURE_H */
+1 -3
kernel/module/internal.h
··· 53 53 /* Provided by the linker */ 54 54 extern const struct kernel_symbol __start___ksymtab[]; 55 55 extern const struct kernel_symbol __stop___ksymtab[]; 56 - extern const struct kernel_symbol __start___ksymtab_gpl[]; 57 - extern const struct kernel_symbol __stop___ksymtab_gpl[]; 58 56 extern const u32 __start___kcrctab[]; 59 - extern const u32 __start___kcrctab_gpl[]; 57 + extern const u8 __start___kflagstab[]; 60 58 61 59 #define KMOD_PATH_LEN 256 62 60 extern char modprobe_path[];
+128 -64
kernel/module/main.c
··· 11 11 #include <linux/extable.h> 12 12 #include <linux/moduleloader.h> 13 13 #include <linux/module_signature.h> 14 + #include <linux/module_symbol.h> 14 15 #include <linux/trace_events.h> 15 16 #include <linux/init.h> 16 17 #include <linux/kallsyms.h> ··· 88 87 struct symsearch { 89 88 const struct kernel_symbol *start, *stop; 90 89 const u32 *crcs; 91 - enum mod_license license; 90 + const u8 *flagstab; 92 91 }; 93 92 94 93 /* ··· 365 364 struct find_symbol_arg *fsa) 366 365 { 367 366 struct kernel_symbol *sym; 368 - 369 - if (!fsa->gplok && syms->license == GPL_ONLY) 370 - return false; 367 + u8 sym_flags; 371 368 372 369 sym = bsearch(fsa->name, syms->start, syms->stop - syms->start, 373 370 sizeof(struct kernel_symbol), cmp_name); 374 371 if (!sym) 375 372 return false; 376 373 374 + sym_flags = *(syms->flagstab + (sym - syms->start)); 375 + if (!fsa->gplok && (sym_flags & KSYM_FLAG_GPL_ONLY)) 376 + return false; 377 + 377 378 fsa->owner = owner; 378 379 fsa->crc = symversion(syms->crcs, sym - syms->start); 379 380 fsa->sym = sym; 380 - fsa->license = syms->license; 381 + fsa->license = (sym_flags & KSYM_FLAG_GPL_ONLY) ? GPL_ONLY : NOT_GPL_ONLY; 381 382 382 383 return true; 383 384 } ··· 390 387 */ 391 388 bool find_symbol(struct find_symbol_arg *fsa) 392 389 { 393 - static const struct symsearch arr[] = { 394 - { __start___ksymtab, __stop___ksymtab, __start___kcrctab, 395 - NOT_GPL_ONLY }, 396 - { __start___ksymtab_gpl, __stop___ksymtab_gpl, 397 - __start___kcrctab_gpl, 398 - GPL_ONLY }, 390 + const struct symsearch syms = { 391 + .start = __start___ksymtab, 392 + .stop = __stop___ksymtab, 393 + .crcs = __start___kcrctab, 394 + .flagstab = __start___kflagstab, 399 395 }; 400 396 struct module *mod; 401 - unsigned int i; 402 397 403 - for (i = 0; i < ARRAY_SIZE(arr); i++) 404 - if (find_exported_symbol_in_section(&arr[i], NULL, fsa)) 405 - return true; 398 + if (find_exported_symbol_in_section(&syms, NULL, fsa)) 399 + return true; 406 400 407 401 list_for_each_entry_rcu(mod, &modules, list, 408 402 lockdep_is_held(&module_mutex)) { 409 - struct symsearch arr[] = { 410 - { mod->syms, mod->syms + mod->num_syms, mod->crcs, 411 - NOT_GPL_ONLY }, 412 - { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms, 413 - mod->gpl_crcs, 414 - GPL_ONLY }, 403 + const struct symsearch syms = { 404 + .start = mod->syms, 405 + .stop = mod->syms + mod->num_syms, 406 + .crcs = mod->crcs, 407 + .flagstab = mod->flagstab, 415 408 }; 416 409 417 410 if (mod->state == MODULE_STATE_UNFORMED) 418 411 continue; 419 412 420 - for (i = 0; i < ARRAY_SIZE(arr); i++) 421 - if (find_exported_symbol_in_section(&arr[i], mod, fsa)) 422 - return true; 413 + if (find_exported_symbol_in_section(&syms, mod, fsa)) 414 + return true; 423 415 } 424 416 425 417 pr_debug("Failed to find symbol %s\n", fsa->name); ··· 604 606 605 607 MODINFO_ATTR(version); 606 608 MODINFO_ATTR(srcversion); 609 + 610 + static void setup_modinfo_import_ns(struct module *mod, const char *s) 611 + { 612 + mod->imported_namespaces = NULL; 613 + } 614 + 615 + static ssize_t show_modinfo_import_ns(const struct module_attribute *mattr, 616 + struct module_kobject *mk, char *buffer) 617 + { 618 + return sysfs_emit(buffer, "%s\n", mk->mod->imported_namespaces); 619 + } 620 + 621 + static int modinfo_import_ns_exists(struct module *mod) 622 + { 623 + return mod->imported_namespaces != NULL; 624 + } 625 + 626 + static void free_modinfo_import_ns(struct module *mod) 627 + { 628 + kfree(mod->imported_namespaces); 629 + mod->imported_namespaces = NULL; 630 + } 631 + 632 + static const struct module_attribute modinfo_import_ns = { 633 + .attr = { .name = "import_ns", .mode = 0444 }, 634 + .show = show_modinfo_import_ns, 635 + .setup = setup_modinfo_import_ns, 636 + .test = modinfo_import_ns_exists, 637 + .free = free_modinfo_import_ns, 638 + }; 607 639 608 640 static struct { 609 641 char name[MODULE_NAME_LEN]; ··· 1086 1058 &module_uevent, 1087 1059 &modinfo_version, 1088 1060 &modinfo_srcversion, 1061 + &modinfo_import_ns, 1089 1062 &modinfo_initstate, 1090 1063 &modinfo_coresize, 1091 1064 #ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC ··· 1437 1408 module_unload_free(mod); 1438 1409 1439 1410 /* Free any allocated parameters. */ 1440 - destroy_params(mod->kp, mod->num_kp); 1411 + module_destroy_params(mod->kp, mod->num_kp); 1441 1412 1442 1413 if (is_livepatch_module(mod)) 1443 1414 free_module_elf(mod); ··· 1495 1466 */ 1496 1467 static int verify_exported_symbols(struct module *mod) 1497 1468 { 1498 - unsigned int i; 1499 1469 const struct kernel_symbol *s; 1500 - struct { 1501 - const struct kernel_symbol *sym; 1502 - unsigned int num; 1503 - } arr[] = { 1504 - { mod->syms, mod->num_syms }, 1505 - { mod->gpl_syms, mod->num_gpl_syms }, 1506 - }; 1507 - 1508 - for (i = 0; i < ARRAY_SIZE(arr); i++) { 1509 - for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) { 1510 - struct find_symbol_arg fsa = { 1511 - .name = kernel_symbol_name(s), 1512 - .gplok = true, 1513 - }; 1514 - if (find_symbol(&fsa)) { 1515 - pr_err("%s: exports duplicate symbol %s" 1516 - " (owned by %s)\n", 1517 - mod->name, kernel_symbol_name(s), 1518 - module_name(fsa.owner)); 1519 - return -ENOEXEC; 1520 - } 1470 + for (s = mod->syms; s < mod->syms + mod->num_syms; s++) { 1471 + struct find_symbol_arg fsa = { 1472 + .name = kernel_symbol_name(s), 1473 + .gplok = true, 1474 + }; 1475 + if (find_symbol(&fsa)) { 1476 + pr_err("%s: exports duplicate symbol %s (owned by %s)\n", 1477 + mod->name, kernel_symbol_name(s), 1478 + module_name(fsa.owner)); 1479 + return -ENOEXEC; 1521 1480 } 1522 1481 } 1523 1482 return 0; ··· 1777 1760 } 1778 1761 } 1779 1762 1763 + static int copy_modinfo_import_ns(struct module *mod, struct load_info *info) 1764 + { 1765 + char *ns; 1766 + size_t len, total_len = 0; 1767 + char *buf, *p; 1768 + 1769 + for_each_modinfo_entry(ns, info, "import_ns") 1770 + total_len += strlen(ns) + 1; 1771 + 1772 + if (!total_len) { 1773 + mod->imported_namespaces = NULL; 1774 + return 0; 1775 + } 1776 + 1777 + buf = kmalloc(total_len, GFP_KERNEL); 1778 + if (!buf) 1779 + return -ENOMEM; 1780 + 1781 + p = buf; 1782 + for_each_modinfo_entry(ns, info, "import_ns") { 1783 + len = strlen(ns); 1784 + memcpy(p, ns, len); 1785 + p += len; 1786 + *p++ = '\n'; 1787 + } 1788 + /* Replace trailing newline with null terminator. */ 1789 + *(p - 1) = '\0'; 1790 + 1791 + mod->imported_namespaces = buf; 1792 + return 0; 1793 + } 1794 + 1780 1795 static int setup_modinfo(struct module *mod, struct load_info *info) 1781 1796 { 1782 1797 const struct module_attribute *attr; 1783 1798 char *imported_namespace; 1784 - int i; 1799 + int i, err; 1785 1800 1786 1801 for (i = 0; (attr = modinfo_attrs[i]); i++) { 1787 1802 if (attr->setup) ··· 1831 1782 return -EPERM; 1832 1783 } 1833 1784 } 1785 + 1786 + err = copy_modinfo_import_ns(mod, info); 1787 + if (err) 1788 + return err; 1834 1789 1835 1790 return 0; 1836 1791 } ··· 2663 2610 mod->syms = section_objs(info, "__ksymtab", 2664 2611 sizeof(*mod->syms), &mod->num_syms); 2665 2612 mod->crcs = section_addr(info, "__kcrctab"); 2666 - mod->gpl_syms = section_objs(info, "__ksymtab_gpl", 2667 - sizeof(*mod->gpl_syms), 2668 - &mod->num_gpl_syms); 2669 - mod->gpl_crcs = section_addr(info, "__kcrctab_gpl"); 2613 + mod->flagstab = section_addr(info, "__kflagstab"); 2614 + 2615 + if (section_addr(info, "__ksymtab_gpl")) 2616 + pr_warn("%s: ignoring obsolete section __ksymtab_gpl\n", 2617 + mod->name); 2618 + if (section_addr(info, "__kcrctab_gpl")) 2619 + pr_warn("%s: ignoring obsolete section __kcrctab_gpl\n", 2620 + mod->name); 2670 2621 2671 2622 #ifdef CONFIG_CONSTRUCTORS 2672 2623 mod->ctors = section_objs(info, ".ctors", ··· 2874 2817 return ret; 2875 2818 } 2876 2819 2877 - static int check_export_symbol_versions(struct module *mod) 2820 + static int check_export_symbol_sections(struct module *mod) 2878 2821 { 2822 + if (mod->num_syms && !mod->flagstab) { 2823 + pr_err("%s: no flags for exported symbols\n", mod->name); 2824 + return -ENOEXEC; 2825 + } 2879 2826 #ifdef CONFIG_MODVERSIONS 2880 - if ((mod->num_syms && !mod->crcs) || 2881 - (mod->num_gpl_syms && !mod->gpl_crcs)) { 2827 + if (mod->num_syms && !mod->crcs) { 2882 2828 return try_to_force_load(mod, 2883 2829 "no versions for exported symbols"); 2884 2830 } ··· 3105 3045 if (mod->init != NULL) 3106 3046 ret = do_one_initcall(mod->init); 3107 3047 if (ret < 0) { 3048 + /* 3049 + * -EEXIST is reserved by [f]init_module() to signal to userspace that 3050 + * a module with this name is already loaded. Use something else if the 3051 + * module itself is returning that. 3052 + */ 3053 + if (ret == -EEXIST) 3054 + ret = -EBUSY; 3055 + 3108 3056 goto fail_free_freeinit; 3109 3057 } 3110 - if (ret > 0) { 3111 - pr_warn("%s: '%s'->init suspiciously returned %d, it should " 3112 - "follow 0/-E convention\n" 3113 - "%s: loading module anyway...\n", 3114 - __func__, mod->name, ret, __func__); 3115 - dump_stack(); 3116 - } 3058 + if (ret > 0) 3059 + pr_warn("%s: init suspiciously returned %d, it should follow 0/-E convention\n", 3060 + mod->name, ret); 3117 3061 3118 3062 /* Now it's a first class citizen! */ 3119 3063 mod->state = MODULE_STATE_LIVE; ··· 3498 3434 if (err) 3499 3435 goto free_unload; 3500 3436 3501 - err = check_export_symbol_versions(mod); 3437 + err = check_export_symbol_sections(mod); 3502 3438 if (err) 3503 3439 goto free_unload; 3504 3440 ··· 3583 3519 mod_sysfs_teardown(mod); 3584 3520 coming_cleanup: 3585 3521 mod->state = MODULE_STATE_GOING; 3586 - destroy_params(mod->kp, mod->num_kp); 3522 + module_destroy_params(mod->kp, mod->num_kp); 3587 3523 blocking_notifier_call_chain(&module_notify_list, 3588 3524 MODULE_STATE_GOING, mod); 3589 3525 klp_module_going(mod);
+2 -2
kernel/module/signing.c
··· 70 70 int module_sig_check(struct load_info *info, int flags) 71 71 { 72 72 int err = -ENODATA; 73 - const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; 73 + const unsigned long markerlen = sizeof(MODULE_SIGNATURE_MARKER) - 1; 74 74 const char *reason; 75 75 const void *mod = info->hdr; 76 76 bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS | ··· 81 81 */ 82 82 if (!mangled_module && 83 83 info->len > markerlen && 84 - memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) { 84 + memcmp(mod + info->len - markerlen, MODULE_SIGNATURE_MARKER, markerlen) == 0) { 85 85 /* We truncate the module to discard the signature */ 86 86 info->len -= markerlen; 87 87 err = mod_verify_sig(mod, info);
+1 -1
kernel/module_signature.c
··· 24 24 if (be32_to_cpu(ms->sig_len) >= file_len - sizeof(*ms)) 25 25 return -EBADMSG; 26 26 27 - if (ms->id_type != PKEY_ID_PKCS7) { 27 + if (ms->id_type != MODULE_SIGNATURE_TYPE_PKCS7) { 28 28 pr_err("%s: not signed with expected PKCS#7 message\n", 29 29 name); 30 30 return -ENOPKG;
+19 -10
kernel/params.c
··· 161 161 char *parse_args(const char *doing, 162 162 char *args, 163 163 const struct kernel_param *params, 164 - unsigned num, 164 + unsigned int num, 165 165 s16 min_level, 166 166 s16 max_level, 167 167 void *arg, parse_unknown_fn unknown) ··· 745 745 } 746 746 #endif 747 747 748 - void destroy_params(const struct kernel_param *params, unsigned num) 749 - { 750 - unsigned int i; 751 - 752 - for (i = 0; i < num; i++) 753 - if (params[i].ops->free) 754 - params[i].ops->free(params[i].arg); 755 - } 756 - 757 748 struct module_kobject * __init_or_module 758 749 lookup_or_create_module_kobject(const char *name) 759 750 { ··· 976 985 late_initcall(param_sysfs_builtin_init); 977 986 978 987 #endif /* CONFIG_SYSFS */ 988 + 989 + #ifdef CONFIG_MODULES 990 + 991 + /* 992 + * module_destroy_params - free all parameters for one module 993 + * @params: module parameters (array) 994 + * @num: number of module parameters 995 + */ 996 + void module_destroy_params(const struct kernel_param *params, unsigned int num) 997 + { 998 + unsigned int i; 999 + 1000 + for (i = 0; i < num; i++) 1001 + if (params[i].ops->free) 1002 + params[i].ops->free(params[i].arg); 1003 + } 1004 + 1005 + #endif /* CONFIG_MODULES */
+1
scripts/Makefile
··· 35 35 HOSTLDLIBS_sorttable = -lpthread 36 36 HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include 37 37 HOSTCFLAGS_sign-file.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) 38 + HOSTCFLAGS_sign-file.o += -I$(srctree)/tools/include/uapi/ 38 39 HOSTLDLIBS_sign-file = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) 39 40 40 41 ifdef CONFIG_UNWINDER_ORC
+12 -4
scripts/mod/modpost.c
··· 244 244 return s; 245 245 } 246 246 247 + static uint8_t get_symbol_flags(const struct symbol *sym) 248 + { 249 + return sym->is_gpl_only ? KSYM_FLAG_GPL_ONLY : 0; 250 + } 251 + 247 252 /* For the hash of exported symbols */ 248 253 static void hash_add_symbol(struct symbol *sym) 249 254 { ··· 1876 1871 if (trim_unused_exports && !sym->used) 1877 1872 continue; 1878 1873 1879 - buf_printf(buf, "KSYMTAB_%s(%s, \"%s\", \"%s\");\n", 1874 + buf_printf(buf, "KSYMTAB_%s(%s, \"%s\");\n", 1880 1875 sym->is_func ? "FUNC" : "DATA", sym->name, 1881 - sym->is_gpl_only ? "_gpl" : "", sym->namespace); 1876 + sym->namespace); 1877 + 1878 + buf_printf(buf, "SYMBOL_FLAGS(%s, 0x%02x);\n", 1879 + sym->name, get_symbol_flags(sym)); 1882 1880 } 1883 1881 1884 1882 if (!modversions) ··· 1899 1891 sym->name, mod->name, mod->is_vmlinux ? "" : ".ko", 1900 1892 sym->name); 1901 1893 1902 - buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n", 1903 - sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : ""); 1894 + buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x);\n", 1895 + sym->name, sym->crc); 1904 1896 } 1905 1897 } 1906 1898
+7 -8
scripts/module.lds.S
··· 20 20 } 21 21 22 22 __ksymtab 0 : ALIGN(8) { *(SORT(___ksymtab+*)) } 23 - __ksymtab_gpl 0 : ALIGN(8) { *(SORT(___ksymtab_gpl+*)) } 24 23 __kcrctab 0 : ALIGN(4) { *(SORT(___kcrctab+*)) } 25 - __kcrctab_gpl 0 : ALIGN(4) { *(SORT(___kcrctab_gpl+*)) } 24 + __kflagstab 0 : ALIGN(1) { *(SORT(___kflagstab+*)) } 26 25 27 26 .ctors 0 : ALIGN(8) { *(SORT(.ctors.*)) *(.ctors) } 28 27 .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } ··· 31 32 __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } 32 33 __ex_table 0 : ALIGN(4) { KEEP(*(__ex_table)) } 33 34 34 - __patchable_function_entries : { *(__patchable_function_entries) } 35 + __patchable_function_entries 0 : { *(__patchable_function_entries) } 35 36 36 37 .init.klp_funcs 0 : ALIGN(8) { KEEP(*(.init.klp_funcs)) } 37 38 .init.klp_objects 0 : ALIGN(8) { KEEP(*(.init.klp_objects)) } 38 39 39 40 #ifdef CONFIG_ARCH_USES_CFI_TRAPS 40 - __kcfi_traps : { KEEP(*(.kcfi_traps)) } 41 + __kcfi_traps 0 : { KEEP(*(.kcfi_traps)) } 41 42 #endif 42 43 43 - .text : { 44 + .text 0 : { 44 45 *(.text .text.[0-9a-zA-Z_]*) 45 46 } 46 47 47 - .bss : { 48 + .bss 0 : { 48 49 *(.bss .bss.[0-9a-zA-Z_]*) 49 50 *(.bss..L*) 50 51 } 51 52 52 - .data : { 53 + .data 0 : { 53 54 *(.data .data.[0-9a-zA-Z_]*) 54 55 *(.data..L*) 55 56 } 56 57 57 - .rodata : { 58 + .rodata 0 : { 58 59 *(.rodata .rodata.[0-9a-zA-Z_]*) 59 60 *(.rodata..L*) 60 61 }
+4 -15
scripts/sign-file.c
··· 40 40 #endif 41 41 #include "ssl-common.h" 42 42 43 - struct module_signature { 44 - uint8_t algo; /* Public-key crypto algorithm [0] */ 45 - uint8_t hash; /* Digest algorithm [0] */ 46 - uint8_t id_type; /* Key identifier type [PKEY_ID_PKCS7] */ 47 - uint8_t signer_len; /* Length of signer's name [0] */ 48 - uint8_t key_id_len; /* Length of key identifier [0] */ 49 - uint8_t __pad[3]; 50 - uint32_t sig_len; /* Length of signature data */ 51 - }; 52 - 53 - #define PKEY_ID_PKCS7 2 54 - 55 - static char magic_number[] = "~Module signature appended~\n"; 43 + #include <linux/module_signature.h> 56 44 57 45 static __attribute__((noreturn)) 58 46 void format(void) ··· 185 197 186 198 int main(int argc, char **argv) 187 199 { 188 - struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 }; 200 + struct module_signature sig_info = { .id_type = MODULE_SIGNATURE_TYPE_PKCS7 }; 189 201 char *hash_algo = NULL; 190 202 char *private_key_name = NULL, *raw_sig_name = NULL; 191 203 char *x509_name, *module_name, *dest_name; ··· 345 357 sig_size = BIO_number_written(bd) - module_size; 346 358 sig_info.sig_len = htonl(sig_size); 347 359 ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name); 348 - ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name); 360 + ERR(BIO_write(bd, MODULE_SIGNATURE_MARKER, sizeof(MODULE_SIGNATURE_MARKER) - 1) < 0, 361 + "%s", dest_name); 349 362 350 363 ERR(BIO_free(bd) != 1, "%s", dest_name); 351 364
+3 -3
security/integrity/ima/ima_modsig.c
··· 40 40 int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, 41 41 struct modsig **modsig) 42 42 { 43 - const size_t marker_len = strlen(MODULE_SIG_STRING); 43 + const size_t marker_len = strlen(MODULE_SIGNATURE_MARKER); 44 44 const struct module_signature *sig; 45 45 struct modsig *hdr; 46 46 size_t sig_len; ··· 51 51 return -ENOENT; 52 52 53 53 p = buf + buf_len - marker_len; 54 - if (memcmp(p, MODULE_SIG_STRING, marker_len)) 54 + if (memcmp(p, MODULE_SIGNATURE_MARKER, marker_len)) 55 55 return -ENOENT; 56 56 57 57 buf_len -= marker_len; ··· 105 105 * Provide the file contents (minus the appended sig) so that the PKCS7 106 106 * code can calculate the file hash. 107 107 */ 108 - size -= modsig->raw_pkcs7_len + strlen(MODULE_SIG_STRING) + 108 + size -= modsig->raw_pkcs7_len + strlen(MODULE_SIGNATURE_MARKER) + 109 109 sizeof(struct module_signature); 110 110 rc = pkcs7_supply_detached_data(modsig->pkcs7_msg, buf, size); 111 111 if (rc)
+41
tools/include/uapi/linux/module_signature.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ 2 + /* 3 + * Module signature handling. 4 + * 5 + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 6 + * Written by David Howells (dhowells@redhat.com) 7 + */ 8 + 9 + #ifndef _UAPI_LINUX_MODULE_SIGNATURE_H 10 + #define _UAPI_LINUX_MODULE_SIGNATURE_H 11 + 12 + #include <linux/types.h> 13 + 14 + /* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */ 15 + #define MODULE_SIGNATURE_MARKER "~Module signature appended~\n" 16 + 17 + enum module_signature_type { 18 + MODULE_SIGNATURE_TYPE_PKCS7 = 2, /* Signature in PKCS#7 message */ 19 + }; 20 + 21 + /* 22 + * Module signature information block. 23 + * 24 + * The constituents of the signature section are, in order: 25 + * 26 + * - Signer's name 27 + * - Key identifier 28 + * - Signature data 29 + * - Information block 30 + */ 31 + struct module_signature { 32 + __u8 algo; /* Public-key crypto algorithm [0] */ 33 + __u8 hash; /* Digest algorithm [0] */ 34 + __u8 id_type; /* Key identifier type [enum module_signature_type] */ 35 + __u8 signer_len; /* Length of signer's name [0] */ 36 + __u8 key_id_len; /* Length of key identifier [0] */ 37 + __u8 __pad[3]; 38 + __be32 sig_len; /* Length of signature data */ 39 + }; 40 + 41 + #endif /* _UAPI_LINUX_MODULE_SIGNATURE_H */
+1
tools/testing/selftests/bpf/Makefile
··· 274 274 $(OUTPUT)/sign-file: ../../../../scripts/sign-file.c 275 275 $(call msg,SIGN-FILE,,$@) 276 276 $(Q)$(CC) $(shell $(PKG_CONFIG) --cflags libcrypto 2> /dev/null) \ 277 + -I$(srctree)/tools/include/uapi/ \ 277 278 $< -o $@ \ 278 279 $(shell $(PKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) 279 280
+3 -25
tools/testing/selftests/bpf/prog_tests/verify_pkcs7_sig.c
··· 18 18 #include <linux/keyctl.h> 19 19 #include <sys/xattr.h> 20 20 #include <linux/fsverity.h> 21 + #include <linux/module_signature.h> 21 22 #include <test_progs.h> 22 23 23 24 #include "test_verify_pkcs7_sig.skel.h" ··· 33 32 #ifndef SHA256_DIGEST_SIZE 34 33 #define SHA256_DIGEST_SIZE 32 35 34 #endif 36 - 37 - /* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */ 38 - #define MODULE_SIG_STRING "~Module signature appended~\n" 39 - 40 - /* 41 - * Module signature information block. 42 - * 43 - * The constituents of the signature section are, in order: 44 - * 45 - * - Signer's name 46 - * - Key identifier 47 - * - Signature data 48 - * - Information block 49 - */ 50 - struct module_signature { 51 - __u8 algo; /* Public-key crypto algorithm [0] */ 52 - __u8 hash; /* Digest algorithm [0] */ 53 - __u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */ 54 - __u8 signer_len; /* Length of signer's name [0] */ 55 - __u8 key_id_len; /* Length of key identifier [0] */ 56 - __u8 __pad[3]; 57 - __be32 sig_len; /* Length of signature data */ 58 - }; 59 35 60 36 struct data { 61 37 __u8 data[MAX_DATA_SIZE]; ··· 193 215 return 0; 194 216 195 217 modlen = st.st_size; 196 - marker_len = sizeof(MODULE_SIG_STRING) - 1; 218 + marker_len = sizeof(MODULE_SIGNATURE_MARKER) - 1; 197 219 198 220 fd = open(mod_path, O_RDONLY); 199 221 if (fd == -1) ··· 206 228 if (mod == MAP_FAILED) 207 229 return -errno; 208 230 209 - if (strncmp(mod + modlen - marker_len, MODULE_SIG_STRING, marker_len)) { 231 + if (strncmp(mod + modlen - marker_len, MODULE_SIGNATURE_MARKER, marker_len)) { 210 232 ret = -EINVAL; 211 233 goto out; 212 234 }