From: minyard@acm.org
To: Linux Kernel <linux-kernel@vger.kernel.org>
Cc: Corey Minyard <cminyard@mvista.com>
Subject: [PATCH] Move console redirect to pid namespace
Date: Fri, 08 Feb 2013 20:28:40 -0600 [thread overview]
Message-ID: <1360376920-30824-1-git-send-email-minyard@acm.org> (raw)
From: Corey Minyard <cminyard@mvista.com>
The console redirect - ioctl(fd, TIOCCONS) - is not in a namespace,
thus a container can do a redirect and grab all the I/O on the host
and all container consoles.
This change puts the redirect in the pid namespace.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
I'm pretty sure this patch is not correct, but I'm not quite sure the
best way to fix this. I'm not 100% sure that the pid namespace is the
right place, but it seemed the most reasonable of all the choices. The
other obvious choice is the mount namespace, but it didn't seem as good
a fit.
The other problem is that I don't think you can call fput() from
destroy_pid_namespace(). That can be called from interrupt context,
and I don't think fput() is safe there. I know it's not safe in 3.4
with the RT patch applied. However, the only way I've come up with to
fix it is to add a workqueue, and that seems a bit heavy for this.
drivers/tty/tty_io.c | 29 ++++++++++++++++++-----------
include/linux/pid_namespace.h | 1 +
kernel/pid_namespace.c | 3 +++
3 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index da9fde8..c93c23d 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -95,6 +95,7 @@
#include <linux/seq_file.h>
#include <linux/serial.h>
#include <linux/ratelimit.h>
+#include <linux/pid_namespace.h>
#include <linux/uaccess.h>
@@ -503,8 +504,10 @@ static const struct file_operations hung_up_tty_fops = {
.release = tty_release,
};
+/*
+ * redirect is in the pid namespace, but we use a global lock.
+ */
static DEFINE_SPINLOCK(redirect_lock);
-static struct file *redirect;
/**
* tty_wakeup - request more data
@@ -563,15 +566,17 @@ static void __tty_hangup(struct tty_struct *tty)
int closecount = 0, n;
unsigned long flags;
int refs = 0;
+ struct file *redir;
if (!tty)
return;
spin_lock(&redirect_lock);
- if (redirect && file_tty(redirect) == tty) {
- f = redirect;
- redirect = NULL;
+ redir = current->nsproxy->pid_ns->redirect;
+ if (redir && file_tty(redir) == tty) {
+ f = redir;
+ current->nsproxy->pid_ns->redirect = NULL;
}
spin_unlock(&redirect_lock);
@@ -1163,10 +1168,12 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct file *p = NULL;
+ struct file *redir;
spin_lock(&redirect_lock);
- if (redirect)
- p = get_file(redirect);
+ redir = current->nsproxy->pid_ns->redirect;
+ if (redir)
+ p = get_file(redir);
spin_unlock(&redirect_lock);
if (p) {
@@ -2247,19 +2254,19 @@ static int tioccons(struct file *file)
if (file->f_op->write == redirected_tty_write) {
struct file *f;
spin_lock(&redirect_lock);
- f = redirect;
- redirect = NULL;
+ f = current->nsproxy->pid_ns->redirect;
+ current->nsproxy->pid_ns->redirect = NULL;
spin_unlock(&redirect_lock);
if (f)
fput(f);
return 0;
}
spin_lock(&redirect_lock);
- if (redirect) {
+ if (current->nsproxy->pid_ns->redirect) {
spin_unlock(&redirect_lock);
return -EBUSY;
}
- redirect = get_file(file);
+ current->nsproxy->pid_ns->redirect = get_file(file);
spin_unlock(&redirect_lock);
return 0;
}
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index 215e5e3..b04870f 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -38,6 +38,7 @@ struct pid_namespace {
int hide_pid;
int reboot; /* group exit code if this pidns was rebooted */
unsigned int proc_inum;
+ struct file *redirect;
};
extern struct pid_namespace init_pid_ns;
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index c1c3dc1..af1bfce 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -18,6 +18,7 @@
#include <linux/proc_fs.h>
#include <linux/reboot.h>
#include <linux/export.h>
+#include <linux/file.h>
#define BITS_PER_PAGE (PAGE_SIZE*8)
@@ -138,6 +139,8 @@ static void destroy_pid_namespace(struct pid_namespace *ns)
{
int i;
+ if (ns->redirect)
+ fput(ns->redirect);
proc_free_inum(ns->proc_inum);
for (i = 0; i < PIDMAP_ENTRIES; i++)
kfree(ns->pidmap[i].page);
--
1.7.4.1
next reply other threads:[~2013-02-09 3:28 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-09 2:28 minyard [this message]
2013-02-09 18:14 ` Bruno Prémont
2013-02-13 19:08 ` Eric W. Biederman
2013-02-15 2:08 ` Corey Minyard
2013-02-15 4:23 ` Eric W. Biederman
2013-02-15 14:50 ` Corey Minyard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1360376920-30824-1-git-send-email-minyard@acm.org \
--to=minyard@acm.org \
--cc=cminyard@mvista.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome