commands: fix state socket implementation

Remove dead state clients from state client list. Consider the following scenario: 01 start container 02 issue shutdown request 03 state_client_fd is added to lxc_handler 03 container doesn't respond to shutdown request 04 user aborts shutdown request 05 lxc_cmd_fd_cleanup() removes state_client_fd from lxc_mainloop 06 invalid state_client_fd is still recorded in the lxc_handler 07 user issues lxc_cmd_stop() request via SIGKILL 08 container reaches STOPPED state and sends message to state_client_fd 09 state_client_fd number has been reused by lxc_cmd_stop_callback() 10 invalid data gets dumped to lxc_cmd_stop() Reproducer: Set an invalid shutdown signal to which the init system does not respond with a shutdown via lxc.signal.halt e.g. "lxc.signal.halt = SIGUSR1". Then do: 1. start container root@conventiont|~ > lxc-start -n a1 2. try to shutdown container root@conventiont|~ > lxc-stop -n a1 3. abort shutdown ^C 4. SIGKILL the container (lxc.signal.stop = SIGKILL) root@conventiont|~ > lxc-stop -n a1 -k lxc-stop: a1: commands.c: lxc_cmd_rsp_recv: 165 File too large - Response data for command "stop" is too long: 12641 bytes > 8192 To not let this happen we remove the state_client_fd from the lxc_handler when we detect a cleanup event in lxc_cmd_fd_cleanup(). Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 28c42dfc
......@@ -948,11 +948,32 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
}
static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
struct lxc_epoll_descr *descr)
struct lxc_epoll_descr *descr,
const lxc_cmd_t cmd)
{
struct state_client *client;
struct lxc_list *cur, *next;
lxc_console_free(handler->conf, fd);
lxc_mainloop_del_handler(descr, fd);
close(fd);
if (cmd != LXC_CMD_ADD_STATE_CLIENT) {
close(fd);
return;
}
process_lock();
lxc_list_for_each_safe(cur, &handler->state_clients, next) {
client = cur->elem;
if (client->clientfd != fd)
continue;
/* kick client from list */
close(client->clientfd);
lxc_list_del(cur);
free(cur->elem);
free(cur);
}
process_unlock();
}
static int lxc_cmd_handler(int fd, uint32_t events, void *data,
......@@ -1021,7 +1042,7 @@ out:
return ret;
out_close:
lxc_cmd_fd_cleanup(fd, handler, descr);
lxc_cmd_fd_cleanup(fd, handler, descr, req.cmd);
goto out;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment