diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-11-20 15:18:22 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-11-22 13:24:47 -0500 |
commit | 3020093f578fb6c9acc6914dfd887a1ebd1db659 (patch) | |
tree | 473af4f139dcb3975b20bcd9d2e04fb1cadc97b3 /fs/nfs/dir.c | |
parent | ece0b4233b6b915d1f63add2bd9f2733aec6317a (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.c | 9 |
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 | |||
176 | typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); | 174 | typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); |
177 | typedef struct { | 175 | typedef 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); |