On Wed, Oct 23, 2024 at 11:24:40AM +0200, Vlastimil Babka wrote: > On 10/22/24 22:40, Lorenzo Stoakes wrote: > > Incorrect invocation of VMA callbacks when the VMA is no longer in a > > consistent state is bug prone and risky to perform. > > > > With regards to the important vm_ops->close() callback We have gone to > > great lengths to try to track whether or not we ought to close VMAs. > > > > Rather than doing so and risking making a mistake somewhere, instead > > unconditionally close and reset vma->vm_ops to an empty dummy operations > > set with a NULL .close operator. > > > > We introduce a new function to do so - vma_close() - and simplify existing > > vms logic which tracked whether we needed to close or not. > > > > This simplifies the logic, avoids incorrect double-calling of the .close() > > callback and allows us to update error paths to simply call vma_close() > > unconditionally - making VMA closure idempotent. > > > > Reported-by: Jann Horn <jannh@xxxxxxxxxx> > > Fixes: deb0f6562884 ("mm/mmap: undo ->mmap() when arch_validate_flags() fails") > > Cc: stable <stable@xxxxxxxxxx> > > Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@xxxxxxxxxx> > > Nice simplification. Nit below. Thanks! > > Reviewed-by: Vlastimil Babka <vbabka@xxxxxxx> > > > +/* > > + * Unconditionally close the VMA if it has a close hook and prevent hooks from > > + * being invoked after close. VMA hooks are mutated. > > + */ > > +static inline void vma_close(struct vm_area_struct *vma) > > +{ > > + if (vma->vm_ops && vma->vm_ops->close) { > > + vma->vm_ops->close(vma); > > + > > + /* > > + * The mapping is in an inconsistent state, and no further hooks > > + * may be invoked upon it. > > + */ > > + vma->vm_ops = &vma_dummy_vm_ops; > > + } > > Nit: if we want to "prevent hooks" as in "any hooks" then we should be > replacing existing vm_ops even if it has no close hook? If it's enough to > prevent further close() hooks (as commit log suggests) then the > implementation is fine but the comment might be misleading. We prevent hooks _after close_, if it has no close, then no, but I'll update the comment to be crystal clear. > > > +} > > + > > #ifdef CONFIG_MMU > > > > /* Flags for folio_pte_batch(). */ > > diff --git a/mm/mmap.c b/mm/mmap.c > > index 10f4ccaf491b..d55c58e99a54 100644