Re: [patch 2.6.13-rc4] fix get_user_pages bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Tue, 2 Aug 2005, Hugh Dickins wrote:
> 
> But have I just realized a non-s390 problem with your pte_dirty
> technique?  The ptep_set_wrprotect in fork's copy_one_pte.
> 
> That's specifically write-protecting the pte to force COW, but leaving
> the dirty bit: so now get_user_pages will skip COW-ing it (in all write
> cases, not just the peculiar ptrace force one).

Damn, you're right. We could obviously move the dirty bit from the page
tables to the "struct page" in fork() (that may have other advantages:  
we're scanning the dang thing anyway, after all) to avoid that special
case, but yes, that's nasty.

One of the reasons I _liked_ the pte_dirty() test is that there's the
reverse case: a mapping that used to be writable, and got dirtied (and
COW'ed as necessary), and then was mprotected back, and the new test would
happily write to it _without_ having to do any extra work. Which in that
case is correct.

But yeah, fork() does something special.

In fact, that brings up another race altogether: a thread that does a
fork() at the same time as get_user_pages() will have the exact same
issues. Even with the old code. Simply because we test the permissions on
the page long before we actually do the real access (ie it may be dirty
and writable when we get it, but by the time the write happens, it might
have become COW-shared).

Now, that's probably not worth worrying about, but it's kind of 
interesting.

		Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux