NFSv4: Fix a readdir regression
Commit 7ebb9315
(NFS: use secinfo when crossing mountpoints) introduces
a regression when decoding an NFSv4 readdir entry that sets the
rdattr_error field.
By treating the resulting value as if it is a decoding error, the current
code may cause us to skip valid readdir entries.
Reported-by: Andy Adamson <andros@netapp.com>
Cc: stable@kernel.org [2.6.39]
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
@@ -3098,7 +3098,7 @@ out_overflow:
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap)
|
static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res)
|
||||||
{
|
{
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
|
|
||||||
@@ -3109,7 +3109,7 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap)
|
|||||||
if (unlikely(!p))
|
if (unlikely(!p))
|
||||||
goto out_overflow;
|
goto out_overflow;
|
||||||
bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
|
bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
|
||||||
return -be32_to_cpup(p);
|
*res = -be32_to_cpup(p);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
out_overflow:
|
out_overflow:
|
||||||
@@ -4070,6 +4070,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
|
|||||||
int status;
|
int status;
|
||||||
umode_t fmode = 0;
|
umode_t fmode = 0;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
|
int32_t err;
|
||||||
|
|
||||||
status = decode_attr_type(xdr, bitmap, &type);
|
status = decode_attr_type(xdr, bitmap, &type);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
@@ -4095,13 +4096,12 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
|
|||||||
goto xdr_error;
|
goto xdr_error;
|
||||||
fattr->valid |= status;
|
fattr->valid |= status;
|
||||||
|
|
||||||
status = decode_attr_error(xdr, bitmap);
|
err = 0;
|
||||||
if (status == -NFS4ERR_WRONGSEC) {
|
status = decode_attr_error(xdr, bitmap, &err);
|
||||||
nfs_fixup_secinfo_attributes(fattr, fh);
|
|
||||||
status = 0;
|
|
||||||
}
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
goto xdr_error;
|
goto xdr_error;
|
||||||
|
if (err == -NFS4ERR_WRONGSEC)
|
||||||
|
nfs_fixup_secinfo_attributes(fattr, fh);
|
||||||
|
|
||||||
status = decode_attr_filehandle(xdr, bitmap, fh);
|
status = decode_attr_filehandle(xdr, bitmap, fh);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
|
Reference in New Issue
Block a user