Commit 6f81a446 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull module updates from Luis Chamberlain:
 "There are a few fixes / cleanups from Vincent, Chunhui, and Petr, but
  the most important part of this pull request is the Rust community
  stepping up to help maintain both C / Rust code for future Rust module
  support. We grow the set of modules maintainers by three now, and with
  this hope to scale to help address what's needed to properly support
  future Rust module support.

  A lot of exciting stuff coming in future kernel releases.

  This has been on linux-next for ~ 3 weeks now with no issues"

* tag 'modules-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux:
  module: Refine kmemleak scanned areas
  module: abort module loading when sysfs setup suffer errors
  MAINTAINERS: scale modules with more reviewers
  module: Clean up the description of MODULE_SIG_<type>
  module: Split modules_install compression and in-kernel decompression
parents f95c1390 b319cea8
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -15678,6 +15678,9 @@ F: include/dt-bindings/clock/mobileye,eyeq5-clk.h
MODULE SUPPORT
M:	Luis Chamberlain <mcgrof@kernel.org>
R:	Petr Pavlu <petr.pavlu@suse.com>
R:	Sami Tolvanen <samitolvanen@google.com>
R:	Daniel Gomez <da.gomez@samsung.com>
L:	linux-modules@vger.kernel.org
L:	linux-kernel@vger.kernel.org
S:	Maintained
+39 −38
Original line number Diff line number Diff line
@@ -229,7 +229,7 @@ comment "Do not forget to sign required modules with scripts/sign-file"
	depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL

choice
	prompt "Which hash algorithm should modules be signed with?"
	prompt "Hash algorithm to sign modules"
	depends on MODULE_SIG || IMA_APPRAISE_MODSIG
	help
	  This determines which sort of hashing algorithm will be used during
@@ -239,31 +239,31 @@ choice
	  the signature on that module.

config MODULE_SIG_SHA1
	bool "Sign modules with SHA-1"
	bool "SHA-1"
	select CRYPTO_SHA1

config MODULE_SIG_SHA256
	bool "Sign modules with SHA-256"
	bool "SHA-256"
	select CRYPTO_SHA256

config MODULE_SIG_SHA384
	bool "Sign modules with SHA-384"
	bool "SHA-384"
	select CRYPTO_SHA512

config MODULE_SIG_SHA512
	bool "Sign modules with SHA-512"
	bool "SHA-512"
	select CRYPTO_SHA512

config MODULE_SIG_SHA3_256
	bool "Sign modules with SHA3-256"
	bool "SHA3-256"
	select CRYPTO_SHA3

config MODULE_SIG_SHA3_384
	bool "Sign modules with SHA3-384"
	bool "SHA3-384"
	select CRYPTO_SHA3

config MODULE_SIG_SHA3_512
	bool "Sign modules with SHA3-512"
	bool "SHA3-512"
	select CRYPTO_SHA3

endchoice
@@ -279,64 +279,65 @@ config MODULE_SIG_HASH
	default "sha3-384" if MODULE_SIG_SHA3_384
	default "sha3-512" if MODULE_SIG_SHA3_512

choice
	prompt "Module compression mode"
config MODULE_COMPRESS
	bool "Module compression"
	help
	  This option allows you to choose the algorithm which will be used to
	  compress modules when 'make modules_install' is run. (or, you can
	  choose to not compress modules at all.)

	  External modules will also be compressed in the same way during the
	  installation.

	  For modules inside an initrd or initramfs, it's more efficient to
	  compress the whole initrd or initramfs instead.

	  Enable module compression to reduce on-disk size of module binaries.
	  This is fully compatible with signed modules.

	  Please note that the tool used to load modules needs to support the
	  corresponding algorithm. module-init-tools MAY support gzip, and kmod
	  MAY support gzip, xz and zstd.
	  The tool used to work with modules needs to support the selected
	  compression type. kmod MAY support gzip, xz and zstd. Other tools
	  might have a limited selection of the supported types.

	  Your build system needs to provide the appropriate compression tool
	  to compress the modules.
	  Note that for modules inside an initrd or initramfs, it's more
	  efficient to compress the whole ramdisk instead.

	  If in doubt, select 'None'.
	  If unsure, say N.

