diff options
Diffstat (limited to 'fs/nfs/nfs3xdr.c')
| -rw-r--r-- | fs/nfs/nfs3xdr.c | 18 | 
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index bffc32406fb..fa6d72131c1 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -592,13 +592,13 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)  	if (attr->ia_valid & ATTR_UID) {  		*p++ = xdr_one; -		*p++ = cpu_to_be32(attr->ia_uid); +		*p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));  	} else  		*p++ = xdr_zero;  	if (attr->ia_valid & ATTR_GID) {  		*p++ = xdr_one; -		*p++ = cpu_to_be32(attr->ia_gid); +		*p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));  	} else  		*p++ = xdr_zero; @@ -657,8 +657,12 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)  	fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode;  	fattr->nlink = be32_to_cpup(p++); -	fattr->uid = be32_to_cpup(p++); -	fattr->gid = be32_to_cpup(p++); +	fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++)); +	if (!uid_valid(fattr->uid)) +		goto out_uid; +	fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++)); +	if (!gid_valid(fattr->gid)) +		goto out_gid;  	p = xdr_decode_size3(p, &fattr->size);  	p = xdr_decode_size3(p, &fattr->du.nfs3.used); @@ -675,6 +679,12 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)  	fattr->valid |= NFS_ATTR_FATTR_V3;  	return 0; +out_uid: +	dprintk("NFS: returned invalid uid\n"); +	return -EINVAL; +out_gid: +	dprintk("NFS: returned invalid gid\n"); +	return -EINVAL;  out_overflow:  	print_overflow_msg(__func__, xdr);  	return -EIO;  |