aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-11-20 15:18:22 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-11-22 13:24:47 -0500
commit3020093f578fb6c9acc6914dfd887a1ebd1db659 (patch)
tree473af4f139dcb3975b20bcd9d2e04fb1cadc97b3 /fs/nfs/dir.c
parentece0b4233b6b915d1f63add2bd9f2733aec6317a (diff)
NFS: Correct the array bound calculation in nfs_readdir_add_to_array
It looks as if the array size calculation in MAX_READDIR_ARRAY does not take the alignment of struct nfs_cache_array_entry into account. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index ddc2e439702b..ced7291cc5f8 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -171,8 +171,6 @@ struct nfs_cache_array {
171 struct nfs_cache_array_entry array[0]; 171 struct nfs_cache_array_entry array[0];
172}; 172};
173 173
174#define MAX_READDIR_ARRAY ((PAGE_SIZE - sizeof(struct nfs_cache_array)) / sizeof(struct nfs_cache_array_entry))
175
176typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); 174typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
177typedef struct { 175typedef struct {
178 struct file *file; 176 struct file *file;
@@ -257,11 +255,14 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
257 255
258 if (IS_ERR(array)) 256 if (IS_ERR(array))
259 return PTR_ERR(array); 257 return PTR_ERR(array);
258
259 cache_entry = &array->array[array->size];
260
261 /* Check that this entry lies within the page bounds */
260 ret = -ENOSPC; 262 ret = -ENOSPC;
261 if (array->size >= MAX_READDIR_ARRAY) 263 if ((char *)&cache_entry[1] - (char *)page_address(page) > PAGE_SIZE)
262 goto out; 264 goto out;
263 265
264 cache_entry = &array->array[array->size];
265 cache_entry->cookie = entry->prev_cookie; 266 cache_entry->cookie = entry->prev_cookie;
266 cache_entry->ino = entry->ino; 267 cache_entry->ino = entry->ino;
267 ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len); 268 ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len);