[PATCH] fs: fix libfs data leak
Changes
2 files changed · +8 −2
| File | Status | Add | Del | Content |
|---|---|---|---|---|
| Documentation/filesystems/vfs.txt | modified | +5 | −0 | View file |
| fs/libfs.c | modified | +3 | −2 | View file |
Documentation/filesystems/vfs.txt
View filediff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 7737bfd..ea271f2 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -617,6 +617,11 @@ struct address_space_operations {
In this case the prepare_write will be retried one the lock is
regained.
+ Note: the page _must not_ be marked uptodate in this function
+ (or anywhere else) unless it actually is uptodate right now. As
+ soon as a page is marked uptodate, it is possible for a concurrent
+ read(2) to copy it to userspace.
+
commit_write: If prepare_write succeeds, new data will be copied
into the page and then commit_write will be called. It will
typically update the size of the file (if appropriate) and
fs/libfs.c
View filediff --git a/fs/libfs.c b/fs/libfs.c
index 7d48704..cf79196 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -335,17 +335,18 @@ int simple_prepare_write(struct file *file, struct page *page,
flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);
}
- SetPageUptodate(page);
}
return 0;
}
int simple_commit_write(struct file *file, struct page *page,
- unsigned offset, unsigned to)
+ unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ if (!PageUptodate(page))
+ SetPageUptodate(page);
/*
* No need to use i_size_read() here, the i_size
* cannot change under us because we hold the i_mutex.