Re: mremap() use is racy

From: Hugh Dickins
Date: Wed Aug 24 2005 - 06:58:28 EST


On Tue, 23 Aug 2005, Linus Torvalds wrote:
> On Tue, 23 Aug 2005, Ulrich Drepper wrote:
> > Linus Torvalds wrote:
> > >
> > > Especially if you use MAP_SHARED, you don't even need to mprotect
> > > anything: you'll get a nice SIGBUS if you ever try to access past
> > > the last page that maps the file.

MAP_PRIVATE also - even if you earlier wrote private data there before
the file got truncated down.

> > If you guarantee this (and test for this) it's fine with me.

Since you're not guaranteeing it, shall I?

The Open Posix Testsuite tests for it: though I haven't run that up,
and its conformance/interfaces/mmap/coverage.txt notes it failed with
glibc-2.3 on Linux-2.6.0-test2.

I have just tested mmap SIGBUS beyond EOF on 2.6.13-rc7,
i386 and x86_64, works correctly as expected.

A quick browse through the others shows all the MMU architectures
appearing to support it: delivering SIGBUS signal if VM_FAULT_SIGBUS
returned by handle_mm_fault.

Except for PA-RISC, which delivers SIGSEGV instead. I imagine that's
wrong, but safer to leave unchanged now - I won't guarantee that one.

> It's how the kernel _should_ work, but very few apps seem to depend on it,
> so no guarantees. I looked over the code, and I think we've lost the
> SIGBUS thing.

It would be easier to follow the route from ->nopage observing offset
beyond EOF through to delivery of the SIGBUS if filemap_nopage were
to say NOPAGE_SIGBUS, rather than the NULL that's defined to be.

Signed-off-by: Hugh Dickins <hugh@xxxxxxxxxxx>

--- 2.6.13-rc7/mm/filemap.c 2005-08-24 11:13:41.000000000 +0100
+++ linux/mm/filemap.c 2005-08-24 12:35:33.000000000 +0100
@@ -1281,7 +1281,7 @@ outside_data_content:
* accessible..
*/
if (area->vm_mm == current->mm)
- return NULL;
+ return NOPAGE_SIGBUS;
/* Fall through to the non-read-ahead case */
no_cached_page:
/*
@@ -1306,7 +1306,7 @@ no_cached_page:
*/
if (error == -ENOMEM)
return NOPAGE_OOM;
- return NULL;
+ return NOPAGE_SIGBUS;

page_not_uptodate:
if (!did_readaround) {
@@ -1366,7 +1366,7 @@ page_not_uptodate:
* mm layer so, possibly freeing the page cache page first.
*/
page_cache_release(page);
- return NULL;
+ return NOPAGE_SIGBUS;
}

EXPORT_SYMBOL(filemap_nopage);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/