* Re: [PATCH] hold cow while breaking
[not found] <Pine.LNX.4.21.0107291404410.897-100000@localhost.localdomain>
@ 2001-07-29 15:30 ` Linus Torvalds
2001-07-29 20:16 ` Hugh Dickins
0 siblings, 1 reply; 5+ messages in thread
From: Linus Torvalds @ 2001-07-29 15:30 UTC (permalink / raw)
To: Hugh Dickins; +Cc: Ingo Molnar, linux-kernel
On Sun, 29 Jul 2001, Hugh Dickins wrote:
>
> do_wp_page() COW breaking is now very slightly unsafe. Please don't
> ask me to provide a test case! but the pte_same() check after regetting
> page_table_lock is not quite enough to guarantee that the old_page was
> not reaped, reused for something else, copy_cow_paged while containing
> that other data, freed and then reused for precisely its original pte.
Oh, but it is.
We do hold the MM semaphore over the whole sequence, so there's no way the
page table entry can be replaced by anything else than a non-present one
(ie vmscan can swap it out, but nothing can swap it in because of the
lock).
So yes, we may copy data that is "garbage", but re-testing the page table
will make sure that if it was garbage we will never use it.
Linus
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] hold cow while breaking
2001-07-29 15:30 ` [PATCH] hold cow while breaking Linus Torvalds
@ 2001-07-29 20:16 ` Hugh Dickins
2001-07-29 20:52 ` Linus Torvalds
0 siblings, 1 reply; 5+ messages in thread
From: Hugh Dickins @ 2001-07-29 20:16 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel
On Sun, 29 Jul 2001, Linus Torvalds wrote:
> On Sun, 29 Jul 2001, Hugh Dickins wrote:
> >
> > do_wp_page() COW breaking is now very slightly unsafe. Please don't
> > ask me to provide a test case! but the pte_same() check after regetting
> > page_table_lock is not quite enough to guarantee that the old_page was
> > not reaped, reused for something else, copy_cow_paged while containing
> > that other data, freed and then reused for precisely its original pte.
>
> Oh, but it is.
>
> We do hold the MM semaphore over the whole sequence, so there's no way the
> page table entry can be replaced by anything else than a non-present one
> (ie vmscan can swap it out, but nothing can swap it in because of the
> lock).
Sorry for being dense, but I still don't get it. I thought the
down_read on mmap_sem is permitting concurrent faults by other users
of the address space (but excluding structural changes to the address
space)? and we haven't locked the page itself, and we've temporarily
dropped the page_table_lock. I just don't see what lock prevents the
page from being refaulted in.
Hugh
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] hold cow while breaking
2001-07-29 20:16 ` Hugh Dickins
@ 2001-07-29 20:52 ` Linus Torvalds
2001-07-29 21:20 ` Hugh Dickins
2001-07-30 5:04 ` Linus Torvalds
0 siblings, 2 replies; 5+ messages in thread
From: Linus Torvalds @ 2001-07-29 20:52 UTC (permalink / raw)
To: Hugh Dickins; +Cc: Ingo Molnar, linux-kernel
On Sun, 29 Jul 2001, Hugh Dickins wrote:
>
> Sorry for being dense, but I still don't get it. I thought the
> down_read on mmap_sem is permitting concurrent faults by other users
> of the address space (but excluding structural changes to the address
> space)? and we haven't locked the page itself, and we've temporarily
> dropped the page_table_lock. I just don't see what lock prevents the
> page from being refaulted in.
Ehh, you're right. But you're still wrong, I think.
Because we hold the mm semaphore, nobody can change the mapping on us.
Which means that even if we first page somthing out and page something
else in to the same page, that "something else" has to be the same thing.
See?
Linus
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] hold cow while breaking
2001-07-29 20:52 ` Linus Torvalds
@ 2001-07-29 21:20 ` Hugh Dickins
2001-07-30 5:04 ` Linus Torvalds
1 sibling, 0 replies; 5+ messages in thread
From: Hugh Dickins @ 2001-07-29 21:20 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel
On Sun, 29 Jul 2001, Linus Torvalds wrote:
> On Sun, 29 Jul 2001, Hugh Dickins wrote:
> >
> > Sorry for being dense, but I still don't get it. I thought the
> > down_read on mmap_sem is permitting concurrent faults by other users
> > of the address space (but excluding structural changes to the address
> > space)? and we haven't locked the page itself, and we've temporarily
> > dropped the page_table_lock. I just don't see what lock prevents the
> > page from being refaulted in.
>
> Ehh, you're right. But you're still wrong, I think.
>
> Because we hold the mm semaphore, nobody can change the mapping on us.
>
> Which means that even if we first page somthing out and page something
> else in to the same page, that "something else" has to be the same thing.
> See?
Sure, I agree with you on that, but it doesn't let us off the hook.
This isn't necessarily the first reuse of that page: after paging it
out and freeing it, it may have got allocated to some other purpose
and freed again, and then reassigned to the original use. And while
it held the data from that intermediate use, we may have done the
copy_cow_page from old_page to new_page, and now we come along and
substitute this corrupt new_page for the good old_page.
Hugh
--- linux-2.4.8-pre2/mm/memory.c Sun Jul 29 08:10:42 2001
+++ linux/mm/memory.c Sun Jul 29 13:12:20 2001
@@ -862,8 +862,8 @@
/*
* We hold the mm semaphore for reading and vma->vm_mm->page_table_lock
*/
-static inline void break_cow(struct vm_area_struct * vma, struct page * old_page, struct page * new_page, unsigned long address,
- pte_t *page_table)
+static inline void break_cow(struct vm_area_struct * vma, struct page * new_page,
+ unsigned long address, pte_t *page_table)
{
flush_page_to_ram(new_page);
flush_cache_page(vma, address);
@@ -935,12 +935,15 @@
/*
* Ok, we need to copy. Oh, well..
*/
+ if (!PageReserved(old_page))
+ page_cache_get(old_page);
spin_unlock(&mm->page_table_lock);
new_page = alloc_page(GFP_HIGHUSER);
if (!new_page)
goto no_mem;
copy_cow_page(old_page,new_page,address);
+ page_cache_release(old_page);
/*
* Re-check the pte - we dropped the lock
@@ -949,7 +952,7 @@
if (pte_same(*page_table, pte)) {
if (PageReserved(old_page))
++mm->rss;
- break_cow(vma, old_page, new_page, address, page_table);
+ break_cow(vma, new_page, address, page_table);
/* Free the old page.. */
new_page = old_page;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] hold cow while breaking
2001-07-29 20:52 ` Linus Torvalds
2001-07-29 21:20 ` Hugh Dickins
@ 2001-07-30 5:04 ` Linus Torvalds
1 sibling, 0 replies; 5+ messages in thread
From: Linus Torvalds @ 2001-07-30 5:04 UTC (permalink / raw)
To: hugh, linux-kernel
In article <Pine.LNX.4.21.0107292212330.1139-100000@localhost.localdomain> you write:
>
>Sure, I agree with you on that, but it doesn't let us off the hook.
>This isn't necessarily the first reuse of that page: after paging it
>out and freeing it, it may have got allocated to some other purpose
>and freed again, and then reassigned to the original use.
Ok, you've convinced me. Thanks for showing me the error of my ways.
Fixed.
Linus
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2001-07-30 5:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <Pine.LNX.4.21.0107291404410.897-100000@localhost.localdomain>
2001-07-29 15:30 ` [PATCH] hold cow while breaking Linus Torvalds
2001-07-29 20:16 ` Hugh Dickins
2001-07-29 20:52 ` Linus Torvalds
2001-07-29 21:20 ` Hugh Dickins
2001-07-30 5:04 ` Linus Torvalds
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®