lkml.org 
[lkml]   [1998]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] Obscure page mapping leak in mmap
Linus,

Quite a few device drivers (sound and bttv at least) call
remap_page_range in their mmap functions, which can fail having remapped
some pages. To clean up, the drivers need to call zap_page_range,
though they don't at the moment and this leads to a short term memory
leak. Future mappings can produce a huge number of log messages because
there are page mappings for a region that has no VMA. I don't know if
this has serious security implications.

Making remap_page_range zap the partial mapping if it runs out of memory
won't do, because some drivers need several calls to remap_page_range to
set up the mappings for a single mmap. (Anything which has allocated a
scatter-gather buffer which is presented to userspace as contiguous).

A general solution is which fixes the leak for all drivers is to call
zap_page_range from do_mmap in the event of a device mmap failure,
though it may be excess overhead in some unusual cases. That's what
I've implemented.

An alternative which would be more efficient for other error cases would
be to simply export zap_page_range, and let individual drivers call it
if remap_page_range fails. But there are quite a few drivers which need
this, and the fix below sorts them all out.

Enjoy,
-- Jamie

--- linux/mm/mmap.c.devel Thu Nov 12 12:06:33 1998
+++ linux/mm/mmap.c Sun Nov 22 02:17:29 1998
@@ -323,7 +323,7 @@
if (correct_wcount)
file->f_dentry->d_inode->i_writecount++;
if (error)
- goto free_vma;
+ goto unmap_and_free_vma;

/*
* merge_segments may merge our vma, so we can't refer to it
@@ -341,6 +341,13 @@
}
return addr;

+unmap_and_free_vma:
+ if (error == -EAGAIN || error == -ENOMEM) {
+ /* Undo any partial mapping done by a device driver. */
+ flush_cache_range(mm, vma->vm_start, vma->vm_end);
+ zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
+ flush_tlb_range(mm, vma->vm_start, vma->vm_end);
+ }
free_vma:
kmem_cache_free(vm_area_cachep, vma);
return error;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:45    [W:0.146 / U:0.228 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site