Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 Aug 2008 05:57:41 GMT
From:      Konrad Jankowski <konrad@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 146895 for review
Message-ID:  <200808080557.m785vf96003799@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=146895

Change 146895 by konrad@vspredator on 2008/08/08 05:56:42

	Fix stack overwriting and memory leak problem in Apple's code.

Affected files ...

.. //depot/projects/soc2008/konrad_collation/libc/gen/arc4random.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/gen/getbsize.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/Makefile.inc#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/Symbol.map#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/clnt_dg.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/clnt_perror.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/clnt_vc.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/rpcsec_gss_stub.c#1 branch
.. //depot/projects/soc2008/konrad_collation/libc/rpc/svc.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/svc_auth.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/svc_dg.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/svc_raw.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/rpc/svc_vc.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/stdio/vfwprintf.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/stdlib/getenv.c#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/string/strxfrm.c#7 edit
.. //depot/projects/soc2008/konrad_collation/libc/sys/jail.2#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/sys/socket.2#5 integrate
.. //depot/projects/soc2008/konrad_collation/libc/xdr/xdr_rec.c#5 integrate

Differences ...

==== //depot/projects/soc2008/konrad_collation/libc/gen/arc4random.c#5 (text+ko) ====

@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.23 2008/07/25 15:42:22 ache Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.24 2008/08/03 20:15:22 ache Exp $");
 
 #include "namespace.h"
 #include <sys/types.h>
@@ -55,6 +55,7 @@
 static pthread_mutex_t	arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
 
 #define	RANDOMDEV	"/dev/urandom"
