]> granicus.if.org Git - libtirpc/commitdiff
Fix a crash in clntunix_create
authorOlaf Kirch <okir@suse.de>
Tue, 16 Dec 2014 18:48:52 +0000 (13:48 -0500)
committerSteve Dickson <steved@redhat.com>
Tue, 16 Dec 2014 19:04:33 +0000 (14:04 -0500)
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 <okir@suse.de>
Signed-off-by: Steve Dickson <steved@redhat.com>
src/rpc_soc.c

index 338edbbfebcd8b986c4343c691c24d33218fd870..e146ed40b1d2d1172d490489a8d057daa0efbbb1 100644 (file)
@@ -564,16 +564,12 @@ clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
        u_int sendsz;
        u_int recvsz;
 {
-       struct netbuf *svcaddr;
-       CLIENT *cl;
+       struct netbuf svcaddr = {0, 0, NULL};
+       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, sendsz, recvsz)
                        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);
 }