From f97bf21ad0463b413cf8f848bc7c8a037806f620 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Wed, 6 Nov 2019 09:38:57 -0600 Subject: [PATCH 1/2] UBUNTU: SAUCE: shiftfs: Restore vm_file value when lower fs mmap fails BugLink: https://bugs.launchpad.net/bugs/1850994 shiftfs_mmap() overwrites vma->vm_file before calling the lower filesystem mmap but does not restore the original value on failure. This means it is giving a pointer to the lower fs file back to the caller with no reference, which is a bad practice. However, it does not lead to any issues with upstream kernels as no caller accesses vma->vm_file after call_mmap(). With the aufs patches applied the story is different. Whereas mmap_region() previously fput a local variable containing the file it assigned to vm_file, it now calls vma_fput() which will fput vm_file, for which it has no reference, and the reference for the original vm_file is not put. Fix this by restoring vma->vm_file to the original value when the mmap call into the lower fs fails. Reported-by: Jann Horn Signed-off-by: Seth Forshee --- fs/shiftfs.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/shiftfs.c b/fs/shiftfs.c index 55bb32b611f2..57d84479026b 100644 --- a/fs/shiftfs.c +++ b/fs/shiftfs.c @@ -1289,10 +1289,17 @@ static int shiftfs_mmap(struct file *file, struct vm_area_struct *vma) shiftfs_file_accessed(file); - if (ret) - fput(realfile); /* Drop refcount from new vm_file value */ - else - fput(file); /* Drop refcount from previous vm_file value */ + if (ret) { + /* + * Drop refcount from new vm_file value and restore original + * vm_file value + */ + vma->vm_file = file; + fput(realfile); + } else { + /* Drop refcount from previous vm_file value */ + fput(file); + } return ret; } -- 2.20.1