]> git.dujemihanovic.xyz Git - linux.git/commitdiff
module: split up 'finit_module()' into init_module_from_file() helper
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 30 May 2023 00:55:13 +0000 (20:55 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Jun 2023 22:46:43 +0000 (15:46 -0700)
This will simplify the next step, where we can then key off the inode to
do one idempotent module load.

Let's do the obvious re-organization in one step, and then the new code
in another.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
kernel/module/main.c

index 4e2cf784cf8ceb66b2bac78b21272145a685f59a..23abfe3e26746a7826e10dc23c4c98aedbe2613a 100644 (file)
@@ -3057,26 +3057,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
        return load_module(&info, uargs, 0);
 }
 
-SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
+static int init_module_from_file(struct file *f, const char __user * uargs, int flags)
 {
        struct load_info info = { };
        void *buf = NULL;
        int len;
-       int err;
-
-       err = may_init_module();
-       if (err)
-               return err;
 
-       pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags);
+       if (!f || !(f->f_mode & FMODE_READ))
+               return -EBADF;
 
-       if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS
-                     |MODULE_INIT_IGNORE_VERMAGIC
-                     |MODULE_INIT_COMPRESSED_FILE))
-               return -EINVAL;
-
-       len = kernel_read_file_from_fd(fd, 0, &buf, INT_MAX, NULL,
-                                      READING_MODULE);
+       len = kernel_read_file(f, 0, &buf, INT_MAX, NULL, READING_MODULE);
        if (len < 0) {
                mod_stat_inc(&failed_kreads);
                mod_stat_add_long(len, &invalid_kread_bytes);
@@ -3084,7 +3074,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
        }
 
        if (flags & MODULE_INIT_COMPRESSED_FILE) {
-               err = module_decompress(&info, buf, len);
+               int err = module_decompress(&info, buf, len);
                vfree(buf); /* compressed data is no longer needed */
                if (err) {
                        mod_stat_inc(&failed_decompress);
@@ -3099,6 +3089,28 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
        return load_module(&info, uargs, flags);
 }
 
+SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
+{
+       int err;
+       struct fd f;
+
+       err = may_init_module();
+       if (err)
+               return err;
+
+       pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags);
+
+       if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS
+                     |MODULE_INIT_IGNORE_VERMAGIC
+                     |MODULE_INIT_COMPRESSED_FILE))
+               return -EINVAL;
+
+       f = fdget(fd);
+       err = init_module_from_file(f.file, uargs, flags);
+       fdput(f);
+       return err;
+}
+
 /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */
 char *module_flags(struct module *mod, char *buf, bool show_state)
 {