Memleak fixes (#194)

* memleak: ipc_socket: properly dispose local-scoped strndup values

Leaking memory was only possible when using filesystem sockets (see
use_filesystem_sockets function) and either:
- client is deliberately disconnecting from a server (continued run
  imposes a risk of exhausting memory)
- server is deliberately disconnecting from its client (ditto, but
  more substantial risk due to the common shared-resource nature
  of the server)

Signed-off-by: Jan Pokorný <jpokorny@redhat.com>

* memleak: ipc_socket: properly dispose inter-function strdup values

Leaking memory was only possible when the server accepted the client,
but didn't get (or was too shy) to talk to it prior to proceeding with
a disconnect.

Signed-off-by: Jan Pokorný <jpokorny@redhat.com>

* ipc_socket: care to explain what's going on with file name inference

Related to the code parts at hand, there was an investigation/fix in
the past, initiated by "make check" failure on FreeBSD 9 [rhbz#1256701].
Unfortunately, not only the magic constant being modified was not
explained in 1908e6c, but (one can derive because of a lack of solid
background of what's going on here, which might have caused that),
it was modified incorrectly at one instance (see also [PR165 comment]),
which was then reinstated in 7ebcb3d.

So, finally de-mystify those magic constants.  Also break the symmetry
between the client/server further with depending on the canonical
"request socket" alias at the server side (the former worked equally but
it was unnecessarily confusing and there's a risk this artificial alias
will get removed in the future).

[rhbz#1256701] https://bugzilla.redhat.com/1256701
[PR165 comment] https://github.com/ClusterLabs/libqb/issues/165#issuecomment-142949541

Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
This commit is contained in:
Jan Pokorný 2017-05-18 12:29:15 +02:00 committed by Chrissie Caulfield
parent 536b4c25ed
commit 41ae3e1267

View File

@ -329,6 +329,9 @@ _finish_connecting(struct qb_ipc_one_way *one_way)
return error;
}
/* Beside disposing no longer needed value, this also signals that
we are done with connect-on-send arrangement at the server side
(i.e. for response and event channels). */
free(one_way->u.us.sock_name);
one_way->u.us.sock_name = NULL;
@ -353,7 +356,8 @@ qb_ipcc_us_disconnect(struct qb_ipcc_connection *c)
size_t length;
if (getsockname(c->response.u.us.sock, (struct sockaddr *)&un_addr, &un_addr_len) == 0) {
length = strlen(un_addr.sun_path);
base_name = strndup(un_addr.sun_path,length-9);
base_name = strndup(un_addr.sun_path,
length - /* strlen("-response") */ 9);
qb_util_log(LOG_DEBUG, "unlinking socket bound files with base_name=%s length=%d",base_name,length);
snprintf(sock_name,PATH_MAX,"%s-%s",base_name,"request");
qb_util_log(LOG_DEBUG, "unlink sock_name=%s",sock_name);
@ -367,6 +371,7 @@ qb_ipcc_us_disconnect(struct qb_ipcc_connection *c)
snprintf(sock_name,PATH_MAX,"%s-%s",base_name,"response");
qb_util_log(LOG_DEBUG, "unlink sock_name=%s",sock_name);
unlink(sock_name);
free(base_name);
}
}
qb_ipcc_us_sock_close(c->event.u.us.sock);
@ -715,15 +720,27 @@ qb_ipcs_us_disconnect(struct qb_ipcs_connection *c)
c->state == QB_IPCS_CONNECTION_ACTIVE) {
_sock_rm_from_mainloop(c);
/* Free the temporaries denoting which respective socket
name on the client's side to connect upon the first
send operation -- normally the variable is free'd once
the connection is established but there may have been
no chance for that. */
free(c->response.u.us.sock_name);
c->response.u.us.sock_name = NULL;
free(c->event.u.us.sock_name);
c->event.u.us.sock_name = NULL;
if (use_filesystem_sockets()) {
struct sockaddr_un un_addr;
socklen_t un_addr_len = sizeof(struct sockaddr_un);
char *base_name;
char sock_name[PATH_MAX];
size_t length;
if (getsockname(c->response.u.us.sock, (struct sockaddr *)&un_addr, &un_addr_len) == 0) {
if (getsockname(c->request.u.us.sock, (struct sockaddr *)&un_addr, &un_addr_len) == 0) {
length = strlen(un_addr.sun_path);
base_name = strndup(un_addr.sun_path,length-8);
base_name = strndup(un_addr.sun_path,
length - /* strlen("-request") */ 8);
qb_util_log(LOG_DEBUG, "unlinking socket bound files with base_name=%s length=%d",base_name,length);
snprintf(sock_name,PATH_MAX,"%s-%s",base_name,"request");
qb_util_log(LOG_DEBUG, "unlink sock_name=%s",sock_name);
@ -737,6 +754,7 @@ qb_ipcs_us_disconnect(struct qb_ipcs_connection *c)
snprintf(sock_name,PATH_MAX,"%s-%s",base_name,"response");
qb_util_log(LOG_DEBUG, "unlink sock_name=%s",sock_name);
unlink(sock_name);
free(base_name);
}
}
qb_ipcc_us_sock_close(c->setup.u.us.sock);