nfs4-acl-tools: when who's length is very big, nfs4_getacl core dump
Subsystems (2)
PATCH 1/1 nfs4-acl-tools: when who's length is very big, nfs4_getacl core dump
From: Fan Chaoting <[email protected]>
nfsv4 server can return an arbitrary
sized who's len(eg. wholen = 62343534343) in an FATTR4_WORD0_ACL request. It can cause program core dump when call 'malloc((wholen + 1) * sizeof(char))'.
This patch checked if who's len bigger than xattr_size when getfacl.
This patch also fixed some code style.
Signed-off-by Fan Chaoting <[email protected]>
the reproduce of this problem:
#####################################################################
1. change the nfs server's code.
fs/nfsd/nfs4xdr.c +8 -1
@@ -2163,6 +2163,13 @@ out_acl: } *attrlenp =htonl ((char *)p - (char *)attrlenp -4 ); + +static int j; + j++; + +if (j %10 ==0 & bmval0 &FATTR4_WORD0_ACL ) { + *attrlenp =6000 ; + } *countp = p - buffer; status = nfs_ok;
@@ -3323,7 +3330,7 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoelse iov = &rqstp->rq_res.head[0 ]; iov->iov_len = ((char *)resp->p) - (char *)iov->iov_base; -BUG_ON (iov->iov_len >PAGE_SIZE ); +// BUG_ON(iov->iov_len > PAGE_SIZE); if (nfsd4_has_session (cs)) {if (cs->status != nfserr_replay_cache) {nfsd4_store_cache_entry (resp);
2. mount -t nfs4 -o acl NFSSERVERIP:/ /mnt
3. touch /mnt/test
4. nfs4_getfacl /mnt/test <--core dump
######################################################################
--- libnfs4acl/acl_nfs4_xattr_load.c | 6 ++++++ libnfs4acl/nfs4_acl_for_path.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-)
libnfs4acl/acl_nfs4_xattr_load.c +6 -0
@@ -139,6 +139,12 @@ struct nfs4_acl * acl_nfs4_xattr_load(char *xattr_v, int xattr_size, u32 is_dir) goto err1; } +/*wholen should less than xattr_size*/ +if (wholen > xattr_size) { + errno =EINVAL ; + goto err1; + } + who = (char *)malloc ((wholen+1 ) *sizeof (char ));if (who ==NULL ) { errno =ENOMEM ;
libnfs4acl/nfs4_acl_for_path.c +4 -4
@@ -92,14 +92,14 @@ static int nfs4_getxattr(const char *path, void *value, size_t size) res =getxattr (path,ACL_NFS4_XATTR , value, size);if (res <-10000 ) { -fprintf (stderr,"An internal NFS server error code (%d) was returned; this should never happen.\n" ,res); +fprintf (stderr,"An internal NFS server error code (%d) was returned; this should never happen.\n" , res); }else if (res <0 ) {if (errno ==ENOATTR ) -fprintf (stderr,"Attribute not found on file.\n" ); +fprintf (stderr,"Attribute not found on file.\n" );else if (errno ==EREMOTEIO ) -fprintf (stderr,"An NFS server error occurred.\n" ); +fprintf (stderr,"An NFS server error occurred.\n" );else if (errno ==EOPNOTSUPP ) -fprintf (stderr,"Operation to request attribute not supported.\n" ); +fprintf (stderr,"Operation to request attribute not supported.\n" );else perror ("Failed getxattr operation" ); }
Signature · 1 line
1.7.1