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>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs_xdr.c
          +++ new/usr/src/uts/common/fs/nfs/nfs_xdr.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
       25 +/*
       26 + * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
       27 + */
  25   28  
  26   29  /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  27   30  /* All Rights Reserved */
  28   31  
  29   32  #include <sys/param.h>
  30   33  #include <sys/types.h>
  31   34  #include <sys/systm.h>
  32   35  #include <sys/user.h>
  33   36  #include <sys/vnode.h>
  34   37  #include <sys/file.h>
↓ open down ↓ 729 lines elided ↑ open up ↑
 764  767  #undef  roundup
 765  768  #endif
 766  769  #define roundup(x, y)   ((((x) + ((y) - 1)) / (y)) * (y))
 767  770  
 768  771  /*
 769  772   * ENCODE ONLY
 770  773   */
 771  774  bool_t
 772  775  xdr_putrddirres(XDR *xdrs, struct nfsrddirres *rd)
 773  776  {
 774      -        struct dirent64 *dp;
 775      -        char *name;
 776      -        int size;
 777      -        uint_t namlen;
 778  777          bool_t true = TRUE;
 779  778          bool_t false = FALSE;
 780      -        int entrysz;
 781      -        int tofit;
 782      -        int bufsize;
 783      -        uint32_t ino, off;
      779 +        struct nfsentry *entry;
 784  780  
 785  781          if (xdrs->x_op != XDR_ENCODE)
 786  782                  return (FALSE);
 787  783          if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
 788  784                  return (FALSE);
 789  785          if (rd->rd_status != NFS_OK)
 790  786                  return (TRUE);
 791  787  
 792      -        bufsize = 1 * BYTES_PER_XDR_UNIT;
 793      -        for (size = rd->rd_size, dp = rd->rd_entries;
 794      -            size > 0;
 795      -            size -= dp->d_reclen, dp = nextdp(dp)) {
 796      -                if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */)
 797      -                        return (FALSE);
 798      -                if (dp->d_ino == 0)
 799      -                        continue;
 800      -                ino = (uint32_t)dp->d_ino; /* for LP64 we clip the bits */
 801      -                if (dp->d_ino != (ino64_t)ino)  /* and they better be zeros */
 802      -                        return (FALSE);
 803      -                off = (uint32_t)dp->d_off;
 804      -                name = dp->d_name;
 805      -                namlen = (uint_t)strlen(name);
 806      -                entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
 807      -                    roundup(namlen, BYTES_PER_XDR_UNIT);
 808      -                tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
 809      -                if (bufsize + tofit > rd->rd_bufsize) {
 810      -                        rd->rd_eof = FALSE;
 811      -                        break;
 812      -                }
      788 +        for (entry = rd->rd_entries; entry != NULL; entry = entry->nextentry) {
 813  789                  if (!xdr_bool(xdrs, &true) ||
 814      -                    !xdr_u_int(xdrs, &ino) ||
 815      -                    !xdr_bytes(xdrs, &name, &namlen, NFS_MAXNAMLEN) ||
 816      -                    !xdr_u_int(xdrs, &off)) {
      790 +                    !xdr_u_int(xdrs, &entry->fileid) ||
      791 +                    !xdr_string(xdrs, &entry->name, NFS_MAXNAMLEN) ||
      792 +                    !xdr_u_int(xdrs, &entry->cookie)) {
 817  793                          return (FALSE);
 818  794                  }
 819      -                bufsize += entrysz;
 820  795          }
 821  796          if (!xdr_bool(xdrs, &false))
 822  797                  return (FALSE);
 823  798          if (!xdr_bool(xdrs, &rd->rd_eof))
 824  799                  return (FALSE);
 825  800          return (TRUE);
 826  801  }
 827  802  
 828  803  /*
 829  804   * DECODE ONLY
↓ open down ↓ 10 lines elided ↑ open up ↑
 840  815  
 841  816          if (xdrs->x_op != XDR_DECODE)
 842  817                  return (FALSE);
 843  818  
 844  819          if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
 845  820                  return (FALSE);
 846  821          if (rd->rd_status != NFS_OK)
 847  822                  return (TRUE);
 848  823  
 849  824          size = rd->rd_size;
 850      -        dp = rd->rd_entries;
      825 +        dp = rd->rd_dirents;
 851  826          offset = rd->rd_offset;
 852  827          for (;;) {
 853  828                  if (!xdr_bool(xdrs, &valid))
 854  829                          return (FALSE);
 855  830                  if (!valid)
 856  831                          break;
 857  832                  if (!xdr_u_int(xdrs, &fileid) ||
 858  833                      !xdr_u_int(xdrs, &namlen))
 859  834                          return (FALSE);
 860  835                  this_reclen = DIRENT64_RECLEN(namlen);
↓ open down ↓ 9 lines elided ↑ open up ↑
 870  845                      DIRENT64_NAMELEN(this_reclen) - namlen);
 871  846                  dp->d_ino = (ino64_t)fileid;
 872  847                  dp->d_reclen = this_reclen;
 873  848                  dp->d_off = (off64_t)offset;
 874  849                  size -= dp->d_reclen;
 875  850                  dp = nextdp(dp);
 876  851          }
 877  852          if (!xdr_bool(xdrs, &rd->rd_eof))
 878  853                  return (FALSE);
 879  854  bufovflw:
 880      -        rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_entries));
      855 +        rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_dirents));
 881  856          rd->rd_offset = offset;
 882  857          return (TRUE);
 883  858  }
 884  859  
 885  860  /*
 886  861   * Arguments for directory operations
 887  862   */
 888  863  bool_t
 889  864  xdr_diropargs(XDR *xdrs, struct nfsdiropargs *da)
 890  865  {
↓ open down ↓ 564 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX