commit 79bf7950d8c8bc9d323887ba0e5fa7555aa6644a Author: Olaf Kirch Date: Tue Feb 8 10:21:16 2011 +0100 Fix a crash in clntunix_create Programs using clntunix_create would abort because glibc detected an attempt to free a bad pointer. It turns out that clntunix_create has two bugs: - it sets up a struct netbuf to hold the sockaddr_un passed into the function, but instead of copying the data, it just assigns the sockaddr pointer - and eventually tries to free that pointer. - when setting up the netbuf, it uses sizeof(raddr) instead of sizeof(*raddr). Instead of doing the trivial fixes, I changed the function to use the __rpc_set_netbuf utility function. While I was at it, I removed an unused local variable. Signed-off-by: Olaf Kirch --- src/rpc_soc.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) Index: libtirpc-0.2.4-rc2/src/rpc_soc.c =================================================================== --- libtirpc-0.2.4-rc2.orig/src/rpc_soc.c +++ libtirpc-0.2.4-rc2/src/rpc_soc.c @@ -564,16 +564,12 @@ clntunix_create(raddr, prog, vers, sockp u_int sendsz; u_int recvsz; { - struct netbuf *svcaddr; - CLIENT *cl; + struct netbuf svcaddr; + CLIENT *cl = NULL; int len; - cl = NULL; - svcaddr = NULL; - if (((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || - ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { - if (svcaddr != NULL) - free(svcaddr); + memset(&svcaddr, 0, sizeof(svcaddr)); + if (__rpc_set_netbuf(&svcaddr, raddr, sizeof(*raddr)) == NULL) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; return(cl); @@ -590,14 +586,10 @@ clntunix_create(raddr, prog, vers, sockp goto done; } } - svcaddr->buf = raddr; - svcaddr->len = sizeof(raddr); - svcaddr->maxlen = sizeof (struct sockaddr_un); - cl = clnt_vc_create(*sockp, svcaddr, prog, + cl = clnt_vc_create(*sockp, &svcaddr, prog, vers, sendsz, recvsz); done: - free(svcaddr->buf); - free(svcaddr); + free(svcaddr.buf); return(cl); }