config MODULE_COMPRESS_NONE
	bool "None"
choice
	prompt "Module compression type"
	depends on MODULE_COMPRESS
	help
	  Do not compress modules. The installed modules are suffixed
	  with .ko.
	  Choose the supported algorithm for module compression.

config MODULE_COMPRESS_GZIP
	bool "GZIP"
	help
	  Compress modules with GZIP. The installed modules are suffixed
	  with .ko.gz.
	  Support modules compressed with GZIP. The installed modules are
	  suffixed with .ko.gz.

config MODULE_COMPRESS_XZ
	bool "XZ"
	help
	  Compress modules with XZ. The installed modules are suffixed
	  with .ko.xz.
	  Support modules compressed with XZ. The installed modules are
	  suffixed with .ko.xz.

config MODULE_COMPRESS_ZSTD
	bool "ZSTD"
	help
	  Compress modules with ZSTD. The installed modules are suffixed
	  with .ko.zst.
	  Support modules compressed with ZSTD. The installed modules are
	  suffixed with .ko.zst.

endchoice

config MODULE_COMPRESS_ALL
	bool "Automatically compress all modules"
	default y
	depends on MODULE_COMPRESS
	help
	  Compress all modules during 'make modules_install'.

	  Your build system needs to provide the appropriate compression tool
	  for the selected compression type. External modules will also be
	  compressed in the same way during the installation.

config MODULE_DECOMPRESS
	bool "Support in-kernel module decompression"
	depends on MODULE_COMPRESS_GZIP || MODULE_COMPRESS_XZ || MODULE_COMPRESS_ZSTD
	depends on MODULE_COMPRESS
	select ZLIB_INFLATE if MODULE_COMPRESS_GZIP
	select XZ_DEC if MODULE_COMPRESS_XZ
	select ZSTD_DECOMPRESS if MODULE_COMPRESS_ZSTD
	help

	  Support for decompressing kernel modules by the kernel itself
	  instead of relying on userspace to perform this task. Useful when
	  load pinning security policy is enabled.
+4 −14
Original line number Diff line number Diff line
@@ -12,19 +12,9 @@
void kmemleak_load_module(const struct module *mod,
			  const struct load_info *info)
{
	unsigned int i;

	/* only scan the sections containing data */
	kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL);

	for (i = 1; i < info->hdr->e_shnum; i++) {
		/* Scan all writable sections that's not executable */
		if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) ||
		    !(info->sechdrs[i].sh_flags & SHF_WRITE) ||
		    (info->sechdrs[i].sh_flags & SHF_EXECINSTR))
			continue;

		kmemleak_scan_area((void *)info->sechdrs[i].sh_addr,
				   info->sechdrs[i].sh_size, GFP_KERNEL);
	/* only scan writable, non-executable sections */
	for_each_mod_mem_type(type) {
		if (type != MOD_DATA && type != MOD_INIT_DATA)
			kmemleak_no_scan(mod->mem[type].base);
	}
}
+42 −21
Original line number Diff line number Diff line
@@ -69,12 +69,13 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
	kfree(sect_attrs);
}

static void add_sect_attrs(struct module *mod, const struct load_info *info)
static int add_sect_attrs(struct module *mod, const struct load_info *info)
{
	unsigned int nloaded = 0, i, size[2];
	struct module_sect_attrs *sect_attrs;
	struct module_sect_attr *sattr;
	struct bin_attribute **gattr;
	int ret;

	/* Count loaded sections and allocate structures */
	for (i = 0; i < info->hdr->e_shnum; i++)
@@ -85,7 +86,7 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
	size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
	sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
	if (!sect_attrs)
		return;
		return -ENOMEM;

	/* Setup section attributes. */
	sect_attrs->grp.name = "sections";
@@ -103,8 +104,10 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
		sattr->address = sec->sh_addr;
		sattr->battr.attr.name =
			kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
		if (!sattr->battr.attr.name)
		if (!sattr->battr.attr.name) {
			ret = -ENOMEM;
			goto out;
		}
		sect_attrs->nsections++;
		sattr->battr.read = module_sect_read;
		sattr->battr.size = MODULE_SECT_READ_SIZE;
@@ -113,13 +116,15 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
	}
	*gattr = NULL;

	if (sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp))
	ret = sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp);
	if (ret)
		goto out;

	mod->sect_attrs = sect_attrs;
	return;
	return 0;
