>> Relying on VM_SHARED to detect MAP_PRIVATE vs. MAP_SHARED is >> unfortunately wrong. >> >> If you're curious, take a look at f83a275dbc5c ("mm: account for >> MAP_SHARED mappings using VM_MAYSHARE and not VM_SHARED in hugetlbfs") >> and mmap() code. >> >> Long story short: if the file is read-only, we only have VM_MAYSHARE but >> not VM_SHARED (and consequently also not VM_MAYWRITE). > > To ask in another way: if file is RO but mapped RW (mmap() will have > VM_SHARED cleared but VM_MAYSHARE set), then if we check VM_MAYSHARE here > won't we grant write bit errornously while we shouldn't? As the user > doesn't really have write permission to the file. Thus the VM_WRITE check. :) I wonder if we should just do it cleanly and introduce the maybe_mkwrite semantics here as well. Then there is no need for additional VM_WRITE checks and hugetlb will work just like !hugetlb. Thoughts? > >> >>> >>>> + if (unshare) >>>> + return 0; >>> >>> Curious when will this happen especially if we switch to VM_SHARED above. >>> Shouldn't "unshare" not happen at all on a shared region? >> >> FAULT_FLAG_UNSHARE is documented to behave like: >> >> "FAULT_FLAG_UNSHARE is ignored and treated like an ordinary read fault >> when no existing R/O-mapped anonymous page is encountered." >> >> It should currently not happen. Focus on should ;) > > OK. :) > > Then does it also mean that it should be better to turn into > WARN_ON_ONCE()? It's just that it looks like a valid path if without it. Well, it should work (and we handle the !hugetlb path) like that as well. So I'd want to avoid WARN_ON_ONCE() at least for that check. > >> >>> >>>> + if (WARN_ON_ONCE(!(vma->vm_flags & VM_WRITE))) >>>> + return VM_FAULT_SIGSEGV; >>> >>> I had a feeling that you just want to double check we have write >>> permission, but IIUC this should be checked far earlier or we'll have >>> problem. No strong opinion if so, but I'd suggest dropping this one, >>> otherwise we could add tons of WARN_ON_ONCE() in anywhere in the page fault >>> stack and they mostly won't trigger at all. >> >> Not quite. We usually (!hugetlb) have maybe_mkwrite() all over the >> place. This is just an indication that we don't have maybe semantics >> here. But as we also don't have it for hugetlb anon code below, maybe I >> can just drop it. (or check it for both call paths) > > Hmm, this reminded me to wonder how hugetlb handles FOLL_FORCE|FOLL_WRITE > on RO regions. > > Maybe that check is needed, but however instead of warning and sigbus, we > need to handle it? We don't support FOLL_FORCE|FOLL_WRITE for hugetlb, but if we would, we'd need the maybe_mkwrite semantics. Fortunately I detest private hugetlb mappings / anon hugetlb pages and couldn't care less about debug access until it's actually a problem for someone :) -- Thanks, David / dhildenb