+#define KEYSIZE		128
 #define	THREAD_LOCK()						\
 	do {							\
 		if (__isthreaded)				\
@@ -106,24 +107,27 @@
 static void
 arc4_stir(void)
 {
-	int     fd, n;
+	int done, fd, n;
 	struct {
-		struct timeval tv;
-		pid_t pid;
-		u_int8_t rnd[128 - sizeof(struct timeval) - sizeof(pid_t)];
-	}       rdat;
+		struct timeval	tv;
+		pid_t 		pid;
+		u_int8_t 	rnd[KEYSIZE];
+	} rdat;
 
-	gettimeofday(&rdat.tv, NULL);
-	rdat.pid = getpid();
 	fd = _open(RANDOMDEV, O_RDONLY, 0);
+	done = 0;
 	if (fd >= 0) {
-		(void) _read(fd, rdat.rnd, sizeof(rdat.rnd));
-		_close(fd);
+		if (_read(fd, &rdat, KEYSIZE) == KEYSIZE)
+			done = 1;
+		(void)_close(fd);
 	} 
-	/* fd < 0?  Ah, what the heck. We'll just take whatever was on the
-	 * stack... */
+	if (!done) {
+		(void)gettimeofday(&rdat.tv, NULL);
+		rdat.pid = getpid();
+		/* We'll just take whatever was on the stack too... */
+	}
 
-	arc4_addrandom((void *) &rdat, sizeof(rdat));
+	arc4_addrandom((u_char *)&rdat, KEYSIZE);
 
 	/*
 	 * Throw away the first N bytes of output, as suggested in the

==== //depot/projects/soc2008/konrad_collation/libc/gen/getbsize.c#5 (text+ko) ====

@@ -31,7 +31,7 @@
 static char sccsid[] = "@(#)getbsize.c	8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/gen/getbsize.c,v 1.8 2007/01/09 00:27:53 imp Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/gen/getbsize.c,v 1.9 2008/08/04 06:53:13 cperciva Exp $");
 
 #include <err.h>
 #include <stdio.h>
@@ -83,6 +83,7 @@
 		default:
 fmterr:			warnx("%s: unknown blocksize", p);
 			n = 512;
+			max = MAXB;
 			mul = 1;
 			break;
 		}

==== //depot/projects/soc2008/konrad_collation/libc/rpc/Makefile.inc#5 (text+ko) ====

@@ -1,5 +1,5 @@
 #	@(#)Makefile    5.11 (Berkeley) 9/6/90
-# $FreeBSD: src/lib/libc/rpc/Makefile.inc,v 1.28 2006/03/13 01:14:59 deischen Exp $
+# $FreeBSD: src/lib/libc/rpc/Makefile.inc,v 1.29 2008/08/06 14:02:05 dfr Exp $
 
 .PATH: ${.CURDIR}/rpc ${.CURDIR}/.
 SRCS+=	auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \
@@ -8,8 +8,9 @@
 	getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \
 	pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \
 	rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \
-	rpcb_st_xdr.c svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_generic.c \
-	svc_raw.c svc_run.c svc_simple.c svc_vc.c
+	rpcb_st_xdr.c rpcsec_gss_stub.c svc.c svc_auth.c svc_dg.c \
+	svc_auth_unix.c svc_generic.c svc_raw.c svc_run.c svc_simple.c \
+	svc_vc.c
 
 # Secure-RPC
 SRCS+=  auth_time.c auth_des.c authdes_prot.c des_crypt.c des_soft.c \

==== //depot/projects/soc2008/konrad_collation/libc/rpc/Symbol.map#5 (text) ====

@@ -1,5 +1,5 @@
 /*
- * $FreeBSD: src/lib/libc/rpc/Symbol.map,v 1.3 2007/05/31 13:01:34 deischen Exp $
+ * $FreeBSD: src/lib/libc/rpc/Symbol.map,v 1.4 2008/08/06 14:02:05 dfr Exp $
  */
 
 FBSD_1.0 {
@@ -244,4 +244,8 @@
 			 * Remove this hack if rpcinfo stops building with it.
 			 */
 	__svc_clean_idle;
+	__rpc_gss_unwrap;
+	__rpc_gss_unwrap_stub;
+	__rpc_gss_wrap;
+	__rpc_gss_wrap_stub;
 };

==== //depot/projects/soc2008/konrad_collation/libc/rpc/clnt_dg.c#5 (text+ko) ====

@@ -37,7 +37,7 @@
 static char sccsid[] = "@(#)clnt_dg.c 1.19 89/03/16 Copyr 1988 Sun Micro";
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/rpc/clnt_dg.c,v 1.19 2007/03/04 12:25:03 simon Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/rpc/clnt_dg.c,v 1.20 2008/08/06 14:02:05 dfr Exp $");
 
 /*
  * Implements a connectionless client side RPC.
@@ -52,6 +52,7 @@
 #include <sys/ioctl.h>
 #include <arpa/inet.h>
 #include <rpc/rpc.h>
+#include <rpc/rpcsec_gss.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
@@ -113,6 +114,8 @@
 
 /* VARIABLES PROTECTED BY clnt_fd_lock: dg_fd_locks, dg_cv */
 
+#define	MCALL_MSG_SIZE 24
+
 /*
  * Private data kept per client handle
  */
@@ -127,6 +130,7 @@
 	XDR			cu_outxdrs;
 	u_int			cu_xdrpos;
 	u_int			cu_sendsz;	/* send size */
+	char			cu_outhdr[MCALL_MSG_SIZE];
 	char			*cu_outbuf;
 	u_int			cu_recvsz;	/* recv size */
 	int			cu_async;
@@ -253,13 +257,16 @@
 	call_msg.rm_xid = __RPC_GETXID(&now);
 	call_msg.rm_call.cb_prog = program;
 	call_msg.rm_call.cb_vers = version;
-	xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
-	if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
+	xdrmem_create(&(cu->cu_outxdrs), cu->cu_outhdr, MCALL_MSG_SIZE,
+	    XDR_ENCODE);
+	if (! xdr_callhdr(&cu->cu_outxdrs, &call_msg)) {
 		rpc_createerr.cf_stat = RPC_CANTENCODEARGS;  /* XXX */
 		rpc_createerr.cf_error.re_errno = 0;
 		goto err2;
 	}
 	cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
+	XDR_DESTROY(&cu->cu_outxdrs);
+	xdrmem_create(&cu->cu_outxdrs, cu->cu_outbuf, sendsz, XDR_ENCODE);
 
 	/* XXX fvdl - do we still want this? */
 #if 0
@@ -312,6 +319,7 @@
 	XDR reply_xdrs;
 	bool_t ok;
 	int nrefreshes = 2;		/* number of times to refresh cred */
+	int nretries = 0;		/* number of times we retransmitted */
 	struct timeval timeout;
 	struct timeval retransmit_time;
 	struct timeval next_sendtime, starttime, time_waited, tv;
@@ -375,25 +383,37 @@
 	kin_len = 1;
 
 call_again:
-	xdrs = &(cu->cu_outxdrs);
-	if (cu->cu_async == TRUE && xargs == NULL)
-		goto get_reply;
-	xdrs->x_op = XDR_ENCODE;
-	XDR_SETPOS(xdrs, cu->cu_xdrpos);
 	/*
 	 * the transaction is the first thing in the out buffer
 	 * XXX Yes, and it's in network byte order, so we should to
 	 * be careful when we increment it, shouldn't we.
 	 */
-	xid = ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf));
+	xid = ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr));
 	xid++;
-	*(u_int32_t *)(void *)(cu->cu_outbuf) = htonl(xid);
+	*(u_int32_t *)(void *)(cu->cu_outhdr) = htonl(xid);
+call_again_same_xid:
+	xdrs = &(cu->cu_outxdrs);
+	if (cu->cu_async == TRUE && xargs == NULL)
+		goto get_reply;
+	xdrs->x_op = XDR_ENCODE;
+	XDR_SETPOS(xdrs, 0);
 