out:
	free_sect_attrs(sect_attrs);
	return ret;
}

static void remove_sect_attrs(struct module *mod)
@@ -158,15 +163,12 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
	kfree(notes_attrs);
}

static void add_notes_attrs(struct module *mod, const struct load_info *info)
static int add_notes_attrs(struct module *mod, const struct load_info *info)
{
	unsigned int notes, loaded, i;
	struct module_notes_attrs *notes_attrs;
	struct bin_attribute *nattr;

	/* failed to create section attributes, so can't create notes */
	if (!mod->sect_attrs)
		return;
	int ret;

	/* Count notes sections and allocate structures.  */
	notes = 0;
@@ -176,12 +178,12 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)
			++notes;

	if (notes == 0)
		return;
		return 0;

	notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes),
			      GFP_KERNEL);
	if (!notes_attrs)
		return;
		return -ENOMEM;

	notes_attrs->notes = notes;
	nattr = &notes_attrs->attrs[0];
@@ -201,19 +203,23 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)
	}

	notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
	if (!notes_attrs->dir)
	if (!notes_attrs->dir) {
		ret = -ENOMEM;
		goto out;
	}

	for (i = 0; i < notes; ++i)
		if (sysfs_create_bin_file(notes_attrs->dir,
					  &notes_attrs->attrs[i]))
	for (i = 0; i < notes; ++i) {
		ret = sysfs_create_bin_file(notes_attrs->dir, &notes_attrs->attrs[i]);
		if (ret)
			goto out;
	}

	mod->notes_attrs = notes_attrs;
	return;
	return 0;

out:
	free_notes_attrs(notes_attrs, i);
	return ret;
}

static void remove_notes_attrs(struct module *mod)
@@ -223,9 +229,15 @@ static void remove_notes_attrs(struct module *mod)
}

#else /* !CONFIG_KALLSYMS */
static inline void add_sect_attrs(struct module *mod, const struct load_info *info) { }
static inline int add_sect_attrs(struct module *mod, const struct load_info *info)
{
	return 0;
}
static inline void remove_sect_attrs(struct module *mod) { }
static inline void add_notes_attrs(struct module *mod, const struct load_info *info) { }
static inline int add_notes_attrs(struct module *mod, const struct load_info *info)
{
	return 0;
}
static inline void remove_notes_attrs(struct module *mod) { }
#endif /* CONFIG_KALLSYMS */

@@ -385,11 +397,20 @@ int mod_sysfs_setup(struct module *mod,
	if (err)
		goto out_unreg_modinfo_attrs;

	add_sect_attrs(mod, info);
	add_notes_attrs(mod, info);
	err = add_sect_attrs(mod, info);
	if (err)
		goto out_del_usage_links;

	err = add_notes_attrs(mod, info);
	if (err)
		goto out_unreg_sect_attrs;

	return 0;

out_unreg_sect_attrs:
	remove_sect_attrs(mod);
out_del_usage_links:
	del_usage_links(mod);
out_unreg_modinfo_attrs:
	module_remove_modinfo_attrs(mod, -1);
out_unreg_param:
+2 −0
Original line number Diff line number Diff line
@@ -53,9 +53,11 @@ $(foreach x, % :, $(if $(findstring $x, $(dst)), \
	$(error module installation path cannot contain '$x')))

suffix-y				:=
ifdef CONFIG_MODULE_COMPRESS_ALL
suffix-$(CONFIG_MODULE_COMPRESS_GZIP)	:= .gz
suffix-$(CONFIG_MODULE_COMPRESS_XZ)	:= .xz
suffix-$(CONFIG_MODULE_COMPRESS_ZSTD)	:= .zst
endif

modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules))
install-$(CONFIG_MODULES) += $(modules)