Ethereal-dev: Re: [ethereal-dev] NFS filename / RPC string bug

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <guy@xxxxxxxxxx>
Date: Fri, 3 Dec 1999 13:36:08 -0800 (PST)
> This small trace file shows a small bug in the NFS filename or RPC string
> handling of NFS v2 packets.

"snoop" doesn't like frame 8, either:

	RPC:  ----- SUN RPC Header -----
	RPC:
	RPC:  Transaction id = 2187714176
	RPC:  Type = 0 (Call)
	RPC:  RPC version = 2   
	RPC:  Program = 100003 (NFS), version = 2, procedure = 4
	RPC:  Credentials: Flavor = 1 (Unix), len = 44 bytes
	RPC:     Time = 1966 
	RPC:     Hostname = louie.dev.tivoli.com
	RPC:     Uid = 4462, Gid = 40   
	RPC:     Groups = 40
	RPC:  Verifier   : Flavor = 0 (None), len = 0 bytes
	RPC:  
	NFS:  ----- Sun NFS -----
	NFS:
	NFS:  Proc = 4 (Look up file name)
	NFS:  File handle = CABAEBFE94B900005972000001080000
	NFS:                01080000718F0000C773890B00000000
	NFS:  ----  short frame ---

and it has a similar complaint about frame 14.

It's been a while since I last dealt directly with NFS code, but I tend
to agree with "snoop" here; the NFS V2 spec (RFC 1094) says of file
handles:

          typedef opaque fhandle[FHSIZE];

and the XDR spec (RFC 1014) says:

	3.8 Fixed-length Opaque Data
 
	   At times, fixed-length uninterpreted data needs to be passed among
	   machines.  This data is called "opaque" and is declared as follows:
   
	         opaque identifier[n];

RFC 1094 also says:

   /* The size in bytes of the opaque file handle. */
   const FHSIZE = 32;

so a V2 file handle is exactly 32 bytes, with no length field preceding
it - and that's what both Ethereal and "snoop" found at the beginning of
the NFS request.  The arguments to a V2 LOOKUP are a "struct diropargs":

          struct diropargs {
              fhandle  dir;
              filename name;
          };

so the file handle should be at the beginning; a "filename" is

          typedef string filename<MAXNAMLEN>;

and RFC 1014 says of a string:

3.10 String
   
   The standard defines a string of n (numbered 0 through n-1) ASCII 
   bytes to be the number n encoded as an unsigned integer (as described
   above), and followed by the n bytes of the string.  Byte m of the
   string always precedes byte m+1 of the string, and byte 0 of the
   string always follows the string's length.  If n is not a multiple of
   four, then the n bytes are followed by enough (0 to 3) residual zero
   bytes, r, to make the total byte count a multiple of four.  Counted
   byte strings are declared as follows:
 
         string object<m>;
      or
         string object<>;
      
 
   The constant m denotes an upper bound of the number of bytes that a
   string may contain.  If m is not specified, as in the second
   declaration, it is assumed to be (2**32) - 1, the maximum length.
   The constant m would normally be found in a protocol specification.
   For example, a filing protocol may state that a file name can be no
   longer than 255 bytes, as follows:
  
         string filename<255>;
            
            0     1     2     3     4     5   ...
         +-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
         |        length n       |byte0|byte1|...| n-1 |  0  |...|  0  |
         +-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
         |<-------4 bytes------->|<------n bytes------>|<---r bytes--->|
                                 |<----n+r (where (n+r) mod 4 = 0)---->|
                                                                  STRING

so it's a 4-byte byte count followed by that many bytes of data;
following those 32 bytes of file handle are *no* byte count, and
"config.h" followed by a '\0' followed by "g.h".

There's no sign of a 4-byte big-endian integer with "8" in it in front
of that string, so, if the packet is supposed to be an NFS V2 LOOKUP
request, it looks malformed.

What OS are the client and server running?