On 09.08.22 22:00, Linus Torvalds wrote: > On Mon, Aug 8, 2022 at 12:32 AM David Hildenbrand <david@xxxxxxxxxx> wrote: >> > > So I've read through the patch several times, and it seems fine, but > this function (and the pmd version of it) just read oddly to me. > >> +static inline bool can_follow_write_pte(pte_t pte, struct page *page, >> + struct vm_area_struct *vma, >> + unsigned int flags) >> +{ >> + if (pte_write(pte)) >> + return true; >> + if (!(flags & FOLL_FORCE)) >> + return false; >> + >> + /* >> + * See check_vma_flags(): only COW mappings need that special >> + * "force" handling when they lack VM_WRITE. >> + */ >> + if (vma->vm_flags & VM_WRITE) >> + return false; >> + VM_BUG_ON(!is_cow_mapping(vma->vm_flags)); > > So apart from the VM_BUG_ON(), this code just looks really strange - > even despite the comment. Just conceptually, the whole "if it's > writable, return that you cannot follow it for a write" just looks so > very very strange. > > That doesn't make the code _wrong_, but considering how many times > this has had subtle bugs, let's not write code that looks strange. > > So I would suggest that to protect against future bugs, we try to make > it be fairly clear and straightforward, and maybe even a bit overly > protective. > > For example, let's kill the "shared mapping that you don't have write > permissions to" very explicitly and without any subtle code at all. > The vm_flags tests are cheap and easy, and we could very easily just > add some core ones to make any mistakes much less critical. > > Now, making that 'is_cow_mapping()' check explicit at the very top of > this would already go a long way: > > /* FOLL_FORCE for writability only affects COW mappings */ > if (!is_cow_mapping(vma->vm_flags)) > return false; > > but I'd actually go even further: in this case that "is_cow_mapping()" > helper to some degree actually hides what is going on. > > So I'd actually prefer for that function to be written something like > > /* If the pte is writable, we can write to the page */ > if (pte_write(pte)) > return true; > > /* Maybe FOLL_FORCE is set to override it? */ > if (flags & FOLL_FORCE) > return false; > > /* But FOLL_FORCE has no effect on shared mappings */ > if (vma->vm_flags & MAP_SHARED) > return false; I'd actually rather check for MAP_MAYSHARE here, which is even stronger. Thoughts? -- Thanks, David / dhildenb