aboutsummaryrefslogtreecommitdiff
path: root/modutils/modutils.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@chromium.org>2016-09-15 12:16:33 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-09-15 12:16:33 +0200
commit3a45b87ac36f60962d6d19c592813e186a9e82e6 (patch)
tree2b3d2249ff2e558bc92a71f91339474a50a0b596 /modutils/modutils.c
parent7fa799a97d381902ab27556918722a6e2d138b9e (diff)
downloadbusybox-3a45b87ac36f60962d6d19c592813e186a9e82e6.tar.gz
modutils: support finit_module syscall
On some systems like Chromium OS, loading modules from non-verified filesystems is denied. Only finit_module is allowed because an open fd is passed which can be checked against a verified location. Change the module loading code to first attempt finit_module and if that fails for whatever reason, fall back to the existing logic. On x86_64, this adds ~80 bytes to modutils/modutils.o and ~68 bytes to modutils/modprobe-small.o. Signed-off-by: Mike Frysinger <vapier@chromium.org> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'modutils/modutils.c')
-rw-r--r--modutils/modutils.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/modutils/modutils.c b/modutils/modutils.c
index 0a056731d..d36caaf68 100644
--- a/modutils/modutils.c
+++ b/modutils/modutils.c
@@ -13,6 +13,9 @@ extern int delete_module(const char *module, unsigned int flags);
#else
# include <sys/syscall.h>
# define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
+# if defined(__NR_finit_module)
+# define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags)
+# endif
# define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
#endif
@@ -212,6 +215,24 @@ int FAST_FUNC bb_init_module(const char *filename, const char *options)
return bb_init_module_24(filename, options);
#endif
+ /*
+ * First we try finit_module if available. Some kernels are configured
+ * to only allow loading of modules off of secure storage (like a read-
+ * only rootfs) which needs the finit_module call. If it fails, we fall
+ * back to normal module loading to support compressed modules.
+ */
+# ifdef __NR_finit_module
+ {
+ int fd = open(filename, O_RDONLY | O_CLOEXEC);
+ if (fd >= 0) {
+ rc = finit_module(fd, options, 0) != 0;
+ close(fd);
+ if (rc == 0)
+ return rc;
+ }
+ }
+# endif
+
image_size = INT_MAX - 4095;
mmaped = 0;
image = try_to_mmap_module(filename, &image_size);