[PATCH 5/7] Fix RPC xdrproc_t calls

Bernd Schmidt bernds_cb1 at t-online.de
Wed Mar 2 20:21:55 UTC 2011


From: Mark Salter <msalter at redhat.com>

xdrproc_t is defined as a variadic function with two fixed arguments.
However, the code uses typecasts of non-variadic functions in assignments
to xdrproc_t types and later calls those functions as an xdrproc_t. This
leads to undefined behavior in C. On C6X, the ABI is different for
variadic and non-variadic functions, so this code fails to work.

Signed-of-by: Mark Salter <msalter at redhat.com>
---
 include/rpc/xdr.h             |    2 +-
 libc/inet/rpc/xdr.c           |    4 ++--
 libc/inet/rpc/xdr_array.c     |    4 ++--
 libc/inet/rpc/xdr_reference.c |    2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/rpc/xdr.h b/include/rpc/xdr.h
index 9981e3a..4b663d7 100644
--- a/include/rpc/xdr.h
+++ b/include/rpc/xdr.h
@@ -159,7 +159,7 @@ struct XDR
  * allocate dynamic storage of the appropriate size and return it.
  * bool_t       (*xdrproc_t)(XDR *, caddr_t *);
  */
-typedef bool_t (*xdrproc_t) (XDR *, void *,...);
+typedef bool_t (*xdrproc_t) (XDR *, void *);
 
 
 /*
diff --git a/libc/inet/rpc/xdr.c b/libc/inet/rpc/xdr.c
index bcf8901..cbd1904 100644
--- a/libc/inet/rpc/xdr.c
+++ b/libc/inet/rpc/xdr.c
@@ -631,14 +631,14 @@ xdr_union (XDR *xdrs, enum_t *dscmp, char *unp, const struct xdr_discrim *choice
   for (; choices->proc != NULL_xdrproc_t; choices++)
     {
       if (choices->value == dscm)
-	return (*(choices->proc)) (xdrs, unp, LASTUNSIGNED);
+	return (*(choices->proc)) (xdrs, unp);
     }
 
   /*
    * no match - execute the default xdr routine if there is one
    */
   return ((dfault == NULL_xdrproc_t) ? FALSE :
-	  (*dfault) (xdrs, unp, LASTUNSIGNED));
+	  (*dfault) (xdrs, unp));
 }
 libc_hidden_def(xdr_union)
 
diff --git a/libc/inet/rpc/xdr_array.c b/libc/inet/rpc/xdr_array.c
index 61603ed..8bdf64d 100644
--- a/libc/inet/rpc/xdr_array.c
+++ b/libc/inet/rpc/xdr_array.c
@@ -125,7 +125,7 @@ xdr_array (XDR *xdrs, caddr_t *addrp, u_int *sizep, u_int maxsize, u_int elsize,
    */
   for (i = 0; (i < c) && stat; i++)
     {
-      stat = (*elproc) (xdrs, target, LASTUNSIGNED);
+      stat = (*elproc) (xdrs, target);
       target += elsize;
     }
 
@@ -161,7 +161,7 @@ xdr_vector (XDR *xdrs, char *basep, u_int nelem, u_int elemsize,
   elptr = basep;
   for (i = 0; i < nelem; i++)
     {
-      if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED))
+      if (!(*xdr_elem) (xdrs, elptr))
 	{
 	  return FALSE;
 	}
diff --git a/libc/inet/rpc/xdr_reference.c b/libc/inet/rpc/xdr_reference.c
index 1c601fc..fb52953 100644
--- a/libc/inet/rpc/xdr_reference.c
+++ b/libc/inet/rpc/xdr_reference.c
@@ -97,7 +97,7 @@ xdr_reference (XDR *xdrs, caddr_t *pp, u_int size, xdrproc_t proc)
 	break;
       }
 
-  stat = (*proc) (xdrs, loc, LASTUNSIGNED);
+  stat = (*proc) (xdrs, loc);
 
   if (xdrs->x_op == XDR_FREE)
     {
-- 
1.7.3.4



More information about the uClibc mailing list