diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-04-10 09:26:35 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-05-01 01:17:07 -0400 |
commit | 8d5658c949e6d89edc579a1f112aeee3bc232a8e (patch) | |
tree | f206d3f6809eeb0ca23c1999cf79aa294968b113 /fs/nfs/pagelist.c | |
parent | c63c7b051395368573779c8309aa5c990dcf2f96 (diff) |
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 @@ | |||
18 | #include <linux/nfs_fs.h> | 18 | #include <linux/nfs_fs.h> |
19 | #include <linux/nfs_mount.h> | 19 | #include <linux/nfs_mount.h> |
20 | 20 | ||
21 | #include "internal.h" | ||
22 | |||
21 | #define NFS_PARANOIA 1 | 23 | #define NFS_PARANOIA 1 |
22 | 24 | ||
23 | static struct kmem_cache *nfs_page_cachep; | 25 | static struct kmem_cache *nfs_page_cachep; |
@@ -231,7 +233,7 @@ out: | |||
231 | */ | 233 | */ |
232 | void nfs_pageio_init(struct nfs_pageio_descriptor *desc, | 234 | void nfs_pageio_init(struct nfs_pageio_descriptor *desc, |
233 | struct inode *inode, | 235 | struct inode *inode, |
234 | int (*doio)(struct inode *, struct list_head *, size_t, int), | 236 | int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int), |
235 | unsigned int bsize, | 237 | unsigned int bsize, |
236 | int io_flags) | 238 | int io_flags) |
237 | { | 239 | { |
@@ -298,8 +300,10 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, | |||
298 | * since nfs_flush_multi and nfs_pagein_multi assume you | 300 | * since nfs_flush_multi and nfs_pagein_multi assume you |
299 | * can have only one struct nfs_page. | 301 | * can have only one struct nfs_page. |
300 | */ | 302 | */ |
303 | if (desc->pg_bsize < PAGE_SIZE) | ||
304 | return 0; | ||
301 | newlen += desc->pg_count; | 305 | newlen += desc->pg_count; |
302 | if (desc->pg_base + newlen > desc->pg_bsize) | 306 | if (newlen > desc->pg_bsize) |
303 | return 0; | 307 | return 0; |
304 | prev = nfs_list_entry(desc->pg_list.prev); | 308 | prev = nfs_list_entry(desc->pg_list.prev); |
305 | if (!nfs_can_coalesce_requests(prev, req)) | 309 | if (!nfs_can_coalesce_requests(prev, req)) |
@@ -320,6 +324,8 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) | |||
320 | if (!list_empty(&desc->pg_list)) { | 324 | if (!list_empty(&desc->pg_list)) { |
321 | int error = desc->pg_doio(desc->pg_inode, | 325 | int error = desc->pg_doio(desc->pg_inode, |
322 | &desc->pg_list, | 326 | &desc->pg_list, |
327 | nfs_page_array_len(desc->pg_base, | ||
328 | desc->pg_count), | ||
323 | desc->pg_count, | 329 | desc->pg_count, |
324 | desc->pg_ioflags); | 330 | desc->pg_ioflags); |
325 | if (error < 0) | 331 | if (error < 0) |