-	if ((! XDR_PUTINT32(xdrs, &proc)) ||
-	    (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
-	    (! (*xargs)(xdrs, argsp))) {
-		cu->cu_error.re_status = RPC_CANTENCODEARGS;
-		goto out;
+	if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
+		if ((! XDR_PUTBYTES(xdrs, cu->cu_outhdr, cu->cu_xdrpos)) ||
+		    (! XDR_PUTINT32(xdrs, &proc)) ||
+		    (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+		    (! (*xargs)(xdrs, argsp))) {
+			cu->cu_error.re_status = RPC_CANTENCODEARGS;
+			goto out;
+		}
+	} else {
+		*(uint32_t *) &cu->cu_outhdr[cu->cu_xdrpos] = htonl(proc);
+		if (!__rpc_gss_wrap(cl->cl_auth, cu->cu_outhdr,
+			cu->cu_xdrpos + sizeof(uint32_t),
+			xdrs, xargs, argsp)) {
+			cu->cu_error.re_status = RPC_CANTENCODEARGS;
+			goto out;
+		}
 	}
 	outlen = (size_t)XDR_GETPOS(xdrs);
 
@@ -420,8 +440,13 @@
 	 * (We assume that this is actually only executed once.)
 	 */
 	reply_msg.acpted_rply.ar_verf = _null_auth;
-	reply_msg.acpted_rply.ar_results.where = resultsp;
-	reply_msg.acpted_rply.ar_results.proc = xresults;
+	if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
+		reply_msg.acpted_rply.ar_results.where = resultsp;
+		reply_msg.acpted_rply.ar_results.proc = xresults;
+	} else {
+		reply_msg.acpted_rply.ar_results.where = NULL;
+		reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
+	}
 
 	for (;;) {
 		/* Decide how long to wait. */
@@ -483,7 +508,17 @@
 				    &retransmit_time);
 			timeradd(&next_sendtime, &retransmit_time,
 			    &next_sendtime);
-			goto send_again;
+			nretries++;
+
+			/*
+			 * When retransmitting a RPCSEC_GSS message,
+			 * we must use a new sequence number (handled
+			 * by __rpc_gss_wrap above).
+			 */
+			if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS)
+				goto send_again;
+			else
+				goto call_again_same_xid;
 		}
 	}
 	inlen = (socklen_t)recvlen;
@@ -505,8 +540,37 @@
 		if (cu->cu_error.re_status == RPC_SUCCESS) {
 			if (! AUTH_VALIDATE(cl->cl_auth,
 					    &reply_msg.acpted_rply.ar_verf)) {
+				if (nretries &&
+				    cl->cl_auth->ah_cred.oa_flavor
+				    == RPCSEC_GSS)
+					/*
+					 * If we retransmitted, its
+					 * possible that we will
+					 * receive a reply for one of
+					 * the earlier transmissions
+					 * (which will use an older
+					 * RPCSEC_GSS sequence
+					 * number). In this case, just
+					 * go back and listen for a
+					 * new reply. We could keep a
+					 * record of all the seq
+					 * numbers we have transmitted
+					 * so far so that we could
+					 * accept a reply for any of
+					 * them here.
+					 */
+					goto get_reply;
 				cu->cu_error.re_status = RPC_AUTHERROR;
 				cu->cu_error.re_why = AUTH_INVALIDRESP;
+			} else {
+				if (cl->cl_auth->ah_cred.oa_flavor
+				    == RPCSEC_GSS) {
+					if (!__rpc_gss_unwrap(cl->cl_auth,
+						&reply_xdrs, xresults,
+						resultsp))
+						cu->cu_error.re_status =
+							RPC_CANTDECODERES;
+				}
 			}
 			if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
 				xdrs->x_op = XDR_FREE;
@@ -670,12 +734,12 @@
 		 * This will get the xid of the PREVIOUS call
 		 */
 		*(u_int32_t *)info =
-		    ntohl(*(u_int32_t *)(void *)cu->cu_outbuf);
+		    ntohl(*(u_int32_t *)(void *)cu->cu_outhdr);
 		break;
 
 	case CLSET_XID:
 		/* This will set the xid of the NEXT call */
-		*(u_int32_t *)(void *)cu->cu_outbuf =
+		*(u_int32_t *)(void *)cu->cu_outhdr =
 		    htonl(*(u_int32_t *)info - 1);
 		/* decrement by 1 as clnt_dg_call() increments once */
 		break;
@@ -688,12 +752,12 @@
 		 * call_struct is changed
 		 */
 		*(u_int32_t *)info =
-		    ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
+		    ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr +
 		    4 * BYTES_PER_XDR_UNIT));
 		break;
 
 	case CLSET_VERS:
