Whamcloud - gitweb
LU-14021 llite: don't touch vma after filemap_fault 58/44558/2
authorAlexander Boyko <alexander.boyko@hpe.com>
Tue, 10 Aug 2021 14:20:42 +0000 (10:20 -0400)
committerOleg Drokin <green@whamcloud.com>
Sat, 11 Sep 2021 06:20:55 +0000 (06:20 +0000)
In case of error filemap_fault unlock mutex vma->vm_mm->mmap_sem,
so touching vma is dangerous, it could be reused or freed.
The patch uses local file variable to skip vma.

HPE-bug-id: LUS-10240
Signed-off-by: Alexander Boyko <alexander.boyko@hpe.com>
Change-Id: I72cd086645061819fab5b8595a880db64cfb9ff7
Reviewed-on: https://review.whamcloud.com/44558
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andrew Perepechko <andrew.perepechko@hpe.com>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/llite_mmap.c

index 8873f70..4600c76 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/file.h>
 
 #define DEBUG_SUBSYSTEM S_LLITE
 
@@ -304,6 +305,8 @@ static vm_fault_t ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf)
 
        result = io->ci_result;
        if (result == 0) {
+               struct file *vm_file = vma->vm_file;
+
                vio = vvp_env_io(env);
                vio->u.fault.ft_vma       = vma;
                vio->u.fault.ft_vmpage    = NULL;
@@ -311,13 +314,15 @@ static vm_fault_t ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf)
                vio->u.fault.ft_flags = 0;
                vio->u.fault.ft_flags_valid = 0;
 
+               get_file(vm_file);
+
                /* May call ll_readpage() */
-               ll_cl_add(vma->vm_file, env, io, LCC_MMAP);
+               ll_cl_add(vm_file, env, io, LCC_MMAP);
 
                result = cl_io_loop(env, io);
 
-               ll_cl_remove(vma->vm_file, env);
-
+               ll_cl_remove(vm_file, env);
+               fput(vm_file);
                /* ft_flags are only valid if we reached
                 * the call to filemap_fault */
                if (vio->u.fault.ft_flags_valid)