Commit 8b7e3f49 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Don't decode fs_locations if we didn't ask for them...

Currently, the server can potentially cause us to Oops by returning an
fs_locations request that we didn't actually request.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent c15c928f
......@@ -3561,6 +3561,10 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
status = 0;
if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
goto out;
status = -EIO;
/* Ignore borken servers that return unrequested attrs */
if (unlikely(res == NULL))
goto out;
dprintk("%s: fsroot ", __func__);
status = decode_pathname(xdr, &res->fs_path);
if (unlikely(status != 0))
......@@ -4295,6 +4299,7 @@ static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf
static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
struct nfs_fattr *fattr, struct nfs_fh *fh,
struct nfs4_fs_locations *fs_loc,
const struct nfs_server *server)
{
int status;
......@@ -4342,9 +4347,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
goto xdr_error;
fattr->valid |= status;
status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr,
struct nfs4_fs_locations,
fattr));
status = decode_attr_fs_locations(xdr, bitmap, fs_loc);
if (status < 0)
goto xdr_error;
fattr->valid |= status;
......@@ -4408,7 +4411,8 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
}
static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
struct nfs_fh *fh, const struct nfs_server *server)
struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc,
const struct nfs_server *server)
{
__be32 *savep;
uint32_t attrlen,
......@@ -4427,7 +4431,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat
if (status < 0)
goto xdr_error;
status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server);
status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc, server);
if (status < 0)
goto xdr_error;
......@@ -4440,7 +4444,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat
static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
const struct nfs_server *server)
{
return decode_getfattr_generic(xdr, fattr, NULL, server);
return decode_getfattr_generic(xdr, fattr, NULL, NULL, server);
}
/*
......@@ -6580,8 +6584,9 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
if (status)
goto out;
xdr_enter_page(xdr, PAGE_SIZE);
status = decode_getfattr(xdr, &res->fs_locations->fattr,
res->fs_locations->server);
status = decode_getfattr_generic(xdr, &res->fs_locations->fattr,
NULL, res->fs_locations,
res->fs_locations->server);
out:
return status;
}
......@@ -6961,7 +6966,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
goto out_overflow;
if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
entry->server) < 0)
NULL, entry->server) < 0)
goto out_overflow;
if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
entry->ino = entry->fattr->mounted_on_fileid;
......
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