-		*(u_int32_t *)(void *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
+		*(u_int32_t *)(void *)(cu->cu_outhdr + 4 * BYTES_PER_XDR_UNIT)
 			= htonl(*(u_int32_t *)info);
 		break;
 
@@ -705,12 +769,12 @@
 		 * call_struct is changed
 		 */
 		*(u_int32_t *)info =
-		    ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
+		    ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr +
 		    3 * BYTES_PER_XDR_UNIT));
 		break;
 
 	case CLSET_PROG:
-		*(u_int32_t *)(void *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
+		*(u_int32_t *)(void *)(cu->cu_outhdr + 3 * BYTES_PER_XDR_UNIT)
 			= htonl(*(u_int32_t *)info);
 		break;
 	case CLSET_ASYNC:

==== //depot/projects/soc2008/konrad_collation/libc/rpc/clnt_perror.c#5 (text+ko) ====

@@ -35,7 +35,7 @@
 static char *sccsid = "@(#)clnt_perror.c	2.1 88/07/29 4.0 RPCSRC";
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/rpc/clnt_perror.c,v 1.17 2004/10/16 06:11:34 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/rpc/clnt_perror.c,v 1.18 2008/08/06 14:02:05 dfr Exp $");
 
 /*
  * clnt_perror.c
@@ -309,7 +309,14 @@
 	"Server rejected verifier", 		/* 4 - AUTH_REJECTEDVERF */
 	"Client credential too weak",		/* 5 - AUTH_TOOWEAK */
 	"Invalid server verifier",		/* 6 - AUTH_INVALIDRESP */
-	"Failed (unspecified error)"		/* 7 - AUTH_FAILED */
+	"Failed (unspecified error)",		/* 7 - AUTH_FAILED */
+	"Kerberos generic error",		/* 8 - AUTH_KERB_GENERIC*/
+	"Kerberos credential expired",		/* 9 - AUTH_TIMEEXPIRE */
+	"Bad kerberos ticket file",		/* 10 - AUTH_TKT_FILE */
+	"Can't decode kerberos authenticator",	/* 11 - AUTH_DECODE */
+	"Address wrong in kerberos ticket",	/* 12 - AUTH_NET_ADDR */
+	"GSS-API crediential problem",		/* 13 - RPCSEC_GSS_CREDPROBLEM */
+	"GSS-API context problem"		/* 14 - RPCSEC_GSS_CTXPROBLEM */
 };
 
 static char *

==== //depot/projects/soc2008/konrad_collation/libc/rpc/clnt_vc.c#5 (text+ko) ====

@@ -35,7 +35,7 @@
 static char sccsid3[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro";
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/rpc/clnt_vc.c,v 1.20 2006/09/09 22:18:57 mbr Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/rpc/clnt_vc.c,v 1.21 2008/08/06 14:02:05 dfr Exp $");
  
 /*
  * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
@@ -77,6 +77,7 @@
 #include <signal.h>
 
 #include <rpc/rpc.h>
+#include <rpc/rpcsec_gss.h>
 #include "un-namespace.h"
 #include "rpc_com.h"
 #include "mt_misc.h"
@@ -285,6 +286,7 @@
 	}
 	ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
 	XDR_DESTROY(&(ct->ct_xdrs));
+	assert(ct->ct_mpos + sizeof(uint32_t) <= MCALL_MSG_SIZE);
 
 	/*
 	 * Create a client handle which uses xdrrec for serialization
@@ -331,6 +333,7 @@
 	int refreshes = 2;
 	sigset_t mask, newmask;
 	int rpc_lock_value;
+	bool_t reply_stat;
 
 	assert(cl != NULL);
 
@@ -360,15 +363,28 @@
 	ct->ct_error.re_status = RPC_SUCCESS;
 	x_id = ntohl(--(*msg_x_id));
 
-	if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
-	    (! XDR_PUTINT32(xdrs, &proc)) ||
-	    (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
-	    (! (*xdr_args)(xdrs, args_ptr))) {
-		if (ct->ct_error.re_status == RPC_SUCCESS)
-			ct->ct_error.re_status = RPC_CANTENCODEARGS;
-		(void)xdrrec_endofrecord(xdrs, TRUE);
-		release_fd_lock(ct->ct_fd, mask);
-		return (ct->ct_error.re_status);
+	if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
+		if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
+		    (! XDR_PUTINT32(xdrs, &proc)) ||
+		    (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+		    (! (*xdr_args)(xdrs, args_ptr))) {
+			if (ct->ct_error.re_status == RPC_SUCCESS)
+				ct->ct_error.re_status = RPC_CANTENCODEARGS;
+			(void)xdrrec_endofrecord(xdrs, TRUE);
+			release_fd_lock(ct->ct_fd, mask);
+			return (ct->ct_error.re_status);
+		}
+	} else {
+		*(uint32_t *) &ct->ct_u.ct_mcallc[ct->ct_mpos] = htonl(proc);
+		if (! __rpc_gss_wrap(cl->cl_auth, ct->ct_u.ct_mcallc,
+			ct->ct_mpos + sizeof(uint32_t),
+			xdrs, xdr_args, args_ptr)) {
+			if (ct->ct_error.re_status == RPC_SUCCESS)
+				ct->ct_error.re_status = RPC_CANTENCODEARGS;
+			(void)xdrrec_endofrecord(xdrs, TRUE);
+			release_fd_lock(ct->ct_fd, mask);
+			return (ct->ct_error.re_status);
+		}
 	}
 	if (! xdrrec_endofrecord(xdrs, shipnow)) {
 		release_fd_lock(ct->ct_fd, mask);
@@ -419,9 +435,18 @@
 		    &reply_msg.acpted_rply.ar_verf)) {
 			ct->ct_error.re_status = RPC_AUTHERROR;
 			ct->ct_error.re_why = AUTH_INVALIDRESP;
-		} else if (! (*xdr_results)(xdrs, results_ptr)) {
-			if (ct->ct_error.re_status == RPC_SUCCESS)
-				ct->ct_error.re_status = RPC_CANTDECODERES;
+		} else {
+			if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
+				reply_stat = (*xdr_results)(xdrs, results_ptr);
+			} else {
+				reply_stat = __rpc_gss_unwrap(cl->cl_auth,
+				    xdrs, xdr_results, results_ptr);
+			}
+			if (! reply_stat) {
+				if (ct->ct_error.re_status == RPC_SUCCESS)
+					ct->ct_error.re_status =
+						RPC_CANTDECODERES;
+			}
 		}
 		/* free verifier ... */
 		if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {

==== //depot/projects/soc2008/konrad_collation/libc/rpc/svc.c#5 (text+ko) ====

@@ -34,7 +34,7 @@
 static char *sccsid = "@(#)svc.c	2.4 88/08/11 4.0 RPCSRC";
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/rpc/svc.c,v 1.24 2006/02/27 22:10:59 deischen Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/rpc/svc.c,v 1.25 2008/08/06 14:02:05 dfr Exp $");
 
 /*
  * svc.c, Server-side remote procedure call interface.
@@ -67,7 +67,7 @@
 #define	RQCRED_SIZE	400		/* this size is excessive */
 
 #define SVC_VERSQUIET 0x0001		/* keep quiet about vers mismatch */
-#define version_keepquiet(xp) ((u_long)(xp)->xp_p3 & SVC_VERSQUIET)
+#define version_keepquiet(xp) (SVC_EXT(xp)->xp_flags & SVC_VERSQUIET)
 
 #define max(a, b) (a > b ? a : b)
 
@@ -452,20 +452,16 @@
 __svc_versquiet_on(xprt)
 	SVCXPRT *xprt;
 {
-	u_long	tmp;
 
-	tmp = ((u_long) xprt->xp_p3) | SVC_VERSQUIET;
-	xprt->xp_p3 = tmp;
+	SVC_EXT(xprt)->xp_flags |= SVC_VERSQUIET;
 }
 
 void
 __svc_versquiet_off(xprt)
 	SVCXPRT *xprt;
 {
-	u_long	tmp;
 
-	tmp = ((u_long) xprt->xp_p3) & ~SVC_VERSQUIET;
-	xprt->xp_p3 = tmp;
+	SVC_EXT(xprt)->xp_flags &= ~SVC_VERSQUIET;
 }
 
 void
@@ -479,7 +475,8 @@
 __svc_versquiet_get(xprt)
 	SVCXPRT *xprt;
 {
-	return ((int) xprt->xp_p3) & SVC_VERSQUIET;
+
+	return (SVC_EXT(xprt)->xp_flags & SVC_VERSQUIET);
 }
 #endif
 
@@ -555,6 +552,39 @@
 	SVC_REPLY(xprt, &rply);
 }
 
+/*
+ * Allocate a new server transport structure. All fields are
+ * initialized to zero and xp_p3 is initialized to point at an
+ * extension structure to hold various flags and authentication
+ * parameters.
+ */
+SVCXPRT *
+svc_xprt_alloc()
+{
+	SVCXPRT *xprt;
+	SVCXPRT_EXT *ext;
+
+	xprt = mem_alloc(sizeof(SVCXPRT));
+	memset(xprt, 0, sizeof(SVCXPRT));
+	ext = mem_alloc(sizeof(SVCXPRT_EXT));
+	memset(ext, 0, sizeof(SVCXPRT_EXT));
+	xprt->xp_p3 = ext;
+
+	return (xprt);
+}
+
+/*
+ * Free a server transport structure.
+ */
+void
+svc_xprt_free(xprt)
+	SVCXPRT *xprt;
+{
+
+	mem_free(xprt->xp_p3, sizeof(SVCXPRT_EXT));
+	mem_free(xprt, sizeof(SVCXPRT));
+}
+
 /* ******************* SERVER INPUT STUFF ******************* */
 
 /*
@@ -643,7 +673,15 @@
 			r.rq_cred = msg.rm_call.cb_cred;
 			/* first authenticate the message */
 			if ((why = _authenticate(&r, &msg)) != AUTH_OK) {
-				svcerr_auth(xprt, why);
+				/*
+				 * RPCSEC_GSS uses this return code
+				 * for requests that form part of its
+				 * context establishment protocol and
+				 * should not be dispatched to the
+				 * application.
+				 */
+				if (why != RPCSEC_GSS_NODISPATCH)
+					svcerr_auth(xprt, why);
 				goto call_done;
 			}
 			/* now match message with a registered service*/
@@ -670,7 +708,7 @@
 			if (prog_found)
 				svcerr_progvers(xprt, low_vers, high_vers);
 			else
-				 svcerr_noprog(xprt);
+				svcerr_noprog(xprt);
 			/* Fall through to ... */
 		}
 		/*

==== //depot/projects/soc2008/konrad_collation/libc/rpc/svc_auth.c#5 (text+ko) ====

@@ -37,7 +37,7 @@
 static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/rpc/svc_auth.c,v 1.13 2006/02/27 22:10:59 deischen Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/rpc/svc_auth.c,v 1.14 2008/08/06 14:02:05 dfr Exp $");
 
 /*
  * svc_auth.c, Server-side rpc authenticator interface.
@@ -75,6 +75,8 @@
 };
 static struct authsvc *Auths = NULL;
 
+static struct svc_auth_ops svc_auth_null_ops;
+
 /*
  * The call rpc message, msg has been obtained from the wire.  The msg contains
  * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
@@ -105,6 +107,8 @@
 /* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */
 
 	rqst->rq_cred = msg->rm_call.cb_cred;
+	SVC_AUTH(rqst->rq_xprt).svc_ah_ops = &svc_auth_null_ops;
+	SVC_AUTH(rqst->rq_xprt).svc_ah_private = NULL;
 	rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
 	rqst->rq_xprt->xp_verf.oa_length = 0;
 	cred_flavor = rqst->rq_cred.oa_flavor;
@@ -143,6 +147,26 @@
 	return (AUTH_REJECTEDCRED);
 }
 
+/*
+ * A set of null auth methods used by any authentication protocols
+ * that don't need to inspect or modify the message body.
+ */
+static bool_t
+svcauth_null_wrap(auth, xdrs, xdr_func, xdr_ptr)
+	SVCAUTH *auth;
+	XDR *xdrs;
+	xdrproc_t xdr_func;
+	caddr_t xdr_ptr;
+{
+
+	return (xdr_func(xdrs, xdr_ptr));
+}
+
+static struct svc_auth_ops svc_auth_null_ops = {
+	svcauth_null_wrap,
+	svcauth_null_wrap,
+};
+
 /*ARGSUSED*/
 enum auth_stat
 _svcauth_null(rqst, msg)

==== //depot/projects/soc2008/konrad_collation/libc/rpc/svc_dg.c#5 (text+ko) ====

@@ -37,7 +37,7 @@
 #ident	"@(#)svc_dg.c	1.17	94/04/24 SMI"
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/rpc/svc_dg.c,v 1.8 2006/02/27 22:10:59 deischen Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/rpc/svc_dg.c,v 1.9 2008/08/06 14:02:05 dfr Exp $");
 
 /*
  * svc_dg.c, Server side for connectionless RPC.
@@ -51,6 +51,7 @@
 #include <sys/socket.h>
 #include <rpc/rpc.h>
 #include <rpc/svc_dg.h>
+#include <assert.h>
 #include <errno.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -125,10 +126,9 @@
 		return (NULL);
 	}
 
-	xprt = mem_alloc(sizeof (SVCXPRT));
+	xprt = svc_xprt_alloc();
 	if (xprt == NULL)
 		goto freedata;
-	memset(xprt, 0, sizeof (SVCXPRT));
 
 	su = mem_alloc(sizeof (*su));
 	if (su == NULL)
@@ -160,7 +160,7 @@
 	if (xprt) {
 		if (su)
 			(void) mem_free(su, sizeof (*su));
-		(void) mem_free(xprt, sizeof (SVCXPRT));
+		svc_xprt_free(xprt);
 	}
 	return (NULL);
 }
@@ -230,13 +230,28 @@
 {
 	struct svc_dg_data *su = su_data(xprt);
 	XDR *xdrs = &(su->su_xdrs);
-	bool_t stat = FALSE;
+	bool_t stat = TRUE;
 	size_t slen;
+	xdrproc_t xdr_proc;
+	caddr_t xdr_where;
 
 	xdrs->x_op = XDR_ENCODE;
 	XDR_SETPOS(xdrs, 0);
 	msg->rm_xid = su->su_xid;
-	if (xdr_replymsg(xdrs, msg)) {
+	if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
+	    msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
+		xdr_proc = msg->acpted_rply.ar_results.proc;
+		xdr_where = msg->acpted_rply.ar_results.where;
+		msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
+		msg->acpted_rply.ar_results.where = NULL;
+
+		if (!xdr_replymsg(xdrs, msg) ||
+		    !SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where))
+			stat = FALSE;
+	} else {
+		stat = xdr_replymsg(xdrs, msg);
+	}
+	if (stat) {
 		slen = XDR_GETPOS(xdrs);
 		if (_sendto(xprt->xp_fd, rpc_buffer(xprt), slen, 0,
 		    (struct sockaddr *)xprt->xp_rtaddr.buf,
@@ -255,7 +270,12 @@
 	xdrproc_t xdr_args;
 	void *args_ptr;
 {
-	return (*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr);
+	struct svc_dg_data *su;
+
+	assert(xprt != NULL);
+	su = su_data(xprt);
+	return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt),
+		&su->su_xdrs, xdr_args, args_ptr));
 }
 
 static bool_t
@@ -288,7 +308,7 @@
 		(void) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen);
 	if (xprt->xp_tp)
 		(void) free(xprt->xp_tp);
-	(void) mem_free(xprt, sizeof (SVCXPRT));
+	svc_xprt_free(xprt);
 }
 
 static bool_t

==== //depot/projects/soc2008/konrad_collation/libc/rpc/svc_raw.c#5 (text+ko) ====

@@ -38,7 +38,7 @@
 static char sccsid[] = "@(#)svc_raw.c 1.25 89/01/31 Copyr 1984 Sun Micro";
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/rpc/svc_raw.c,v 1.15 2006/02/27 22:10:59 deischen Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/rpc/svc_raw.c,v 1.16 2008/08/06 14:02:05 dfr Exp $");
 
 /*
  * svc_raw.c,   This a toy for simple testing and timing.
@@ -66,7 +66,7 @@
  */
 static struct svc_raw_private {
 	char	*raw_buf;	/* should be shared with the cl handle */
-	SVCXPRT	server;
+	SVCXPRT	*server;
 	XDR	xdr_stream;
 	char	verf_body[MAX_AUTH_BYTES];
 } *svc_raw_private;
@@ -99,17 +99,17 @@
 		if (__rpc_rawcombuf == NULL)
 			__rpc_rawcombuf = calloc(UDPMSGSIZE, sizeof (char));
 		srp->raw_buf = __rpc_rawcombuf; /* Share it with the client */
+		srp->server = svc_xprt_alloc();
 		svc_raw_private = srp;
 	}
-	srp->server.xp_fd = FD_SETSIZE;
-	srp->server.xp_port = 0;
-	srp->server.xp_p3 = NULL;
-	svc_raw_ops(&srp->server);
-	srp->server.xp_verf.oa_base = srp->verf_body;
+	srp->server->xp_fd = FD_SETSIZE;
+	srp->server->xp_port = 0;
+	svc_raw_ops(srp->server);
+	srp->server->xp_verf.oa_base = srp->verf_body;
 	xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
-	xprt_register(&srp->server);
+	xprt_register(srp->server);
 	mutex_unlock(&svcraw_lock);
-	return (&srp->server);
+	return (srp->server);
 }
 
 /*ARGSUSED*/
@@ -154,6 +154,9 @@
 {
 	struct svc_raw_private *srp;
 	XDR *xdrs;
+	bool_t stat;
+	xdrproc_t xdr_proc;
+	caddr_t xdr_where;
 
 	mutex_lock(&svcraw_lock);
 	srp = svc_raw_private;
@@ -166,7 +169,20 @@
 	xdrs = &srp->xdr_stream;
 	xdrs->x_op = XDR_ENCODE;
 	(void) XDR_SETPOS(xdrs, 0);
-	if (! xdr_replymsg(xdrs, msg)) {
+	if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
+	    msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
+		xdr_proc = msg->acpted_rply.ar_results.proc;
+		xdr_where = msg->acpted_rply.ar_results.where;
+		msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
+		msg->acpted_rply.ar_results.where = NULL;
+
+		if (!xdr_replymsg(xdrs, msg) ||
+		    !SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where))
+			stat = FALSE;
+	} else {
+		stat = xdr_replymsg(xdrs, msg);
+	}
+	if (!stat) {
 		return (FALSE);
 	}
 	(void) XDR_GETPOS(xdrs);  /* called just for overhead */
@@ -189,7 +205,9 @@
 		return (FALSE);
 	}
 	mutex_unlock(&svcraw_lock);
-	return (*xdr_args)(&srp->xdr_stream, args_ptr);
+
+	return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt), &srp->xdr_stream,
+		xdr_args, args_ptr));
 }
 
 /*ARGSUSED*/

