@@ -1809,6 +1809,7 @@ unsigned long mmap_region(struct file *f*/vma->vm_file=get_file(file);error=call_mmap(file,vma);+file=vma->vm_file;if(error)gotounmap_and_free_vma;
@@ -1870,7 +1871,6 @@ unsigned long mmap_region(struct file *fif(vm_flags&VM_DENYWRITE)allow_write_access(file);}-file=vma->vm_file;out:perf_event_mmap(vma);---a/mm/util.c+++b/mm/util.c
@@ -314,12 +314,48 @@ int vma_is_stack_for_current(struct vm_a/**Changebackingfile,onlyvalidtouseduringinitialVMAsetup.*/-voidvma_set_file(structvm_area_struct*vma,structfile*file)+intvma_set_file_checkwrite(structvm_area_struct*vma,structfile*file){+vm_flags_tvm_flags=vma->vm_flags;+interr=0;+/* Changing an anonymous vma with this is illegal */get_file(file);++/* Get temporary denial counts on replacement */+if(vm_flags&VM_DENYWRITE){+err=deny_write_access(file);+if(err)+gotoout_put;+}+if(vm_flags&VM_SHARED){+err=mapping_map_writable(file->f_mapping);+if(err)+gotoout_allow;+}+swap(vma->vm_file,file);++/* Undo temporary denial counts on replaced */+if(vm_flags&VM_SHARED)+mapping_unmap_writable(file->f_mapping);+out_allow:+if(vm_flags&VM_DENYWRITE)+allow_write_access(file);+out_put:fput(file);+returnerr;+}+EXPORT_SYMBOL(vma_set_file_checkwrite);++/*+*Changebackingfile,onlyvalidtouseduringinitialVMAsetup.+*/+voidvma_set_file(structvm_area_struct*vma,structfile*file)+{+interr=vma_set_file_checkwrite(vma,file);++WARN_ON_ONCE(err);}EXPORT_SYMBOL(vma_set_file);
From: Christian König <christian.koenig@amd.com> Date: 2021-06-22 12:43:52
Am 22.06.21 um 14:30 schrieb Miklos Szeredi:
Overlayfs did not honor positive i_writecount on realfile for VM_DENYWRITE
mappings. Similarly negative i_mmap_writable counts were ignored for
VM_SHARED mappings.
Fix by making vma_set_file() switch the temporary counts obtained and
released by mmap_region().
Mhm, I don't fully understand the background but that looks like
something specific to overlayfs to me.
So why are you changing the common helper?
Thanks,
Christian.
On Tue, 22 Jun 2021 at 14:43, Christian König [off-list ref] wrote:
Am 22.06.21 um 14:30 schrieb Miklos Szeredi:
quoted
Overlayfs did not honor positive i_writecount on realfile for VM_DENYWRITE
mappings. Similarly negative i_mmap_writable counts were ignored for
VM_SHARED mappings.
Fix by making vma_set_file() switch the temporary counts obtained and
released by mmap_region().
Mhm, I don't fully understand the background but that looks like
something specific to overlayfs to me.
So why are you changing the common helper?
Need to hold the temporary counts until the final ones are obtained in
vma_link(), which is out of overlayfs' scope.
Thanks,
Miklos
From: Christian König <christian.koenig@amd.com> Date: 2021-06-23 11:41:10
Am 22.06.21 um 17:10 schrieb Miklos Szeredi:
On Tue, 22 Jun 2021 at 14:43, Christian König [off-list ref] wrote:
quoted
Am 22.06.21 um 14:30 schrieb Miklos Szeredi:
quoted
Overlayfs did not honor positive i_writecount on realfile for VM_DENYWRITE
mappings. Similarly negative i_mmap_writable counts were ignored for
VM_SHARED mappings.
Fix by making vma_set_file() switch the temporary counts obtained and
released by mmap_region().
Mhm, I don't fully understand the background but that looks like
something specific to overlayfs to me.
So why are you changing the common helper?
Need to hold the temporary counts until the final ones are obtained in
vma_link(), which is out of overlayfs' scope.
Ah! So basically we need to move the denial counts which mmap_region()
added to the original file to the new one as well. That's indeed a
rather good point.
Can you rather change the vma_set_file() function to return the error
and add a __must_check?
I can take care fixing the users in DMA-buf and DRM subsystem.
Thanks,
Christian.
On Wed, Jun 23, 2021 at 01:41:02PM +0200, Christian König wrote:
Am 22.06.21 um 17:10 schrieb Miklos Szeredi:
quoted
On Tue, 22 Jun 2021 at 14:43, Christian König [off-list ref] wrote:
quoted
Am 22.06.21 um 14:30 schrieb Miklos Szeredi:
quoted
Overlayfs did not honor positive i_writecount on realfile for VM_DENYWRITE
mappings. Similarly negative i_mmap_writable counts were ignored for
VM_SHARED mappings.
Fix by making vma_set_file() switch the temporary counts obtained and
released by mmap_region().
Mhm, I don't fully understand the background but that looks like
something specific to overlayfs to me.
So why are you changing the common helper?
Need to hold the temporary counts until the final ones are obtained in
vma_link(), which is out of overlayfs' scope.
Ah! So basically we need to move the denial counts which mmap_region() added
to the original file to the new one as well. That's indeed a rather good
point.
Can you rather change the vma_set_file() function to return the error and
add a __must_check?
I can take care fixing the users in DMA-buf and DRM subsystem.
Okay, but changing to __must_check has to be the last step to avoid compile
errors. This v2 is with __must_check commented out.
Thanks,
Miklos
---
From: Miklos Szeredi <redacted>
Subject: [PATCH v2] ovl: fix mmap denywrite
Overlayfs did not honor positive i_writecount on realfile for VM_DENYWRITE
mappings. Similarly negative i_mmap_writable counts were ignored for
VM_SHARED mappings.
Fix by making vma_set_file() switch the temporary counts obtained and
released by mmap_region().
Reported-by: Chengguang Xu <redacted>
Signed-off-by: Miklos Szeredi <redacted>
---
fs/overlayfs/file.c | 4 +++-
include/linux/mm.h | 2 +-
mm/mmap.c | 2 +-
mm/util.c | 27 ++++++++++++++++++++++++++-
4 files changed, 31 insertions(+), 4 deletions(-)
@@ -1807,6 +1807,7 @@ unsigned long mmap_region(struct file *f*/vma->vm_file=get_file(file);error=call_mmap(file,vma);+file=vma->vm_file;if(error)gotounmap_and_free_vma;
@@ -1868,7 +1869,6 @@ unsigned long mmap_region(struct file *fif(vm_flags&VM_DENYWRITE)allow_write_access(file);}-file=vma->vm_file;out:perf_event_mmap(vma);---a/mm/util.c+++b/mm/util.c
@@ -314,12 +314,37 @@ int vma_is_stack_for_current(struct vm_a/**Changebackingfile,onlyvalidtouseduringinitialVMAsetup.*/-voidvma_set_file(structvm_area_struct*vma,structfile*file)+intvma_set_file(structvm_area_struct*vma,structfile*file){+vm_flags_tvm_flags=vma->vm_flags;+interr=0;+/* Changing an anonymous vma with this is illegal */get_file(file);++/* Get temporary denial counts on replacement */+if(vm_flags&VM_DENYWRITE){+err=deny_write_access(file);+if(err)+gotoout_put;+}+if(vm_flags&VM_SHARED){+err=mapping_map_writable(file->f_mapping);+if(err)+gotoout_allow;+}+swap(vma->vm_file,file);++/* Undo temporary denial counts on replaced */+if(vm_flags&VM_SHARED)+mapping_unmap_writable(file->f_mapping);+out_allow:+if(vm_flags&VM_DENYWRITE)+allow_write_access(file);+out_put:fput(file);+returnerr;}EXPORT_SYMBOL(vma_set_file);
From: Christian König <christian.koenig@amd.com> Date: 2021-07-12 11:18:23
Am 09.07.21 um 15:48 schrieb Miklos Szeredi:
On Wed, Jun 23, 2021 at 01:41:02PM +0200, Christian König wrote:
quoted
Am 22.06.21 um 17:10 schrieb Miklos Szeredi:
quoted
On Tue, 22 Jun 2021 at 14:43, Christian König [off-list ref] wrote:
quoted
Am 22.06.21 um 14:30 schrieb Miklos Szeredi:
quoted
Overlayfs did not honor positive i_writecount on realfile for VM_DENYWRITE
mappings. Similarly negative i_mmap_writable counts were ignored for
VM_SHARED mappings.
Fix by making vma_set_file() switch the temporary counts obtained and
released by mmap_region().
Mhm, I don't fully understand the background but that looks like
something specific to overlayfs to me.
So why are you changing the common helper?
Need to hold the temporary counts until the final ones are obtained in
vma_link(), which is out of overlayfs' scope.
Ah! So basically we need to move the denial counts which mmap_region() added
to the original file to the new one as well. That's indeed a rather good
point.
Can you rather change the vma_set_file() function to return the error and
add a __must_check?
I can take care fixing the users in DMA-buf and DRM subsystem.
Okay, but changing to __must_check has to be the last step to avoid compile
errors. This v2 is with __must_check commented out.
Good point. Please ping me whenever that is upstream and I will take
care of fixing all the callers in the DRM subsystem and DMA-buf
Thanks,
Miklos
---
From: Miklos Szeredi <redacted>
Subject: [PATCH v2] ovl: fix mmap denywrite
Overlayfs did not honor positive i_writecount on realfile for VM_DENYWRITE
mappings. Similarly negative i_mmap_writable counts were ignored for
VM_SHARED mappings.
Fix by making vma_set_file() switch the temporary counts obtained and
released by mmap_region().
Reported-by: Chengguang Xu <redacted>
Signed-off-by: Miklos Szeredi <redacted>
Reviewed-by: Christian König <christian.koenig@amd.com>
Regards,
Christian.
@@ -1807,6 +1807,7 @@ unsigned long mmap_region(struct file *f*/vma->vm_file=get_file(file);error=call_mmap(file,vma);+file=vma->vm_file;if(error)gotounmap_and_free_vma;
@@ -1868,7 +1869,6 @@ unsigned long mmap_region(struct file *fif(vm_flags&VM_DENYWRITE)allow_write_access(file);}-file=vma->vm_file;out:perf_event_mmap(vma);---a/mm/util.c+++b/mm/util.c
@@ -314,12 +314,37 @@ int vma_is_stack_for_current(struct vm_a/**Changebackingfile,onlyvalidtouseduringinitialVMAsetup.*/-voidvma_set_file(structvm_area_struct*vma,structfile*file)+intvma_set_file(structvm_area_struct*vma,structfile*file){+vm_flags_tvm_flags=vma->vm_flags;+interr=0;+/* Changing an anonymous vma with this is illegal */get_file(file);++/* Get temporary denial counts on replacement */+if(vm_flags&VM_DENYWRITE){+err=deny_write_access(file);+if(err)+gotoout_put;+}+if(vm_flags&VM_SHARED){+err=mapping_map_writable(file->f_mapping);+if(err)+gotoout_allow;+}+swap(vma->vm_file,file);++/* Undo temporary denial counts on replaced */+if(vm_flags&VM_SHARED)+mapping_unmap_writable(file->f_mapping);+out_allow:+if(vm_flags&VM_DENYWRITE)+allow_write_access(file);+out_put:fput(file);+returnerr;}EXPORT_SYMBOL(vma_set_file);