Commit 2963542f authored by Benjamin Coddington's avatar Benjamin Coddington Committed by Jiri Slaby

NFS: Don't attempt to decode missing directory entries

commit ce85cfbe upstream.

If a READDIR reply comes back without any page data, avoid a NULL pointer
dereference in xdr_copy_to_scratch().

BUG: unable to handle kernel NULL pointer dereference at 0000000000000001
IP: [<ffffffff813a378d>] memcpy+0xd/0x110
...
Call Trace:
	? xdr_inline_decode+0x7a/0xb0 [sunrpc]
	nfs3_decode_dirent+0x73/0x320 [nfsv3]
	nfs_readdir_page_filler+0xd5/0x4e0 [nfs]
	? nfs3_rpc_wrapper.constprop.9+0x42/0xc0 [nfsv3]
	nfs_readdir_xdr_to_array+0x1fa/0x330 [nfs]
	? mem_cgroup_commit_charge+0xac/0x160
	? nfs_readdir_xdr_to_array+0x330/0x330 [nfs]
	nfs_readdir_filler+0x22/0x90 [nfs]
	do_read_cache_page+0x7e/0x1a0
	read_cache_page+0x1c/0x20
	nfs_readdir+0x18e/0x660 [nfs]
	? nfs3_xdr_dec_getattr3res+0x80/0x80 [nfsv3]
	iterate_dir+0x97/0x130
	SyS_getdents+0x94/0x120
	? fillonedir+0xd0/0xd0
	system_call_fastpath+0x12/0x17
Signed-off-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Cc: Neil Brown <nfbrown@suse.com>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
parent d038b9c4
...@@ -510,6 +510,9 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en ...@@ -510,6 +510,9 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
if (scratch == NULL) if (scratch == NULL)
return -ENOMEM; return -ENOMEM;
if (buflen == 0)
goto out_nopages;
xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen); xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen);
xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
...@@ -531,6 +534,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en ...@@ -531,6 +534,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
break; break;
} while (!entry->eof); } while (!entry->eof);
out_nopages:
if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) { if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) {
array = nfs_readdir_get_array(page); array = nfs_readdir_get_array(page);
if (!IS_ERR(array)) { if (!IS_ERR(array)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment