Module Name: src Committed By: christos Date: Tue Jan 26 16:23:27 UTC 2016
Modified Files: src/usr.bin/showmount: showmount.c Log Message: PR/50712: David Binderman: Fix memory leaks. To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/usr.bin/showmount/showmount.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/showmount/showmount.c diff -u src/usr.bin/showmount/showmount.c:1.21 src/usr.bin/showmount/showmount.c:1.22 --- src/usr.bin/showmount/showmount.c:1.21 Sat Oct 18 04:33:30 2014 +++ src/usr.bin/showmount/showmount.c Tue Jan 26 11:23:27 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: showmount.c,v 1.21 2014/10/18 08:33:30 snj Exp $ */ +/* $NetBSD: showmount.c,v 1.22 2016/01/26 16:23:27 christos Exp $ */ /* * Copyright (c) 1989, 1993, 1995 @@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 19 #if 0 static char sccsid[] = "@(#)showmount.c 8.3 (Berkeley) 3/29/95"; #endif -__RCSID("$NetBSD: showmount.c,v 1.21 2014/10/18 08:33:30 snj Exp $"); +__RCSID("$NetBSD: showmount.c,v 1.22 2016/01/26 16:23:27 christos Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -152,7 +152,7 @@ main(int argc, char **argv) if (rpcs & DODUMP) if ((estat = tcp_callrpc(host, RPCPROG_MNT, mntvers, - RPCMNT_DUMP, (xdrproc_t)xdr_void, (char *)0, + RPCMNT_DUMP, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_mntdump, (char *)&mntdump)) != 0) { fprintf(stderr, "showmount: Can't do Mountdump rpc: "); clnt_perrno(estat); @@ -160,7 +160,7 @@ main(int argc, char **argv) } if (rpcs & DOEXPORTS) if ((estat = tcp_callrpc(host, RPCPROG_MNT, mntvers, - RPCMNT_EXPORT, (xdrproc_t)xdr_void, (char *)0, + RPCMNT_EXPORT, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_exports, (char *)&exports)) != 0) { fprintf(stderr, "showmount: Can't do Exports rpc: "); clnt_perrno(estat); @@ -233,6 +233,16 @@ tcp_callrpc(const char *host, int prognu return rval; } +static void +mountlist_free(struct mountlist *ml) +{ + if (ml == NULL) + return; + mountlist_free(ml->ml_left); + mountlist_free(ml->ml_right); + free(ml); +} + /* * Xdr routine for retrieving the mount dump list */ @@ -244,20 +254,24 @@ xdr_mntdump(XDR *xdrsp, struct mountlist char *strp; otp = NULL; - *mlp = (struct mountlist *)0; + *mlp = NULL; if (!xdr_bool(xdrsp, &bool_int)) - return (0); + return 0; while (bool_int) { - mp = (struct mountlist *)malloc(sizeof(struct mountlist)); + mp = malloc(sizeof(*mp)); if (mp == NULL) - return (0); - mp->ml_left = mp->ml_right = (struct mountlist *)0; + goto out; + mp->ml_left = mp->ml_right = NULL; strp = mp->ml_host; - if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) - return (0); + if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) { + free(mp); + goto out; + } strp = mp->ml_dirp; - if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) - return (0); + if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) { + free(mp); + goto out; + } /* * Build a binary tree on sorted order of either host or dirp. @@ -274,7 +288,7 @@ xdr_mntdump(XDR *xdrsp, struct mountlist case ALL: if (val == 0) { if (val2 == 0) { - free((caddr_t)mp); + free(mp); goto next; } val = val2; @@ -282,14 +296,14 @@ xdr_mntdump(XDR *xdrsp, struct mountlist break; case DIRS: if (val2 == 0) { - free((caddr_t)mp); + free(mp); goto next; } val = val2; break; default: if (val == 0) { - free((caddr_t)mp); + free(mp); goto next; } break; @@ -306,9 +320,31 @@ xdr_mntdump(XDR *xdrsp, struct mountlist } next: if (!xdr_bool(xdrsp, &bool_int)) - return (0); + goto out; } - return (1); + return 1; +out: + mountlist_free(*mlp); + return 0; +} + +static void +grouplist_free(struct grouplist *gp) +{ + if (gp == NULL) + return; + grouplist_free(gp->gr_next); + free(gp); +} + +static void +exportslist_free(struct exportslist *ep) +{ + if (ep == NULL) + return; + exportslist_free(ep->ex_next); + grouplist_free(ep->ex_groups); + free(ep); } /* @@ -317,42 +353,47 @@ next: static int xdr_exports(XDR *xdrsp, struct exportslist **exp) { - struct exportslist *ep; + struct exportslist *ep = NULL; struct grouplist *gp; int bool_int, grpbool; char *strp; - *exp = (struct exportslist *)0; + *exp = NULL; if (!xdr_bool(xdrsp, &bool_int)) - return (0); + return 0; while (bool_int) { - ep = (struct exportslist *)malloc(sizeof(struct exportslist)); + ep = malloc(sizeof(*ep)); if (ep == NULL) - return (0); - ep->ex_groups = (struct grouplist *)0; + goto out; + ep->ex_groups = NULL; strp = ep->ex_dirp; if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) - return (0); + goto out; if (!xdr_bool(xdrsp, &grpbool)) - return (0); + goto out; while (grpbool) { - gp = (struct grouplist *)malloc(sizeof(struct grouplist)); + gp = malloc(sizeof(*gp)); if (gp == NULL) - return (0); - strp = gp->gr_name; - if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) - return (0); + goto out; gp->gr_next = ep->ex_groups; ep->ex_groups = gp; + strp = gp->gr_name; + if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) + goto out; if (!xdr_bool(xdrsp, &grpbool)) - return (0); + goto out; } ep->ex_next = *exp; *exp = ep; + ep = NULL; if (!xdr_bool(xdrsp, &bool_int)) - return (0); + goto out; } - return (1); + return 1; +out: + exportslist_free(ep); + exportslist_free(*exp); + return 0; } static void