1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

scd,w32: Fix socket resource leak.

* scd/scdaemon.c (main): Use gnupg_fd_t for socket, and use
assuan_sock_close for the socket allocated by assuan_sock_new.
(handle_connections): Use gnupg_fd_t for listen_fd.
Use assuan_sock_close for the socket by npth_accept.

--

GnuPG-bug-id: 5029
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2022-03-29 09:55:02 +09:00
parent 435861b9fb
commit a67a09be30

View File

@ -269,7 +269,7 @@ static gnupg_fd_t create_server_socket (const char *name,
assuan_sock_nonce_t *nonce); assuan_sock_nonce_t *nonce);
static void *start_connection_thread (void *arg); static void *start_connection_thread (void *arg);
static void handle_connections (int listen_fd); static void handle_connections (gnupg_fd_t listen_fd);
/* Pth wrapper function definitions. */ /* Pth wrapper function definitions. */
ASSUAN_SYSTEM_NPTH_IMPL; ASSUAN_SYSTEM_NPTH_IMPL;
@ -741,7 +741,7 @@ main (int argc, char **argv )
/* This is the simple pipe based server */ /* This is the simple pipe based server */
ctrl_t ctrl; ctrl_t ctrl;
npth_attr_t tattr; npth_attr_t tattr;
int fd = -1; gnupg_fd_t fd = GNUPG_INVALID_FD;
#ifndef HAVE_W32_SYSTEM #ifndef HAVE_W32_SYSTEM
{ {
@ -776,8 +776,8 @@ main (int argc, char **argv )
if (multi_server) if (multi_server)
{ {
socket_name = create_socket_name (SCDAEMON_SOCK_NAME); socket_name = create_socket_name (SCDAEMON_SOCK_NAME);
fd = FD2INT(create_server_socket (socket_name, fd = create_server_socket (socket_name,
&redir_socket_name, &socket_nonce)); &redir_socket_name, &socket_nonce);
} }
res = npth_attr_init (&tattr); res = npth_attr_init (&tattr);
@ -811,8 +811,8 @@ main (int argc, char **argv )
/* We run handle_connection to wait for the shutdown signal and /* We run handle_connection to wait for the shutdown signal and
to run the ticker stuff. */ to run the ticker stuff. */
handle_connections (fd); handle_connections (fd);
if (fd != -1) if (fd != GNUPG_INVALID_FD)
close (fd); assuan_sock_close (fd);
} }
else if (!is_daemon) else if (!is_daemon)
{ {
@ -821,7 +821,7 @@ main (int argc, char **argv )
} }
else else
{ /* Regular server mode */ { /* Regular server mode */
int fd; gnupg_fd_t fd;
#ifndef HAVE_W32_SYSTEM #ifndef HAVE_W32_SYSTEM
pid_t pid; pid_t pid;
int i; int i;
@ -829,8 +829,8 @@ main (int argc, char **argv )
/* Create the socket. */ /* Create the socket. */
socket_name = create_socket_name (SCDAEMON_SOCK_NAME); socket_name = create_socket_name (SCDAEMON_SOCK_NAME);
fd = FD2INT (create_server_socket (socket_name, fd = create_server_socket (socket_name,
&redir_socket_name, &socket_nonce)); &redir_socket_name, &socket_nonce);
fflush (NULL); fflush (NULL);
@ -946,7 +946,7 @@ main (int argc, char **argv )
handle_connections (fd); handle_connections (fd);
close (fd); assuan_sock_close (fd);
} }
xfree (config_filename); xfree (config_filename);
@ -1241,7 +1241,7 @@ scd_kick_the_loop (void)
in which case this code will only do regular timeouts and handle in which case this code will only do regular timeouts and handle
signals. */ signals. */
static void static void
handle_connections (int listen_fd) handle_connections (gnupg_fd_t listen_fd)
{ {
npth_attr_t tattr; npth_attr_t tattr;
struct sockaddr_un paddr; struct sockaddr_un paddr;
@ -1249,7 +1249,6 @@ handle_connections (int listen_fd)
fd_set fdset, read_fdset; fd_set fdset, read_fdset;
int nfd; int nfd;
int ret; int ret;
int fd;
struct timespec timeout; struct timespec timeout;
struct timespec *t; struct timespec *t;
int saved_errno; int saved_errno;
@ -1310,10 +1309,10 @@ handle_connections (int listen_fd)
FD_ZERO (&fdset); FD_ZERO (&fdset);
nfd = 0; nfd = 0;
if (listen_fd != -1) if (listen_fd != GNUPG_INVALID_FD)
{ {
FD_SET (listen_fd, &fdset); FD_SET (FD2INT (listen_fd), &fdset);
nfd = listen_fd; nfd = FD2INT (listen_fd);
} }
for (;;) for (;;)
@ -1331,7 +1330,7 @@ handle_connections (int listen_fd)
file descriptors to wait for, so that the select will be file descriptors to wait for, so that the select will be
used to just wait on a signal or timeout event. */ used to just wait on a signal or timeout event. */
FD_ZERO (&fdset); FD_ZERO (&fdset);
listen_fd = -1; listen_fd = GNUPG_INVALID_FD;
} }
periodical_check = scd_update_reader_status_file (); periodical_check = scd_update_reader_status_file ();
@ -1392,13 +1391,16 @@ handle_connections (int listen_fd)
} }
#endif #endif
if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset)) if (listen_fd != GNUPG_INVALID_FD
&& FD_ISSET (FD2INT (listen_fd), &read_fdset))
{ {
ctrl_t ctrl; ctrl_t ctrl;
gnupg_fd_t fd;
plen = sizeof paddr; plen = sizeof paddr;
fd = npth_accept (listen_fd, (struct sockaddr *)&paddr, &plen); fd = INT2FD (npth_accept (FD2INT (listen_fd),
if (fd == -1) (struct sockaddr *)&paddr, &plen));
if (fd == GNUPG_INVALID_FD)
{ {
log_error ("accept failed: %s\n", strerror (errno)); log_error ("accept failed: %s\n", strerror (errno));
} }
@ -1406,22 +1408,23 @@ handle_connections (int listen_fd)
{ {
log_error ("error allocating connection control data: %s\n", log_error ("error allocating connection control data: %s\n",
strerror (errno) ); strerror (errno) );
close (fd); assuan_sock_close (fd);
} }
else else
{ {
char threadname[50]; char threadname[50];
npth_t thread; npth_t thread;
snprintf (threadname, sizeof threadname, "conn fd=%d", fd); snprintf (threadname, sizeof threadname, "conn fd=%d",
ctrl->thread_startup.fd = INT2FD (fd); FD2INT (fd));
ctrl->thread_startup.fd = fd;
ret = npth_create (&thread, &tattr, start_connection_thread, ctrl); ret = npth_create (&thread, &tattr, start_connection_thread, ctrl);
if (ret) if (ret)
{ {
log_error ("error spawning connection handler: %s\n", log_error ("error spawning connection handler: %s\n",
strerror (ret)); strerror (ret));
xfree (ctrl); xfree (ctrl);
close (fd); assuan_sock_close (fd);
} }
else else
npth_setname_np (thread, threadname); npth_setname_np (thread, threadname);