]> granicus.if.org Git - libtirpc/commitdiff
Use of lseek() in xdr_rec.c:xdrrec_getpos().
authorMatthew N. Dodd <matthew.nygard.dodd@gmail.com>
Mon, 20 Jun 2011 17:33:35 +0000 (13:33 -0400)
committerSteve Dickson <steved@redhat.com>
Tue, 21 Jun 2011 18:31:44 +0000 (14:31 -0400)
The use of lseek() in xdr_rec.c:xdrrec_getpos() without checking for
ESPIPE will fail to handle the common case, resulting in poor behavior
in calling code. (In particular auth_gss.c:authgss_marshal() calls
gss_get_mic() with rpcbuf.length set to -1, with spectacular results.)

The original MIT Krb5 RPC code lacks this addition, which I'm unclear of
the utility of in the first place.

Reverting to the MIT code permits correct function of a trivial RPC
client using GSS.

Signed-off-by: Frank Filz <ffilzlnx@us.ibm.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
src/xdr_rec.c

index 4e815d787e10b54286fe9db79ad5c1fbc6687c7f..2aca623a98ba45432bfe300b37bd7e4b542c4308 100644 (file)
@@ -64,7 +64,6 @@
 #include <rpc/clnt.h>
 #include <stddef.h>
 #include "rpc_com.h"
-#include <unistd.h>
 static bool_t  xdrrec_getlong(XDR *, long *);
 static bool_t  xdrrec_putlong(XDR *, const long *);
 static bool_t  xdrrec_getbytes(XDR *, char *, u_int);
@@ -330,22 +329,22 @@ xdrrec_getpos(xdrs)
        RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
        off_t pos;
 
-       pos = lseek((int)(u_long)rstrm->tcp_handle, (off_t)0, 1);
-       if (pos != -1)
-               switch (xdrs->x_op) {
+       switch (xdrs->x_op) {
 
-               case XDR_ENCODE:
-                       pos += rstrm->out_finger - rstrm->out_base;
-                       break;
+       case XDR_ENCODE:
+               pos = rstrm->out_finger - rstrm->out_base
+                       - BYTES_PER_XDR_UNIT;
+               break;
 
-               case XDR_DECODE:
-                       pos -= rstrm->in_boundry - rstrm->in_finger;
-                       break;
+       case XDR_DECODE:
+               pos = rstrm->in_boundry - rstrm->in_finger
+                       - BYTES_PER_XDR_UNIT;
+               break;
 
-               default:
-                       pos = (off_t) -1;
-                       break;
-               }
+       default:
+               pos = (off_t) -1;
+               break;
+       }
        return ((u_int) pos);
 }