diff --git a/CHANGELOG b/CHANGELOG index c7d7483..e9aeec1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,6 +18,7 @@ - fix file handle leak in nsswitch parser. - fix memory leak in mount and expire request processing. - add additional check to prevent running of cancelled tasks. +- fix potential file handle leakage in rpc_subs.c for some failure cases. 1/9/2006 autofs-5.0.1 rc2 ------------------------- diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c index da2a396..342d33a 100644 --- a/lib/rpc_subs.c +++ b/lib/rpc_subs.c @@ -87,7 +87,7 @@ static CLIENT *create_udp_client(struct int err = ghn_errno == -1 ? errno : ghn_errno; char *estr = strerror_r(err, buf, HOST_ENT_BUF_SIZE); error(LOGOPT_ANY, "hostname lookup failed: %s", estr); - return NULL; + goto out_close; } memcpy(&raddr.sin_addr.s_addr, php->h_addr, php->h_length); @@ -120,10 +120,24 @@ got_addr: info->timeout, &fd, info->send_sz, info->recv_sz); - if (client) - clnt_control(client, CLSET_FD_CLOSE, NULL); + if (!client) { + info->client = NULL; + goto out_close; + } + + /* Close socket fd on destroy, as is default for rpcowned fds */ + if (!clnt_control(client, CLSET_FD_CLOSE, NULL)) { + clnt_destroy(client); + info->client = NULL; + goto out_close; + } return client; + +out_close: + if (fd != -1) + close(fd); + return NULL; } int rpc_udp_getclient(struct conn_info *info, @@ -276,7 +290,7 @@ static CLIENT *create_tcp_client(struct int err = ghn_errno == -1 ? errno : ghn_errno; char *estr = strerror_r(err, buf, HOST_ENT_BUF_SIZE); error(LOGOPT_ANY, "hostname lookup failed: %s", estr); - return NULL; + goto out_close; } memcpy(&addr.sin_addr.s_addr, php->h_addr, php->h_length); @@ -296,19 +310,24 @@ got_addr: client = clnttcp_create(&addr, info->program, info->version, &fd, info->send_sz, info->recv_sz); - if (!client) + + if (!client) { + info->client = NULL; goto out_close; + } /* Close socket fd on destroy, as is default for rpcowned fds */ if (!clnt_control(client, CLSET_FD_CLOSE, NULL)) { clnt_destroy(client); + info->client = NULL; goto out_close; } return client; out_close: - close(fd); + if (fd != -1) + close(fd); return NULL; } @@ -759,8 +778,10 @@ static int masked_match(const char *addr int i = 0; ret = inet_aton(mask, &maddr.sin_addr); - if (!ret) + if (!ret) { + close(sock); return 0; + } ma = ntohl((uint32_t) maddr.sin_addr.s_addr); while (!(ma & 1)) { diff --git a/modules/replicated.c b/modules/replicated.c index 9336cf8..27d3565 100644 --- a/modules/replicated.c +++ b/modules/replicated.c @@ -344,16 +344,16 @@ static unsigned int get_nfs_info(struct parms.pm_prog = NFS_PROGRAM; - status = rpc_portmap_getclient(pm_info, - host->name, proto, RPC_CLOSE_DEFAULT); - if (!status) - return 0; - /* Try to prode UDP first to conserve socket space */ rpc_info->proto = getprotobyname(proto); if (!rpc_info->proto) return 0; + status = rpc_portmap_getclient(pm_info, + host->name, proto, RPC_CLOSE_DEFAULT); + if (!status) + return 0; + parms.pm_prot = rpc_info->proto->p_proto; #if 0 if (!(version & NFS4_REQUESTED)) @@ -519,15 +519,15 @@ static int get_supported_ver_and_cost(st vers = version; } + rpc_info.proto = getprotobyname(proto); + if (!rpc_info.proto) + return 0; + status = rpc_portmap_getclient(&pm_info, host->name, proto, RPC_CLOSE_DEFAULT); if (!status) return 0; - rpc_info.proto = getprotobyname(proto); - if (!rpc_info.proto) - return 0; - parms.pm_prot = rpc_info.proto->p_proto; status = 0;