[Devel] [PATCH RHEL7 COMMIT] mm: mmap use correct file when updating bean counter

Konstantin Khorenko khorenko at virtuozzo.com
Thu May 18 21:28:04 MSK 2023


The commit is pushed to "branch-rh7-3.10.0-1160.88.1.vz7.195.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.88.1.vz7.195.3
------>
commit 4c1242d054e1f841954b359607b1851fa4c9e486
Author: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
Date:   Fri May 12 16:25:12 2023 +0300

    mm: mmap use correct file when updating bean counter
    
    in mmap_region when updating beancounters after calling
    ->mmap(...) which can change flags and file, but only when the flags
    change counters are updates. When updating on change of flags it is
    possible that the file pointer change too but it is not used and instead
    the cached file ptr is used.
    
    Update counter when file changes too and use correct file
    when updating.
    
    Also avoid double fput on error - when changing file ->mmap
    fputs vma->vm_file and sets it to a new file.
    But the file pointer is not updated on error and the cached
    file ptr can be fput second time - in that case the result is
    crash at unlink_file_vma (maybe related to PSBM-146968).
    
    https://jira.vzint.dev/browse/PSBM-147170
    Signed-off-by: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
---
 mm/mmap.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/mm/mmap.c b/mm/mmap.c
index e8628d0d89ca..dcb06921c668 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1827,15 +1827,17 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
 		error = file->f_op->mmap(file, vma);
 		if (error)
 			goto unmap_and_free_vma;
-		if (vm_flags != vma->vm_flags) {
+		if (vm_flags != vma->vm_flags || file != vma->vm_file) {
 		/*
-		 * ->vm_flags has been changed in f_op->mmap method.
+		 * ->vm_flags or file has been changed in f_op->mmap method.
 		 * We have to recharge ub memory.
 		 */
 			ub_memory_uncharge(mm, len, vm_flags, file);
-			if (ub_memory_charge(mm, len, vma->vm_flags, file, UB_HARD)) {
+			if (ub_memory_charge(mm, len, vma->vm_flags,
+					     vma->vm_file, UB_HARD)) {
 				ub_charged = 0;
 				error = -ENOMEM;
+				file = vma->vm_file;
 				goto unmap_and_free_vma;
 			}
 		}


More information about the Devel mailing list