iprop: Fix leak in ipropd-master

This commit is contained in:
Nicolas Williams
2023-01-03 20:47:53 -06:00
parent 8c23a706f3
commit a791f45e62

View File

@@ -48,6 +48,7 @@ static int time_before_gone;
const char *master_hostname; const char *master_hostname;
const char *pidfile_basename; const char *pidfile_basename;
static char hostname[128];
static krb5_socket_t static krb5_socket_t
make_signal_socket (krb5_context context) make_signal_socket (krb5_context context)
@@ -275,12 +276,11 @@ static void
add_slave (krb5_context context, krb5_keytab keytab, slave **root, add_slave (krb5_context context, krb5_keytab keytab, slave **root,
krb5_socket_t fd) krb5_socket_t fd)
{ {
krb5_principal server; krb5_principal server = NULL;
krb5_error_code ret; krb5_error_code ret;
slave *s; slave *s;
socklen_t addr_len; socklen_t addr_len;
krb5_ticket *ticket = NULL; krb5_ticket *ticket = NULL;
char hostname[128];
s = calloc(1, sizeof(*s)); s = calloc(1, sizeof(*s));
if (s == NULL) { if (s == NULL) {
@@ -301,10 +301,18 @@ add_slave (krb5_context context, krb5_keytab keytab, slave **root,
goto error; goto error;
} }
if (master_hostname) /*
strlcpy(hostname, master_hostname, sizeof(hostname)); * We write message lengths separately from the payload, and may do
else * back-to-back small writes when flushing pending input and then a new
gethostname(hostname, sizeof(hostname)); * update. Avoid Nagle delays.
*/
#if defined(IPPROTO_TCP) && defined(TCP_NODELAY)
{
int nodelay = 1;
(void) setsockopt(s->fd, IPPROTO_TCP, TCP_NODELAY,
(void *)&nodelay, sizeof(nodelay));
}
#endif
ret = krb5_sname_to_principal (context, hostname, IPROP_NAME, ret = krb5_sname_to_principal (context, hostname, IPROP_NAME,
KRB5_NT_SRV_HST, &server); KRB5_NT_SRV_HST, &server);
@@ -331,26 +339,11 @@ add_slave (krb5_context context, krb5_keytab keytab, slave **root,
*/ */
socket_set_nonblocking(s->fd, 1); socket_set_nonblocking(s->fd, 1);
/*
* We write message lengths separately from the payload, and may do
* back-to-back small writes when flushing pending input and then a new
* update. Avoid Nagle delays.
*/
#if defined(IPPROTO_TCP) && defined(TCP_NODELAY)
{
int nodelay = 1;
(void) setsockopt(s->fd, IPPROTO_TCP, TCP_NODELAY,
(void *)&nodelay, sizeof(nodelay));
}
#endif
krb5_free_principal (context, server);
if (ret) { if (ret) {
krb5_warn (context, ret, "krb5_recvauth"); krb5_warn (context, ret, "krb5_recvauth");
goto error; goto error;
} }
ret = krb5_unparse_name (context, ticket->client, &s->name); ret = krb5_unparse_name (context, ticket->client, &s->name);
krb5_free_ticket (context, ticket);
if (ret) { if (ret) {
krb5_warn (context, ret, "krb5_unparse_name"); krb5_warn (context, ret, "krb5_unparse_name");
goto error; goto error;
@@ -378,6 +371,8 @@ add_slave (krb5_context context, krb5_keytab keytab, slave **root,
} }
} }
krb5_free_principal(context, server);
krb5_free_ticket(context, ticket);
krb5_warnx (context, "connection from %s", s->name); krb5_warnx (context, "connection from %s", s->name);
s->version = 0; s->version = 0;
@@ -389,6 +384,9 @@ add_slave (krb5_context context, krb5_keytab keytab, slave **root,
return; return;
error: error:
remove_slave(context, s, root); remove_slave(context, s, root);
krb5_free_principal(context, server);
if (ticket)
krb5_free_ticket(context, ticket);
} }
static int static int
@@ -1587,6 +1585,20 @@ main(int argc, char **argv)
exit(0); exit(0);
} }
memset(hostname, 0, sizeof(hostname));
if (master_hostname &&
strlcpy(hostname, master_hostname,
sizeof(hostname)) >= sizeof(hostname)) {
errx(1, "Hostname too long: %s", master_hostname);
} else if (master_hostname == NULL) {
if (gethostname(hostname, sizeof(hostname)) == -1)
err(1, "Could not get hostname");
if (hostname[sizeof(hostname) - 1] != '\0')
errx(1, "Hostname too long %.*s...",
(int)sizeof(hostname), hostname);
}
if (detach_from_console && daemon_child == -1) if (detach_from_console && daemon_child == -1)
daemon_child = roken_detach_prep(argc, argv, "--daemon-child"); daemon_child = roken_detach_prep(argc, argv, "--daemon-child");
rk_pidfile(pidfile_basename); rk_pidfile(pidfile_basename);