Print this page
OS-20 share_nfs(1m) charset handling is unreliable
OS-22 Page fault at nfscmd_dropped_entrysize+0x1e()
OS-23 NFSv2/3/4: READDIR responses are inconsistent when charset conversion fails
OS-24 rfs3_readdir(): Issues related to nfscmd_convdirent()
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
*** 20,29 ****
--- 20,32 ----
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+ /*
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <sys/param.h>
*** 769,824 ****
* ENCODE ONLY
*/
bool_t
xdr_putrddirres(XDR *xdrs, struct nfsrddirres *rd)
{
- struct dirent64 *dp;
- char *name;
- int size;
- uint_t namlen;
bool_t true = TRUE;
bool_t false = FALSE;
! int entrysz;
! int tofit;
! int bufsize;
! uint32_t ino, off;
if (xdrs->x_op != XDR_ENCODE)
return (FALSE);
if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
return (FALSE);
if (rd->rd_status != NFS_OK)
return (TRUE);
! bufsize = 1 * BYTES_PER_XDR_UNIT;
! for (size = rd->rd_size, dp = rd->rd_entries;
! size > 0;
! size -= dp->d_reclen, dp = nextdp(dp)) {
! if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */)
! return (FALSE);
! if (dp->d_ino == 0)
! continue;
! ino = (uint32_t)dp->d_ino; /* for LP64 we clip the bits */
! if (dp->d_ino != (ino64_t)ino) /* and they better be zeros */
! return (FALSE);
! off = (uint32_t)dp->d_off;
! name = dp->d_name;
! namlen = (uint_t)strlen(name);
! entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
! roundup(namlen, BYTES_PER_XDR_UNIT);
! tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
! if (bufsize + tofit > rd->rd_bufsize) {
! rd->rd_eof = FALSE;
! break;
! }
if (!xdr_bool(xdrs, &true) ||
! !xdr_u_int(xdrs, &ino) ||
! !xdr_bytes(xdrs, &name, &namlen, NFS_MAXNAMLEN) ||
! !xdr_u_int(xdrs, &off)) {
return (FALSE);
}
- bufsize += entrysz;
}
if (!xdr_bool(xdrs, &false))
return (FALSE);
if (!xdr_bool(xdrs, &rd->rd_eof))
return (FALSE);
--- 772,799 ----
* ENCODE ONLY
*/
bool_t
xdr_putrddirres(XDR *xdrs, struct nfsrddirres *rd)
{
bool_t true = TRUE;
bool_t false = FALSE;
! struct nfsentry *entry;
if (xdrs->x_op != XDR_ENCODE)
return (FALSE);
if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
return (FALSE);
if (rd->rd_status != NFS_OK)
return (TRUE);
! for (entry = rd->rd_entries; entry != NULL; entry = entry->nextentry) {
if (!xdr_bool(xdrs, &true) ||
! !xdr_u_int(xdrs, &entry->fileid) ||
! !xdr_string(xdrs, &entry->name, NFS_MAXNAMLEN) ||
! !xdr_u_int(xdrs, &entry->cookie)) {
return (FALSE);
}
}
if (!xdr_bool(xdrs, &false))
return (FALSE);
if (!xdr_bool(xdrs, &rd->rd_eof))
return (FALSE);
*** 845,855 ****
return (FALSE);
if (rd->rd_status != NFS_OK)
return (TRUE);
size = rd->rd_size;
! dp = rd->rd_entries;
offset = rd->rd_offset;
for (;;) {
if (!xdr_bool(xdrs, &valid))
return (FALSE);
if (!valid)
--- 820,830 ----
return (FALSE);
if (rd->rd_status != NFS_OK)
return (TRUE);
size = rd->rd_size;
! dp = rd->rd_dirents;
offset = rd->rd_offset;
for (;;) {
if (!xdr_bool(xdrs, &valid))
return (FALSE);
if (!valid)
*** 875,885 ****
dp = nextdp(dp);
}
if (!xdr_bool(xdrs, &rd->rd_eof))
return (FALSE);
bufovflw:
! rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_entries));
rd->rd_offset = offset;
return (TRUE);
}
/*
--- 850,860 ----
dp = nextdp(dp);
}
if (!xdr_bool(xdrs, &rd->rd_eof))
return (FALSE);
bufovflw:
! rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_dirents));
rd->rd_offset = offset;
return (TRUE);
}
/*