public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH] sysrq-j: emergency shell
@ 2008-11-21 23:51 Vegard Nossum
  2008-11-22  0:42 ` Matt Keenan
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Vegard Nossum @ 2008-11-21 23:51 UTC (permalink / raw)
  To: linux-kernel; +Cc: Alan Cox, Alexey Dobriyan

>From 57adfe62983db316fceba1b64258fd3d8830bcd8 Mon Sep 17 00:00:00 2001
From: Vegard Nossum <vegard.nossum@gmail.com>
Date: Sat, 22 Nov 2008 00:25:57 +0100
Subject: [PATCH] sysrq-j: emergency shell

This patch adds support for "SysRq-j", which invokes an emergency
root shell in the current console.

Please don't bite my head off for abusing the file API; documentation
was rather sparse! (Corrections are welcome, though.)

It seems that keyboard input will go to the shell only half of the
time; the other half goes to whatever program was running there in
the first place. I tried to kill the other users of the TTY using
TIOCSCTTY, but it seems not to have worked. Any ideas?

Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
---
 init/main.c |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/init/main.c b/init/main.c
index 7e117a2..edd5274 100644
--- a/init/main.c
+++ b/init/main.c
@@ -63,6 +63,8 @@
 #include <linux/signal.h>
 #include <linux/idr.h>
 #include <linux/ftrace.h>
+#include <linux/sysrq.h>
+#include <linux/file.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -833,6 +835,106 @@ static int noinline init_post(void)
 	panic("No init found.  Try passing init= option to kernel.");
 }
 
+static int sysrq_sh_thread(void *unused)
+{
+	static char *const argv[] = {"sh", NULL};
+	static char *const envp[] = {"HOME=/", "TERM=linux", NULL};
+
+	struct file *console;
+	int i;
+	int ret;
+
+	for (i = 0; i < 3; ++i) {
+		ret = get_unused_fd();
+		if (ret < 0)
+			goto put_fds;
+		if (ret != i) {
+			put_unused_fd(ret);
+			ret = -EBADF;
+			goto put_fds;
+		}
+	}
+
+	console = filp_open("/dev/console", O_RDWR | O_NOCTTY, 0);
+	if (IS_ERR(console)) {
+		ret = PTR_ERR(console);
+		goto put_fds;
+	}
+
+	get_file(console);
+	get_file(console);
+	get_file(console);
+	fd_install(0, console);
+	fd_install(1, console);
+	fd_install(2, console);
+
+	/* Become session leader */
+	ret = sys_setsid();
+	if (ret < 0)
+		goto put_filp;
+
+	/* Exclusive mode; no others are allowed to open() this tty */
+	ret = sys_ioctl(0, TIOCEXCL, 0);
+	if (ret < 0)
+		goto put_filp;
+
+	/* Steal the tty from whoever */
+	ret = sys_ioctl(0, TIOCSCTTY, 1);
+	if (ret < 0)
+		goto put_filp;
+
+	/* Flush pending input */
+	ret = sys_ioctl(0, TCFLSH, TCIFLUSH);
+	if (ret < 0)
+		goto put_filp;
+
+	/* If execve() returns, something went wrong. */
+	ret = kernel_execve("/bin/sh", argv, envp);
+
+put_filp:
+	fput(console);
+
+put_fds:
+	while (--i >= 0)
+		put_unused_fd(i);
+
+	printk(KERN_ERR "Couldn't start shell: %d\n", ret);
+	return ret;
+}
+
+static void sysrq_sh_work_func(struct work_struct *work)
+{
+	int err;
+
+	err = kernel_thread(sysrq_sh_thread, NULL, CLONE_FS | CLONE_SIGHAND);
+	if (err < 0)
+		printk(KERN_ERR "Couldn't start kernel thread (%d)\n", err);
+}
+
+static DECLARE_WORK(sysrq_sh_work, &sysrq_sh_work_func);
+
+static void sysrq_sh_handle(int key, struct tty_struct *tty)
+{
+	schedule_work(&sysrq_sh_work);
+}
+
+static struct sysrq_key_op sysrq_sh_op = {
+	.handler = sysrq_sh_handle,
+	.help_msg = "shell(j)",
+	.action_msg = "Emergency shell",
+};
+
+static void sysrq_sh_init(void)
+{
+	int err;
+
+	err = register_sysrq_key('j', &sysrq_sh_op);
+	if (err < 0) {
+		printk(KERN_ERR "Couldn't register SysRq-j (emergency shell) "
+			"handler. (%d)\n", err);
+	}
+}
+
 static int __init kernel_init(void * unused)
 {
 	lock_kernel();
@@ -877,6 +979,8 @@ static int __init kernel_init(void * unused)
 		prepare_namespace();
 	}
 
+	sysrq_sh_init();
+
 	/*
 	 * Ok, we have completed the initial bootup, and
 	 * we're essentially up and running. Get rid of the
-- 
1.5.6.5


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [RFC][PATCH] sysrq-j: emergency shell
  2008-11-21 23:51 [RFC][PATCH] sysrq-j: emergency shell Vegard Nossum
@ 2008-11-22  0:42 ` Matt Keenan
  2008-11-22  7:19 ` David Newall
  2008-11-22 17:27 ` Alexey Dobriyan
  2 siblings, 0 replies; 8+ messages in thread
From: Matt Keenan @ 2008-11-22  0:42 UTC (permalink / raw)
  To: Vegard Nossum; +Cc: linux-kernel, Alan Cox, Alexey Dobriyan

On Sat, 2008-11-22 at 00:51 +0100, Vegard Nossum wrote:
> >From 57adfe62983db316fceba1b64258fd3d8830bcd8 Mon Sep 17 00:00:00 2001
> From: Vegard Nossum <vegard.nossum@gmail.com>
> Date: Sat, 22 Nov 2008 00:25:57 +0100
> Subject: [PATCH] sysrq-j: emergency shell
> 
> This patch adds support for "SysRq-j", which invokes an emergency
> root shell in the current console.
> 
> Please don't bite my head off for abusing the file API; documentation
> was rather sparse! (Corrections are welcome, though.)
> 
> It seems that keyboard input will go to the shell only half of the
> time; the other half goes to whatever program was running there in
> the first place. I tried to kill the other users of the TTY using
> TIOCSCTTY, but it seems not to have worked. Any ideas?
> 

Have you considered SIGTSTP?

Matt



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC][PATCH] sysrq-j: emergency shell
  2008-11-21 23:51 [RFC][PATCH] sysrq-j: emergency shell Vegard Nossum
  2008-11-22  0:42 ` Matt Keenan
@ 2008-11-22  7:19 ` David Newall
  2008-11-22 17:27 ` Alexey Dobriyan
  2 siblings, 0 replies; 8+ messages in thread
From: David Newall @ 2008-11-22  7:19 UTC (permalink / raw)
  To: Vegard Nossum; +Cc: linux-kernel, Alan Cox, Alexey Dobriyan

Vegard Nossum wrote:
> This patch adds support for "SysRq-j", which invokes an emergency
> root shell in the current console.

I like this idea.  I like it a lot.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC][PATCH] sysrq-j: emergency shell
  2008-11-21 23:51 [RFC][PATCH] sysrq-j: emergency shell Vegard Nossum
  2008-11-22  0:42 ` Matt Keenan
  2008-11-22  7:19 ` David Newall
@ 2008-11-22 17:27 ` Alexey Dobriyan
  2008-11-22 19:07   ` Alan Cox
  2 siblings, 1 reply; 8+ messages in thread
From: Alexey Dobriyan @ 2008-11-22 17:27 UTC (permalink / raw)
  To: Vegard Nossum; +Cc: linux-kernel, Alan Cox

On Sat, Nov 22, 2008 at 12:51:59AM +0100, Vegard Nossum wrote:
> This patch adds support for "SysRq-j", which invokes an emergency
> root shell in the current console.
> 
> Please don't bite my head off for abusing the file API; documentation
> was rather sparse! (Corrections are welcome, though.)
> 
> It seems that keyboard input will go to the shell only half of the
> time; the other half goes to whatever program was running there in
> the first place. I tried to kill the other users of the TTY using
> TIOCSCTTY, but it seems not to have worked. Any ideas?

This should go in together with CVE number attached.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC][PATCH] sysrq-j: emergency shell
  2008-11-22 17:27 ` Alexey Dobriyan
@ 2008-11-22 19:07   ` Alan Cox
  2008-11-22 22:48     ` Vegard Nossum
  0 siblings, 1 reply; 8+ messages in thread
From: Alan Cox @ 2008-11-22 19:07 UTC (permalink / raw)
  To: Alexey Dobriyan; +Cc: Vegard Nossum, linux-kernel

> > It seems that keyboard input will go to the shell only half of the
> > time; the other half goes to whatever program was running there in
> > the first place. I tried to kill the other users of the TTY using
> > TIOCSCTTY, but it seems not to have worked. Any ideas?
> 
> This should go in together with CVE number attached.

TIOCSTTY isn't supposed to kill anything.

Alan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC][PATCH] sysrq-j: emergency shell
  2008-11-22 19:07   ` Alan Cox
@ 2008-11-22 22:48     ` Vegard Nossum
  2008-11-23  0:10       ` Alan Cox
  0 siblings, 1 reply; 8+ messages in thread
From: Vegard Nossum @ 2008-11-22 22:48 UTC (permalink / raw)
  To: Alan Cox; +Cc: Alexey Dobriyan, linux-kernel

On Sat, Nov 22, 2008 at 8:07 PM, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>> > It seems that keyboard input will go to the shell only half of the
>> > time; the other half goes to whatever program was running there in
>> > the first place. I tried to kill the other users of the TTY using
>> > TIOCSCTTY, but it seems not to have worked. Any ideas?
>>
>> This should go in together with CVE number attached.
>
> TIOCSTTY isn't supposed to kill anything.

Oops, by killing, I meant simply to take it exclusively:

              EPERM, unless the caller is root and arg equals 1, in which case
              the  tty is stolen, and all processes that had it as controlling
              tty lose it.

But I realize that this does not necessarily mean that the other
processes cannot read from or write to the tty anymore. Do you know
how to do that? :-)


Vegard

-- 
"The animistic metaphor of the bug that maliciously sneaked in while
the programmer was not looking is intellectually dishonest as it
disguises that the error is the programmer's own creation."
	-- E. W. Dijkstra, EWD1036

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC][PATCH] sysrq-j: emergency shell
  2008-11-22 22:48     ` Vegard Nossum
@ 2008-11-23  0:10       ` Alan Cox
  2008-11-23 19:29         ` Andi Kleen
  0 siblings, 1 reply; 8+ messages in thread
From: Alan Cox @ 2008-11-23  0:10 UTC (permalink / raw)
  To: Vegard Nossum; +Cc: Alexey Dobriyan, linux-kernel

> But I realize that this does not necessarily mean that the other
> processes cannot read from or write to the tty anymore. Do you know
> how to do that? :-)

When you have control vhangup()


That just leaves the small matter of keymaps. I'm really not sure of the
point of this sysrq-j hack, it seems to me we have a perfectly good vt
switch mechanism

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC][PATCH] sysrq-j: emergency shell
  2008-11-23  0:10       ` Alan Cox
@ 2008-11-23 19:29         ` Andi Kleen
  0 siblings, 0 replies; 8+ messages in thread
From: Andi Kleen @ 2008-11-23 19:29 UTC (permalink / raw)
  To: Alan Cox; +Cc: Vegard Nossum, Alexey Dobriyan, linux-kernel

Alan Cox <alan@lxorguk.ukuu.org.uk> writes:

>> But I realize that this does not necessarily mean that the other
>> processes cannot read from or write to the tty anymore. Do you know
>> how to do that? :-)
>
> When you have control vhangup()

It also means more people have to disable sysrq than before.

AFAIK currently it's not possible to actually change anything 
with sysrq (just reboot/kill/show information). That would
be the first one who could be actually used to change
data, enable network login etc.

I bet this unexpected change of security policy would
surprise a lot of existing users and suddenly give
a new attack vector.

So if this is added it should at least have a separate
enable switch with default off. But as Alan says, we
have vt-switch anyways so ...

-Andi

-- 
ak@linux.intel.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-11-23 19:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-21 23:51 [RFC][PATCH] sysrq-j: emergency shell Vegard Nossum
2008-11-22  0:42 ` Matt Keenan
2008-11-22  7:19 ` David Newall
2008-11-22 17:27 ` Alexey Dobriyan
2008-11-22 19:07   ` Alan Cox
2008-11-22 22:48     ` Vegard Nossum
2008-11-23  0:10       ` Alan Cox
2008-11-23 19:29         ` Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox