nfs: don't truncate directory cookies to 32-bits in the NFS server
In NFSv2, the directory cookie was 32-bits. NFSv3 widened it to 64-bits and SVN r22521 widened the corresponding argument in VOP_READDIR, but FreeBSD's NFS server continued to treat the cookies as 32-bits, and 0-extended to fill the field on the wire. Nobody ever noticed, because every in-tree file system generates cookies that fit comfortably within 32-bits. Also, have better type safety for txdr_hyper. Turn it into an inline function that type-checks its arguments. Prevents warnings about shift-count-overflow. PR: 260375 MFC after: 2 weeks Reviewed by: rmacklem Differential Revision: https://reviews.freebsd.org/D33404
This commit is contained in:
parent
f037731345
commit
32fbc5d824
@ -93,9 +93,11 @@
|
|||||||
((((u_quad_t)ntohl(((u_int32_t *)(f))[0])) << 32) | \
|
((((u_quad_t)ntohl(((u_int32_t *)(f))[0])) << 32) | \
|
||||||
(u_quad_t)(ntohl(((u_int32_t *)(f))[1])))
|
(u_quad_t)(ntohl(((u_int32_t *)(f))[1])))
|
||||||
|
|
||||||
#define txdr_hyper(f, t) do { \
|
static inline void
|
||||||
((u_int32_t *)(t))[0] = htonl((u_int32_t)((f) >> 32)); \
|
txdr_hyper(uint64_t f, uint32_t* t)
|
||||||
((u_int32_t *)(t))[1] = htonl((u_int32_t)((f) & 0xffffffff)); \
|
{
|
||||||
} while (0)
|
t[0] = htonl((u_int32_t)(f >> 32));
|
||||||
|
t[1] = htonl((u_int32_t)(f & 0xffffffff));
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _NFS_XDR_SUBS_H_ */
|
#endif /* _NFS_XDR_SUBS_H_ */
|
||||||
|
@ -2258,11 +2258,12 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
|
|||||||
(void) nfsm_strtom(nd, dp->d_name, nlen);
|
(void) nfsm_strtom(nd, dp->d_name, nlen);
|
||||||
if (nd->nd_flag & ND_NFSV3) {
|
if (nd->nd_flag & ND_NFSV3) {
|
||||||
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
|
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
|
||||||
*tl++ = 0;
|
txdr_hyper(*cookiep, tl);
|
||||||
} else
|
} else {
|
||||||
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
|
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||||
*tl = txdr_unsigned(*cookiep);
|
*tl = txdr_unsigned(*cookiep);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
cpos += dp->d_reclen;
|
cpos += dp->d_reclen;
|
||||||
dp = (struct dirent *)cpos;
|
dp = (struct dirent *)cpos;
|
||||||
cookiep++;
|
cookiep++;
|
||||||
@ -2747,8 +2748,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
|
|||||||
*tl = txdr_unsigned(dp->d_fileno);
|
*tl = txdr_unsigned(dp->d_fileno);
|
||||||
dirlen += nfsm_strtom(nd, dp->d_name, nlen);
|
dirlen += nfsm_strtom(nd, dp->d_name, nlen);
|
||||||
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
|
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
|
||||||
*tl++ = 0;
|
txdr_hyper(*cookiep, tl);
|
||||||
*tl = txdr_unsigned(*cookiep);
|
|
||||||
nfsrv_postopattr(nd, 0, nvap);
|
nfsrv_postopattr(nd, 0, nvap);
|
||||||
dirlen += nfsm_fhtom(nd,(u_int8_t *)&nfh,0,1);
|
dirlen += nfsm_fhtom(nd,(u_int8_t *)&nfh,0,1);
|
||||||
dirlen += (5*NFSX_UNSIGNED+NFSX_V3POSTOPATTR);
|
dirlen += (5*NFSX_UNSIGNED+NFSX_V3POSTOPATTR);
|
||||||
@ -2757,8 +2757,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
|
|||||||
} else {
|
} else {
|
||||||
NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
|
NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
|
||||||
*tl++ = newnfs_true;
|
*tl++ = newnfs_true;
|
||||||
*tl++ = 0;
|
txdr_hyper(*cookiep, tl);
|
||||||
*tl = txdr_unsigned(*cookiep);
|
|
||||||
dirlen += nfsm_strtom(nd, dp->d_name, nlen);
|
dirlen += nfsm_strtom(nd, dp->d_name, nlen);
|
||||||
if (nvp != NULL) {
|
if (nvp != NULL) {
|
||||||
supports_nfsv4acls =
|
supports_nfsv4acls =
|
||||||
|
@ -1433,13 +1433,13 @@ nfsrv_fillattr(struct nfsrv_descript *nd, struct nfsvattr *nvap)
|
|||||||
if (nd->nd_flag & ND_NFSV3) {
|
if (nd->nd_flag & ND_NFSV3) {
|
||||||
fp->fa_type = vtonfsv34_type(nvap->na_type);
|
fp->fa_type = vtonfsv34_type(nvap->na_type);
|
||||||
fp->fa_mode = vtonfsv34_mode(nvap->na_mode);
|
fp->fa_mode = vtonfsv34_mode(nvap->na_mode);
|
||||||
txdr_hyper(nvap->na_size, &fp->fa3_size);
|
txdr_hyper(nvap->na_size, (uint32_t*)&fp->fa3_size);
|
||||||
txdr_hyper(nvap->na_bytes, &fp->fa3_used);
|
txdr_hyper(nvap->na_bytes, (uint32_t*)&fp->fa3_used);
|
||||||
fp->fa3_rdev.specdata1 = txdr_unsigned(NFSMAJOR(nvap->na_rdev));
|
fp->fa3_rdev.specdata1 = txdr_unsigned(NFSMAJOR(nvap->na_rdev));
|
||||||
fp->fa3_rdev.specdata2 = txdr_unsigned(NFSMINOR(nvap->na_rdev));
|
fp->fa3_rdev.specdata2 = txdr_unsigned(NFSMINOR(nvap->na_rdev));
|
||||||
fp->fa3_fsid.nfsuquad[0] = 0;
|
fp->fa3_fsid.nfsuquad[0] = 0;
|
||||||
fp->fa3_fsid.nfsuquad[1] = txdr_unsigned(nvap->na_fsid);
|
fp->fa3_fsid.nfsuquad[1] = txdr_unsigned(nvap->na_fsid);
|
||||||
txdr_hyper(nvap->na_fileid, &fp->fa3_fileid);
|
txdr_hyper(nvap->na_fileid, (uint32_t*)&fp->fa3_fileid);
|
||||||
txdr_nfsv3time(&nvap->na_atime, &fp->fa3_atime);
|
txdr_nfsv3time(&nvap->na_atime, &fp->fa3_atime);
|
||||||
txdr_nfsv3time(&nvap->na_mtime, &fp->fa3_mtime);
|
txdr_nfsv3time(&nvap->na_mtime, &fp->fa3_mtime);
|
||||||
txdr_nfsv3time(&nvap->na_ctime, &fp->fa3_ctime);
|
txdr_nfsv3time(&nvap->na_ctime, &fp->fa3_ctime);
|
||||||
|
@ -83,10 +83,12 @@ do { \
|
|||||||
#define fxdr_hyper(f) \
|
#define fxdr_hyper(f) \
|
||||||
((((u_quad_t)ntohl(((u_int32_t *)(f))[0])) << 32) | \
|
((((u_quad_t)ntohl(((u_int32_t *)(f))[0])) << 32) | \
|
||||||
(u_quad_t)(ntohl(((u_int32_t *)(f))[1])))
|
(u_quad_t)(ntohl(((u_int32_t *)(f))[1])))
|
||||||
#define txdr_hyper(f, t) \
|
|
||||||
do { \
|
static inline void
|
||||||
((u_int32_t *)(t))[0] = htonl((u_int32_t)((f) >> 32)); \
|
txdr_hyper(uint64_t f, uint32_t* t)
|
||||||
((u_int32_t *)(t))[1] = htonl((u_int32_t)((f) & 0xffffffff)); \
|
{
|
||||||
} while (0)
|
t[0] = htonl((u_int32_t)(f >> 32));
|
||||||
|
t[1] = htonl((u_int32_t)(f & 0xffffffff));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user