diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-04-10 09:26:35 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-04-30 22:17:07 -0700 |
commit | 8d5658c949e6d89edc579a1f112aeee3bc232a8e (patch) | |
tree | f206d3f6809eeb0ca23c1999cf79aa294968b113 /fs/nfs/pagelist.c | |
parent | c63c7b051395368573779c8309aa5c990dcf2f96 (diff) | |
download | linux-8d5658c949e6d89edc579a1f112aeee3bc232a8e.tar.bz2 |
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/pagelist.c')
-rw-r--r-- | fs/nfs/pagelist.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index ea1a85df9ab1..096efd73eb4c 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -18,6 +18,8 @@ #include <linux/nfs_fs.h> #include <linux/nfs_mount.h> +#include "internal.h" + #define NFS_PARANOIA 1 static struct kmem_cache *nfs_page_cachep; @@ -231,7 +233,7 @@ out: */ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, struct inode *inode, - int (*doio)(struct inode *, struct list_head *, size_t, int), + int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int), unsigned int bsize, int io_flags) { @@ -298,8 +300,10 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, * since nfs_flush_multi and nfs_pagein_multi assume you * can have only one struct nfs_page. */ + if (desc->pg_bsize < PAGE_SIZE) + return 0; newlen += desc->pg_count; - if (desc->pg_base + newlen > desc->pg_bsize) + if (newlen > desc->pg_bsize) return 0; prev = nfs_list_entry(desc->pg_list.prev); if (!nfs_can_coalesce_requests(prev, req)) @@ -320,6 +324,8 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) if (!list_empty(&desc->pg_list)) { int error = desc->pg_doio(desc->pg_inode, &desc->pg_list, + nfs_page_array_len(desc->pg_base, + desc->pg_count), desc->pg_count, desc->pg_ioflags); if (error < 0) |