* Kees Cook <kees@xxxxxxxxxx> [240626 12:32]: > On Tue, Jun 25, 2024 at 03:11:44PM -0400, Liam R. Howlett wrote: > > From: "Liam R. Howlett" <Liam.Howlett@xxxxxxxxxx> > > > > Change from nr_pages variable to vms.nr_accounted for the charged pages > > calculation. This is necessary for a future patch. > > > > This also avoids checking security_vm_enough_memory_mm() if the amount > > of memory won't change. > > Is there a reason for making this change? (I.e. why not leave off the > "charged" test?) Before, the munmap() completed prior to mmap()'ing the MAP_FIXED vma. If we don't remove the nr_accounted from the charged, we risk hitting the maximum limit. > > Looking at the callbacks in the LSM, only capabilities and SELinux are > hooking this, and both are checking whether a process has elevated privs > and are ignoring the "pages" argument entirely, so I'm not sure it's > safe to change the logic for whether to make the call based on an unused > argument (i.e. the LSM may want to _always_ know about this). On the > other hand, it looks like it's purely an accounting issue, and if the > page count didn't change, there's no reason to bother calling into all > this to make no changes to the accounting. I didn't see any reason not to avoid the call, but your statement is valid. I didn't see anything looking at the callbacks that would have issue with skipping it - but I'd like to hear what LSM has to say. I don't have any objections to removing the extra check, if anyone thinks it could be an issue. > > I've added the LSM list to CC... Thank you, and thanks for looking at this. > > -Kees > > > > > Signed-off-by: Liam R. Howlett <Liam.Howlett@xxxxxxxxxx> > > Cc: Kees Cook <kees@xxxxxxxxxx> > > --- > > mm/mmap.c | 6 ++++-- > > 1 file changed, 4 insertions(+), 2 deletions(-) > > > > diff --git a/mm/mmap.c b/mm/mmap.c > > index f3edabf83975..adb0bb5ea344 100644 > > --- a/mm/mmap.c > > +++ b/mm/mmap.c > > @@ -2970,6 +2970,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, > > } else { > > /* Minimal setup of vms */ > > vms.nr_pages = 0; > > + vms.nr_accounted = 0; > > next = vma_next(&vmi); > > prev = vma_prev(&vmi); > > if (prev) > > @@ -2981,9 +2982,10 @@ unsigned long mmap_region(struct file *file, unsigned long addr, > > */ > > if (accountable_mapping(file, vm_flags)) { > > charged = pglen; > > - charged -= nr_accounted; > > - if (security_vm_enough_memory_mm(mm, charged)) > > + charged -= vms.nr_accounted; > > + if (charged && security_vm_enough_memory_mm(mm, charged)) > > goto abort_munmap; > > + > > vms.nr_accounted = 0; > > vm_flags |= VM_ACCOUNT; > > } > > -- > > 2.43.0 > > > > -- > Kees Cook