The same basic sequence of events happens with and without user namespaces. init sheds its tty with setsid() but then opens /dev/console, which as the effect of making /dev/console it's controlling tty. Later getty also opens /dev/console and tries the TIOCSCTTY ioctl on the fd. At this point I think the following code in the kernel handling of that ioctl comes into play:
if (tty->session) {
/*
* This tty is already the controlling
* tty for another session group!
*/
if (arg == 1 && capable(CAP_SYS_ADMIN)) { /* * Steal it away */ read_lock(&tasklist_lock); session_clear_tty(tty->session); read_unlock(&tasklist_lock);
} else { ret = -EPERM; goto unlock;
}
}
I.e. getty doesn't have CAP_SYS_ADMIN and thus can't steal the console from init. I'm not sure what the fix is yet, whether there's something we can do here which can allow root within a namespace to steal the console or whether upstart just needs to explicitly shed the console after opening it.
The same basic sequence of events happens with and without user namespaces. init sheds its tty with setsid() but then opens /dev/console, which as the effect of making /dev/console it's controlling tty. Later getty also opens /dev/console and tries the TIOCSCTTY ioctl on the fd. At this point I think the following code in the kernel handling of that ioctl comes into play:
if (tty->session) { CAP_SYS_ ADMIN)) {
/*
* Steal it away
*/
read_ lock(&tasklist_ lock);
session_ clear_tty( tty->session) ;
read_ unlock( &tasklist_ lock);
ret = -EPERM;
goto unlock;
/*
* This tty is already the controlling
* tty for another session group!
*/
if (arg == 1 && capable(
} else {
}
}
I.e. getty doesn't have CAP_SYS_ADMIN and thus can't steal the console from init. I'm not sure what the fix is yet, whether there's something we can do here which can allow root within a namespace to steal the console or whether upstart just needs to explicitly shed the console after opening it.