diff --git a/src/clnt_dg.c b/src/clnt_dg.c index 04a2aba..eb5467f 100644 --- a/src/clnt_dg.c +++ b/src/clnt_dg.c @@ -160,15 +160,22 @@ clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz) thr_sigsetmask(SIG_SETMASK, &newmask, &mask); mutex_lock(&clnt_fd_lock); if (dg_fd_locks == (int *) NULL) { - int cv_allocsz; - size_t fd_allocsz; - int dtbsize = __rpc_dtbsize(); + size_t cv_allocsz, fd_allocsz; + unsigned int dtbsize = __rpc_dtbsize(); + + if ( (size_t) dtbsize > SIZE_MAX/sizeof(cond_t)) { + mutex_unlock(&clnt_fd_lock); + thr_sigsetmask(SIG_SETMASK, &(mask), NULL); + errno = EOVERFLOW; + goto err1; + } fd_allocsz = dtbsize * sizeof (int); dg_fd_locks = (int *) mem_alloc(fd_allocsz); if (dg_fd_locks == (int *) NULL) { mutex_unlock(&clnt_fd_lock); thr_sigsetmask(SIG_SETMASK, &(mask), NULL); + errno = ENOMEM; goto err1; } else memset(dg_fd_locks, '\0', fd_allocsz); @@ -180,6 +187,7 @@ clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz) dg_fd_locks = (int *) NULL; mutex_unlock(&clnt_fd_lock); thr_sigsetmask(SIG_SETMASK, &(mask), NULL); + errno = ENOMEM; goto err1; } else { int i; diff --git a/src/clnt_generic.c b/src/clnt_generic.c index e5a314f..3f3dabf 100644 --- a/src/clnt_generic.c +++ b/src/clnt_generic.c @@ -47,7 +47,6 @@ extern bool_t __rpc_is_local_host(const char *); int __rpc_raise_fd(int); -extern int __binddynport(int fd); #ifndef NETIDLEN #define NETIDLEN 32 @@ -341,8 +340,7 @@ clnt_tli_create(int fd, const struct netconfig *nconf, servtype = nconf->nc_semantics; if (!__rpc_fd2sockinfo(fd, &si)) goto err; - if (__binddynport(fd) == -1) - goto err; + bindresvport(fd, NULL); } else { if (!__rpc_fd2sockinfo(fd, &si)) goto err; diff --git a/src/clnt_vc.c b/src/clnt_vc.c index 6098c3a..3d775c7 100644 --- a/src/clnt_vc.c +++ b/src/clnt_vc.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include "rpc_com.h" @@ -201,14 +202,25 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz) thr_sigsetmask(SIG_SETMASK, &newmask, &mask); mutex_lock(&clnt_fd_lock); if (vc_fd_locks == (int *) NULL) { - int cv_allocsz, fd_allocsz; - int dtbsize = __rpc_dtbsize(); + size_t cv_allocsz, fd_allocsz; + unsigned int dtbsize = __rpc_dtbsize(); + struct rpc_createerr *ce = &get_rpc_createerr(); + + if ( (size_t) dtbsize > SIZE_MAX/sizeof(cond_t)) { + mutex_unlock(&clnt_fd_lock); + thr_sigsetmask(SIG_SETMASK, &(mask), NULL); + ce->cf_stat = RPC_SYSTEMERROR; + ce->cf_error.re_errno = EOVERFLOW; + goto err; + } fd_allocsz = dtbsize * sizeof (int); vc_fd_locks = (int *) mem_alloc(fd_allocsz); if (vc_fd_locks == (int *) NULL) { mutex_unlock(&clnt_fd_lock); thr_sigsetmask(SIG_SETMASK, &(mask), NULL); + ce->cf_stat = RPC_SYSTEMERROR; + ce->cf_error.re_errno = ENOMEM; goto err; } else memset(vc_fd_locks, '\0', fd_allocsz); @@ -221,6 +233,8 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz) vc_fd_locks = (int *) NULL; mutex_unlock(&clnt_fd_lock); thr_sigsetmask(SIG_SETMASK, &(mask), NULL); + ce->cf_stat = RPC_SYSTEMERROR; + ce->cf_error.re_errno = ENOMEM; goto err; } else { int i; diff --git a/src/rpc_soc.c b/src/rpc_soc.c index af6c482..5a6eeb7 100644 --- a/src/rpc_soc.c +++ b/src/rpc_soc.c @@ -67,8 +67,6 @@ extern mutex_t rpcsoc_lock; -extern int __binddynport(int fd); - static CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, int *, u_int, u_int, char *, int); static SVCXPRT *svc_com_create(int, u_int, u_int, char *); @@ -147,8 +145,7 @@ clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp, flags) bindaddr.maxlen = bindaddr.len = sizeof (struct sockaddr_in); bindaddr.buf = raddr; - if (__binddynport(fd) == -1) - goto err; + bindresvport(fd, NULL); cl = clnt_tli_create(fd, nconf, &bindaddr, prog, vers, sendsz, recvsz); if (cl) { diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c index a94fc73..e45736a 100644 --- a/src/rpcb_clnt.c +++ b/src/rpcb_clnt.c @@ -752,7 +752,7 @@ __try_protocol_version_2(program, version, nconf, host, tp) client = getpmaphandle(nconf, host, &parms.r_addr); if (client == NULL) - return (NULL); + goto error; /* * Set retry timeout. @@ -771,11 +771,11 @@ __try_protocol_version_2(program, version, nconf, host, tp) if (clnt_st != RPC_SUCCESS) { rpc_createerr.cf_stat = RPC_PMAPFAILURE; clnt_geterr(client, &rpc_createerr.cf_error); - return (NULL); + goto error; } else if (port == 0) { pmapaddress = NULL; rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; - return (NULL); + goto error; } port = htons(port); CLNT_CONTROL(client, CLGET_SVC_ADDR, (char *)&remote); @@ -789,14 +789,24 @@ __try_protocol_version_2(program, version, nconf, host, tp) free(pmapaddress); pmapaddress = NULL; } - return (NULL); + goto error; } memcpy(pmapaddress->buf, remote.buf, remote.len); memcpy(&((char *)pmapaddress->buf)[sizeof (short)], (char *)(void *)&port, sizeof (short)); pmapaddress->len = pmapaddress->maxlen = remote.len; + CLNT_DESTROY(client); return pmapaddress; + +error: + if (client) { + CLNT_DESTROY(client); + client = NULL; + + } + return (NULL); + } #endif @@ -836,6 +846,7 @@ __rpcb_findaddr_timed(program, version, nconf, host, clpp, tp) struct netbuf *address = NULL; rpcvers_t start_vers = RPCBVERS4; struct netbuf servaddr; + struct rpc_err rpcerr; /* parameter checking */ if (nconf == NULL) { @@ -892,7 +903,8 @@ __rpcb_findaddr_timed(program, version, nconf, host, clpp, tp) clnt_st = CLNT_CALL(client, (rpcproc_t)RPCBPROC_GETADDR, (xdrproc_t) xdr_rpcb, (char *)(void *)&parms, (xdrproc_t) xdr_wrapstring, (char *)(void *) &ua, *tp); - if (clnt_st == RPC_SUCCESS) { + switch (clnt_st) { + case RPC_SUCCESS: if ((ua == NULL) || (ua[0] == 0)) { /* address unknown */ rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; @@ -914,12 +926,15 @@ __rpcb_findaddr_timed(program, version, nconf, host, clpp, tp) (char *)(void *)&servaddr); __rpc_fixup_addr(address, &servaddr); goto done; - } else if (clnt_st == RPC_PROGVERSMISMATCH) { - struct rpc_err rpcerr; + case RPC_PROGVERSMISMATCH: clnt_geterr(client, &rpcerr); if (rpcerr.re_vers.low > RPCBVERS4) goto error; /* a new version, can't handle */ - } else if (clnt_st != RPC_PROGUNAVAIL) { + /* Try the next lower version */ + case RPC_PROGUNAVAIL: + case RPC_CANTDECODEARGS: + break; + default: /* Cant handle this error */ rpc_createerr.cf_stat = clnt_st; clnt_geterr(client, &rpc_createerr.cf_error); @@ -929,7 +944,7 @@ __rpcb_findaddr_timed(program, version, nconf, host, clpp, tp) #ifdef PORTMAP /* Try version 2 for TCP or UDP */ if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { - address = __try_protocol_version_2(program, 2, nconf, host, tp); + address = __try_protocol_version_2(program, version, nconf, host, tp); if (address == NULL) goto error; } diff --git a/src/xdr_stdio.c b/src/xdr_stdio.c index 4410262..846c7bf 100644 --- a/src/xdr_stdio.c +++ b/src/xdr_stdio.c @@ -38,6 +38,7 @@ */ #include +#include #include #include @@ -103,10 +104,12 @@ xdrstdio_getlong(xdrs, lp) XDR *xdrs; long *lp; { + int32_t mycopy; - if (fread(lp, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1) + if (fread(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1) return (FALSE); - *lp = (long)ntohl((u_int32_t)*lp); + + *lp = (long)ntohl(mycopy); return (TRUE); } @@ -115,8 +118,14 @@ xdrstdio_putlong(xdrs, lp) XDR *xdrs; const long *lp; { - long mycopy = (long)htonl((u_int32_t)*lp); + int32_t mycopy; + +#if defined(_LP64) + if ((*lp > UINT32_MAX) || (*lp < INT32_MIN)) + return (FALSE); +#endif + mycopy = (int32_t)htonl((int32_t)*lp); if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1) return (FALSE); return (TRUE);