==== //depot/projects/soc2008/konrad_collation/libc/rpc/svc_vc.c#5 (text+ko) ====

@@ -34,7 +34,7 @@
 static char *sccsid = "@(#)svc_tcp.c	2.2 88/08/01 4.0 RPCSRC";
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/rpc/svc_vc.c,v 1.27 2008/03/30 09:36:17 dfr Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/rpc/svc_vc.c,v 1.28 2008/08/06 14:02:05 dfr Exp $");
 
 /*
  * svc_vc.c, Server side for Connection Oriented based RPC. 
@@ -146,15 +146,12 @@
 	r->sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
 	r->recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
 	r->maxrec = __svc_maxrec;
-	xprt = mem_alloc(sizeof(SVCXPRT));
+	xprt = svc_xprt_alloc();
 	if (xprt == NULL) {
 		warnx("svc_vc_create: out of memory");
 		goto cleanup_svc_vc_create;
 	}
-	xprt->xp_tp = NULL;
 	xprt->xp_p1 = r;
-	xprt->xp_p2 = NULL;
-	xprt->xp_p3 = NULL;
 	xprt->xp_verf = _null_auth;
 	svc_vc_rendezvous_ops(xprt);
 	xprt->xp_port = (u_short)-1;	/* It is the rendezvouser */
@@ -259,16 +256,15 @@
  
 	assert(fd != -1);
 
-	xprt = mem_alloc(sizeof(SVCXPRT));
+	xprt = svc_xprt_alloc();
 	if (xprt == NULL) {
 		warnx("svc_vc: makefd_xprt: out of memory");
 		goto done;
 	}
-	memset(xprt, 0, sizeof *xprt);
 	cd = mem_alloc(sizeof(struct cf_conn));
 	if (cd == NULL) {
 		warnx("svc_tcp: makefd_xprt: out of memory");
-		mem_free(xprt, sizeof(SVCXPRT));
+		svc_xprt_free(xprt);
 		xprt = NULL;
 		goto done;
 	}
@@ -417,7 +413,7 @@
 		free(xprt->xp_tp);
 	if (xprt->xp_netid)
 		free(xprt->xp_netid);
-	mem_free(xprt, sizeof(SVCXPRT));
+	svc_xprt_free(xprt);
 }
 
 /*ARGSUSED*/
@@ -623,11 +619,12 @@
 	xdrproc_t xdr_args;
 	void *args_ptr;
 {
+	struct cf_conn *cd;
 
 	assert(xprt != NULL);
-	/* args_ptr may be NULL */
-	return ((*xdr_args)(&(((struct cf_conn *)(xprt->xp_p1))->xdrs),
-	    args_ptr));
+	cd = (struct cf_conn *)(xprt->xp_p1);
+	return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt),
+		&cd->xdrs, xdr_args, args_ptr));
 }
 
 static bool_t
@@ -655,6 +652,9 @@
 	struct cf_conn *cd;
 	XDR *xdrs;
 	bool_t rstat;
+	xdrproc_t xdr_proc;
+	caddr_t xdr_where;
+	u_int pos;
 
 	assert(xprt != NULL);
 	assert(msg != NULL);
@@ -664,8 +664,27 @@
 
 	xdrs->x_op = XDR_ENCODE;
 	msg->rm_xid = cd->x_id;
-	rstat = xdr_replymsg(xdrs, msg);
-	(void)xdrrec_endofrecord(xdrs, TRUE);
+	rstat = TRUE;
+	if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
+	    msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
+		xdr_proc = msg->acpted_rply.ar_results.proc;
+		xdr_where = msg->acpted_rply.ar_results.where;
+		msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
+		msg->acpted_rply.ar_results.where = NULL;
+
+		pos = XDR_GETPOS(xdrs);
+		if (!xdr_replymsg(xdrs, msg) ||
+		    !SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where)) {
+			XDR_SETPOS(xdrs, pos);
+			rstat = FALSE;
+		}
+	} else {
+		rstat = xdr_replymsg(xdrs, msg);
+	}
+
+	if (rstat)
+		(void)xdrrec_endofrecord(xdrs, TRUE);
+
 	return (rstat);
 }
 

==== //depot/projects/soc2008/konrad_collation/libc/stdio/vfwprintf.c#5 (text+ko) ====

@@ -36,7 +36,7 @@
 #endif /* LIBC_SCCS and not lint */
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.32 2008/06/29 22:54:26 das Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.33 2008/08/04 06:55:42 cperciva Exp $");
 
 /*
  * Actual wprintf innards.
@@ -333,8 +333,10 @@
 		}
 		if (nconv == (size_t)-1 || nconv == (size_t)-2)
 			return (NULL);
-	} else
+	} else {
 		insize = strlen(mbsarg);
+		nconv = 0;
+	}
 

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808080557.m785vf96003799>