]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
terminal: prevent memory leak for lxc_terminal_state 3171/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 25 Oct 2019 09:45:55 +0000 (11:45 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 25 Oct 2019 13:14:12 +0000 (15:14 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/terminal.c
src/lxc/terminal.h

index 578de68aa8710a4bf701c9ba00117189d621d846..13953cf790e4f04f2065f51e1d0a0da01dd28b57 100644 (file)
@@ -115,10 +115,10 @@ int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata,
 
 struct lxc_terminal_state *lxc_terminal_signal_init(int srcfd, int dstfd)
 {
-       int ret;
+       __do_free struct lxc_terminal_state *ts = NULL;
        bool istty = false;
+       int ret;
        sigset_t mask;
-       struct lxc_terminal_state *ts;
 
        ts = malloc(sizeof(*ts));
        if (!ts)
@@ -177,16 +177,23 @@ on_error:
        return ts;
 }
 
-void lxc_terminal_signal_fini(struct lxc_terminal_state *ts)
+void lxc_terminal_signal_fini(struct lxc_terminal *terminal)
 {
-       if (ts->sigfd >= 0) {
-               close(ts->sigfd);
+       struct lxc_terminal_state *state = terminal->tty_state;
 
-               if (pthread_sigmask(SIG_SETMASK, &ts->oldmask, NULL) < 0)
+       if (!terminal->tty_state)
+               return;
+
+       state = terminal->tty_state;
+       if (state->sigfd >= 0) {
+               close(state->sigfd);
+
+               if (pthread_sigmask(SIG_SETMASK, &state->oldmask, NULL) < 0)
                        SYSWARN("Failed to restore signal mask");
        }
 
-       free(ts);
+       free(terminal->tty_state);
+       terminal->tty_state = NULL;
 }
 
 static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal)
@@ -348,10 +355,7 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data,
                if (fd == terminal->master) {
                        terminal->master = -EBADF;
                } else if (fd == terminal->peer) {
-                       if (terminal->tty_state) {
-                               lxc_terminal_signal_fini(terminal->tty_state);
-                               terminal->tty_state = NULL;
-                       }
+                       lxc_terminal_signal_fini(terminal);
                        terminal->peer = -EBADF;
                } else {
                        ERROR("Handler received unexpected file descriptor");
@@ -499,10 +503,7 @@ int lxc_setup_tios(int fd, struct termios *oldtios)
 
 static void lxc_terminal_peer_proxy_free(struct lxc_terminal *terminal)
 {
-       if (terminal->tty_state) {
-               lxc_terminal_signal_fini(terminal->tty_state);
-               terminal->tty_state = NULL;
-       }
+       lxc_terminal_signal_fini(terminal);
 
        close(terminal->proxy.master);
        terminal->proxy.master = -1;
@@ -1018,6 +1019,9 @@ int lxc_console(struct lxc_container *c, int ttynum,
        struct lxc_epoll_descr descr;
        struct termios oldtios;
        struct lxc_terminal_state *ts;
+       struct lxc_terminal terminal = {
+               .tty_state = NULL,
+       };
        int istty = 0;
 
        ttyfd = lxc_cmd_console(c->name, &ttynum, &masterfd, c->config_path);
@@ -1033,6 +1037,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
                ret = -1;
                goto close_fds;
        }
+       terminal.tty_state = ts;
        ts->escape = escape;
        ts->stdoutfd = stdoutfd;
 
@@ -1107,7 +1112,7 @@ close_mainloop:
        lxc_mainloop_close(&descr);
 
 sigwinch_fini:
-       lxc_terminal_signal_fini(ts);
+       lxc_terminal_signal_fini(&terminal);
 
 close_fds:
        close(masterfd);
@@ -1171,6 +1176,7 @@ void lxc_terminal_conf_free(struct lxc_terminal *terminal)
        free(terminal->path);
        if (terminal->buffer_size > 0 && terminal->ringbuf.addr)
                lxc_ringbuf_release(&terminal->ringbuf);
+       lxc_terminal_signal_fini(terminal);
 }
 
 int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal)
index 02f31f8d8b28affa7e35568bcbd1ebf00b1d8f25..170c9d95c08e8e93f03619d9e8995ee58f406c2f 100644 (file)
@@ -265,8 +265,8 @@ extern int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata,
 /**
  * lxc_terminal_signal_fini: uninstall signal handler
  *
- * @ts
- * - the lxc_terminal_state returned by lxc_terminal_signal_init
+ * @terminal
+ * - the lxc_terminal
  *
  * Restore the saved signal handler that was in effect at the time
  * lxc_terminal_signal_init() was called.
@@ -274,7 +274,7 @@ extern int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata,
  * Must be called with process_lock held to protect the lxc_ttys list, or
  * from a non-threaded context.
  */
-extern void lxc_terminal_signal_fini(struct lxc_terminal_state *ts);
+extern void lxc_terminal_signal_fini(struct lxc_terminal *terminal);
 
 extern int lxc_terminal_write_ringbuffer(struct lxc_terminal *terminal);
 extern int lxc_terminal_create_log_file(struct lxc_terminal *terminal);