summaryrefslogtreecommitdiff
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-04-10 09:26:35 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-04-30 22:17:07 -0700
commit8d5658c949e6d89edc579a1f112aeee3bc232a8e (patch)
treef206d3f6809eeb0ca23c1999cf79aa294968b113 /fs/nfs/write.c
parentc63c7b051395368573779c8309aa5c990dcf2f96 (diff)
downloadlwn-8d5658c949e6d89edc579a1f112aeee3bc232a8e.tar.gz
lwn-8d5658c949e6d89edc579a1f112aeee3bc232a8e.zip
NFS: Fix a buffer overflow in the allocation of struct nfs_read/writedata
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 6ce2d94e7b3f..0a8bbc399689 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -72,9 +72,8 @@ void nfs_commit_free(struct nfs_write_data *wdata)
call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free);
}
-struct nfs_write_data *nfs_writedata_alloc(size_t len)
+struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
{
- unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS);
if (p) {
@@ -832,7 +831,7 @@ static void nfs_execute_write(struct nfs_write_data *data)
* Generate multiple small requests to write out a single
* contiguous dirty area on one page.
*/
-static int nfs_flush_multi(struct inode *inode, struct list_head *head, size_t count, int how)
+static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int how)
{
struct nfs_page *req = nfs_list_entry(head->next);
struct page *page = req->wb_page;
@@ -848,7 +847,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, size_t c
do {
size_t len = min(nbytes, wsize);
- data = nfs_writedata_alloc(len);
+ data = nfs_writedata_alloc(1);
if (!data)
goto out_bad;
list_add(&data->pages, &list);
@@ -897,13 +896,13 @@ out_bad:
* This is the case if nfs_updatepage detects a conflicting request
* that has been written but not committed.
*/
-static int nfs_flush_one(struct inode *inode, struct list_head *head, size_t count, int how)
+static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int how)
{
struct nfs_page *req;
struct page **pages;
struct nfs_write_data *data;
- data = nfs_writedata_alloc(count);
+ data = nfs_writedata_alloc(npages);
if (!data)
goto out_bad;