Skip to content

Commit

Permalink
fix console stdin,stdout,stderr fds
Browse files Browse the repository at this point in the history
The fds for stdin,stdout,stderr that we were leaving open for /sbin/init
in the container were those from /dev/tty or lxc.console (if given), which
wasn't right. Inside the container it should only have access to the pty
that lxc creates representing the console.

This was noticed because busybox's init was resetting the termio on its
stdin which was effecting the actual users terminal instead of the pty.
This meant it was setting icanon so were were not passing keystrokes
immediately to the pty, and hence command line history/editing wasn't
working.

Fix by dup'ing the console pty to stdin,stdout,stderr just before
exec()ing /sbin/init. Fix fd leak in error handling that I noticed while
going through this code.

Also tested with lxc.console = none, lxc.console = /dev/tty7 and no
lxc.console specified.

Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
  • Loading branch information
Dwight Engen authored and stgraber committed Mar 7, 2014
1 parent 0faa844 commit f699807
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 4 deletions.
18 changes: 17 additions & 1 deletion src/lxc/console.c
Expand Up @@ -506,7 +506,7 @@ static void lxc_console_peer_default(struct lxc_console *console)
DEBUG("using '%s' as console", path);

if (!isatty(console->peer))
return;
goto err1;

ts = lxc_console_sigwinch_init(console->peer, console->master);
if (!ts)
Expand Down Expand Up @@ -611,7 +611,23 @@ int lxc_console_create(struct lxc_conf *conf)
return -1;
}

int lxc_console_set_stdfds(struct lxc_handler *handler)
{
struct lxc_conf *conf = handler->conf;
struct lxc_console *console = &conf->console;

if (console->slave < 0)
return 0;

if (dup2(console->slave, 0) < 0 ||
dup2(console->slave, 1) < 0 ||
dup2(console->slave, 2) < 0)
{
SYSERROR("failed to dup console");
return -1;
}
return 0;
}

static int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata,
struct lxc_epoll_descr *descr)
Expand Down
1 change: 1 addition & 0 deletions src/lxc/console.h
Expand Up @@ -36,3 +36,4 @@ extern int lxc_console(struct lxc_container *c, int ttynum,
int escape);
extern int lxc_console_getfd(struct lxc_container *c, int *ttynum,
int *masterfd);
extern int lxc_console_set_stdfds(struct lxc_handler *);
1 change: 0 additions & 1 deletion src/lxc/lxc_console.c
Expand Up @@ -28,7 +28,6 @@
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <signal.h>
#include <libgen.h>
Expand Down
1 change: 0 additions & 1 deletion src/lxc/lxc_start.c
Expand Up @@ -27,7 +27,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
Expand Down
10 changes: 9 additions & 1 deletion src/lxc/start.c
Expand Up @@ -31,7 +31,6 @@
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <grp.h>
#include <poll.h>
#include <sys/param.h>
Expand Down Expand Up @@ -726,6 +725,15 @@ static int do_start(void *data)
goto out_warn_father;
}

/* Some init's such as busybox will set sane tty settings on stdin,
* stdout, stderr which it thinks is the console. We already set them
* the way we wanted on the real terminal, and we want init to do its
* setup on its console ie. the pty allocated in lxc_console_create()
* so make sure that that pty is stdin,stdout,stderr.
*/
if (lxc_console_set_stdfds(handler) < 0)
goto out_warn_father;

close(handler->sigfd);

/* after this call, we are in error because this
Expand Down

0 comments on commit f699807

Please sign in to comment.