Skip to content

Commit 763978c

Browse files
committed
Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux
Pull module updates from Luis Chamberlain: "The biggest change here is in-kernel support for module decompression. This change is being made to help support LSMs like LoadPin as otherwise it loses link between the source of kernel module on the disk and binary blob that is being loaded into the kernel. kmod decompression is still done by userspace even with this is done, both because there are no measurable gains in not doing so and as it adds a secondary extra check for validating the module before loading it into the kernel. The rest of the changes are minor, the only other change worth mentionin there is Jessica Yu is now bowing out of maintenance of modules as she's taking a break from work. While there were other changes posted for modules, those have not yet received much review of testing so I'm not yet comfortable in merging any of those changes yet." * 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux: module: fix signature check failures when using in-kernel decompression kernel: Fix spelling mistake "compresser" -> "compressor" MAINTAINERS: add mailing lists for kmod and modules module.h: allow #define strings to work with MODULE_IMPORT_NS module: add in-kernel support for decompressing MAINTAINERS: Remove myself as modules maintainer module: Remove outdated comment
2 parents 98f2345 + a97ac8c commit 763978c

File tree

8 files changed

+340
-19
lines changed

8 files changed

+340
-19
lines changed

MAINTAINERS

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10705,6 +10705,7 @@ F: samples/kmemleak/kmemleak-test.c
1070510705
KMOD KERNEL MODULE LOADER - USERMODE HELPER
1070610706
M: Luis Chamberlain <[email protected]>
1070710707
10708+
1070810709
S: Maintained
1070910710
F: include/linux/kmod.h
1071010711
F: kernel/kmod.c
@@ -12994,9 +12995,10 @@ F: drivers/media/dvb-frontends/mn88473*
1299412995

1299512996
MODULE SUPPORT
1299612997
M: Luis Chamberlain <[email protected]>
12997-
M: Jessica Yu <[email protected]>
12998+
12999+
1299813000
S: Maintained
12999-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git modules-next
13001+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git modules-next
1300013002
F: include/linux/module.h
1300113003
F: kernel/module.c
1300213004

include/linux/module.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,8 @@ extern typeof(name) __mod_##type##__##name##_device_table \
290290
* files require multiple MODULE_FIRMWARE() specifiers */
291291
#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
292292

293-
#define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns)
293+
#define _MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns)
294+
#define MODULE_IMPORT_NS(ns) _MODULE_IMPORT_NS(ns)
294295

295296
struct notifier_block;
296297

include/uapi/linux/module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
/* Flags for sys_finit_module: */
66
#define MODULE_INIT_IGNORE_MODVERSIONS 1
77
#define MODULE_INIT_IGNORE_VERMAGIC 2
8+
#define MODULE_INIT_COMPRESSED_FILE 4
89

910
#endif /* _UAPI_LINUX_MODULE_H */

init/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,19 @@ config MODULE_COMPRESS_ZSTD
22782278

22792279
endchoice
22802280

2281+
config MODULE_DECOMPRESS
2282+
bool "Support in-kernel module decompression"
2283+
depends on MODULE_COMPRESS_GZIP || MODULE_COMPRESS_XZ
2284+
select ZLIB_INFLATE if MODULE_COMPRESS_GZIP
2285+
select XZ_DEC if MODULE_COMPRESS_XZ
2286+
help
2287+
2288+
Support for decompressing kernel modules by the kernel itself
2289+
instead of relying on userspace to perform this task. Useful when
2290+
load pinning security policy is enabled.
2291+
2292+
If unsure, say N.
2293+
22812294
config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS
22822295
bool "Allow loading of modules with missing namespace imports"
22832296
help

kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ obj-y += up.o
6767
endif
6868
obj-$(CONFIG_UID16) += uid16.o
6969
obj-$(CONFIG_MODULES) += module.o
70+
obj-$(CONFIG_MODULE_DECOMPRESS) += module_decompress.o
7071
obj-$(CONFIG_MODULE_SIG) += module_signing.o
7172
obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
7273
obj-$(CONFIG_KALLSYMS) += kallsyms.o

kernel/module-internal.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,29 @@ struct load_info {
2222
bool sig_ok;
2323
#ifdef CONFIG_KALLSYMS
2424
unsigned long mod_kallsyms_init_off;
25+
#endif
26+
#ifdef CONFIG_MODULE_DECOMPRESS
27+
struct page **pages;
28+
unsigned int max_pages;
29+
unsigned int used_pages;
2530
#endif
2631
struct {
2732
unsigned int sym, str, mod, vers, info, pcpu;
2833
} index;
2934
};
3035

3136
extern int mod_verify_sig(const void *mod, struct load_info *info);
37+
38+
#ifdef CONFIG_MODULE_DECOMPRESS
39+
int module_decompress(struct load_info *info, const void *buf, size_t size);
40+
void module_decompress_cleanup(struct load_info *info);
41+
#else
42+
static inline int module_decompress(struct load_info *info,
43+
const void *buf, size_t size)
44+
{
45+
return -EOPNOTSUPP;
46+
}
47+
static inline void module_decompress_cleanup(struct load_info *info)
48+
{
49+
}
50+
#endif

kernel/module.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,6 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
958958
}
959959
}
960960

961-
/* Stop the machine so refcounts can't move and disable module. */
962961
ret = try_stop_module(mod, flags, &forced);
963962
if (ret != 0)
964963
goto out;
@@ -2884,12 +2883,13 @@ static int module_sig_check(struct load_info *info, int flags)
28842883
const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
28852884
const char *reason;
28862885
const void *mod = info->hdr;
2887-
2886+
bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS |
2887+
MODULE_INIT_IGNORE_VERMAGIC);
28882888
/*
2889-
* Require flags == 0, as a module with version information
2890-
* removed is no longer the module that was signed
2889+
* Do not allow mangled modules as a module with version information
2890+
* removed is no longer the module that was signed.
28912891
*/
2892-
if (flags == 0 &&
2892+
if (!mangled_module &&
28932893
info->len > markerlen &&
28942894
memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
28952895
/* We truncate the module to discard the signature */
@@ -3174,9 +3174,12 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
31743174
return err;
31753175
}
31763176

3177-
static void free_copy(struct load_info *info)
3177+
static void free_copy(struct load_info *info, int flags)
31783178
{
3179-
vfree(info->hdr);
3179+
if (flags & MODULE_INIT_COMPRESSED_FILE)
3180+
module_decompress_cleanup(info);
3181+
else
3182+
vfree(info->hdr);
31803183
}
31813184

31823185
static int rewrite_section_headers(struct load_info *info, int flags)
@@ -4125,7 +4128,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
41254128
}
41264129

41274130
/* Get rid of temporary copy. */
4128-
free_copy(info);
4131+
free_copy(info, flags);
41294132

41304133
/* Done! */
41314134
trace_module_load(mod);
@@ -4174,7 +4177,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
41744177

41754178
module_deallocate(mod, info);
41764179
free_copy:
4177-
free_copy(info);
4180+
free_copy(info, flags);
41784181
return err;
41794182
}
41804183

@@ -4201,7 +4204,8 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
42014204
SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
42024205
{
42034206
struct load_info info = { };
4204-
void *hdr = NULL;
4207+
void *buf = NULL;
4208+
int len;
42054209
int err;
42064210

42074211
err = may_init_module();
@@ -4211,15 +4215,24 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
42114215
pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags);
42124216

42134217
if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS
4214-
|MODULE_INIT_IGNORE_VERMAGIC))
4218+
|MODULE_INIT_IGNORE_VERMAGIC
4219+
|MODULE_INIT_COMPRESSED_FILE))
42154220
return -EINVAL;
42164221

4217-
err = kernel_read_file_from_fd(fd, 0, &hdr, INT_MAX, NULL,
4222+
len = kernel_read_file_from_fd(fd, 0, &buf, INT_MAX, NULL,
42184223
READING_MODULE);
4219-
if (err < 0)
4220-
return err;
4221-
info.hdr = hdr;
4222-
info.len = err;
4224+
if (len < 0)
4225+
return len;
4226+
4227+
if (flags & MODULE_INIT_COMPRESSED_FILE) {
4228+
err = module_decompress(&info, buf, len);
4229+
vfree(buf); /* compressed data is no longer needed */
4230+
if (err)
4231+
return err;
4232+
} else {
4233+
info.hdr = buf;
4234+
info.len = len;
4235+
}
42234236

42244237
return load_module(&info, uargs, flags);
42254238
}

0 commit comments

Comments
 (0)