All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drivers/tty: add kernel.restrict_pushback sysctl
@ 2015-12-20 15:45 Jann Horn
  2015-12-20 16:36 ` One Thousand Gnomes
  0 siblings, 1 reply; 4+ messages in thread
From: Jann Horn @ 2015-12-20 15:45 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby; +Cc: linux-kernel, Jann Horn

This new sysctl can be set to 1 to require CAP_SYS_ADMIN for
the TIOCSTI ioctl (which lets the caller push input back into
the TTY and thereby fake input to other processes that read
from the same TTY).

This is a well-known problem that hasn't been handled
particularly well in userland, e.g. allowing a user to whose
account root switches using "su" (or using "sudo" in the
default config) to write input to root's shell, resulting
in a privilege escalation. Additionally, it has increased
the impact of other security issues and requires care by
LSMs to ensure that restricted processes can't fiddle with
the TTYs of more privileged processes running under the
same user.

TIOCSTI is relatively exotic. For most users, turning this
sysctl on should be no problem.

Note that this does not make it completely safe to leak pty
FDs to unprivileged code: They could still be used to steal
passwords that the user enters in his terminal, to
selectively suppress keystrokes or to just fake program
output. An automatic kernel-side solution to this, if it is
even possible, would probably be complicated.

Signed-off-by: Jann Horn <jann@thejh.net>
---
 drivers/tty/tty_io.c | 12 +++++++++++-
 include/linux/tty.h  |  2 ++
 kernel/sysctl.c      | 10 ++++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index bcc8e1e..c7536d6 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -126,6 +126,15 @@ struct ktermios tty_std_termios = {	/* for the benefit of tty drivers  */
 	.c_ospeed = 38400
 };
 
+/*
+ * There are many ways in which an attacker can get hold of a TTY's
+ * file descriptor, both through leaks from a privileged parent to
+ * a less privileged child and through other attacks. The system
+ * administrator can set this flag to reduce the impact of such
+ * attacks a lot.
+ */
+int sysctl_restrict_pushback __read_mostly;
+
 EXPORT_SYMBOL(tty_std_termios);
 
 /* This list gets poked at by procfs and various bits of boot up code. This
@@ -2270,8 +2279,9 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
 {
 	char ch, mbz = 0;
 	struct tty_ldisc *ld;
+	bool needpriv = current->signal->tty != tty || sysctl_restrict_pushback;
 
-	if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
+	if (needpriv && !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	if (get_user(ch, p))
 		return -EFAULT;
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 5e31f1b..8cc8173 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -674,3 +674,5 @@ static inline void proc_tty_unregister_driver(struct tty_driver *d) {}
 	} while (0)
 
 #endif
+
+extern int sysctl_restrict_pushback;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index dc6858d..7bd1a28 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -65,6 +65,7 @@
 #include <linux/sched/sysctl.h>
 #include <linux/kexec.h>
 #include <linux/bpf.h>
+#include <linux/tty.h>
 
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -1172,6 +1173,15 @@ static struct ctl_table kern_table[] = {
 		.extra2		= &one,
 	},
 #endif
+	{
+		.procname	= "restrict_pushback",
+		.data		= &sysctl_restrict_pushback,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &one,
+	},
 	{ }
 };
 
-- 
2.1.4


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

* Re: [PATCH] drivers/tty: add kernel.restrict_pushback sysctl
  2015-12-20 15:45 [PATCH] drivers/tty: add kernel.restrict_pushback sysctl Jann Horn
@ 2015-12-20 16:36 ` One Thousand Gnomes
  2015-12-20 19:16   ` Jann Horn
  0 siblings, 1 reply; 4+ messages in thread
From: One Thousand Gnomes @ 2015-12-20 16:36 UTC (permalink / raw)
  To: Jann Horn; +Cc: Greg Kroah-Hartman, Jiri Slaby, linux-kernel

On Sun, 20 Dec 2015 16:45:26 +0100
Jann Horn <jann@thejh.net> wrote:

> This new sysctl can be set to 1 to require CAP_SYS_ADMIN for
> the TIOCSTI ioctl (which lets the caller push input back into
> the TTY and thereby fake input to other processes that read
> from the same TTY).

You can already do tbis with an LSM, you don't need to add random
unstructured extra options nobody will know about. Your extra code also
doesn't log anything so the user who does hit a usage case will have
nightmares debugging it.

Am LSM can also do the job properly because it can use labels to
ascertain the action to perform dependant upon the tty and how it is
currently being used. An LSM can also protect you far better as it can
taint the input (for example it can arrange that any TIOCSTI input
character from a non root user causes the receiving process to be
untrusted - so you attach the su session and your input just makes the
shell executing it untrusted so unable to run the command).

> This is a well-known problem that hasn't been handled
> particularly well in userland, e.g. allowing a user to whose
> account root switches using "su" (or using "sudo" in the
> default config) to write input to root's shell, resulting
> in a privilege escalation. Additionally, it has increased

And the same attack works via X events and keyboard programming games. If
you leak file handles you lose. Again an LSM can mitigate here in ways
your sysctl can't.

> Note that this does not make it completely safe to leak pty
> FDs to unprivileged code: They could still be used to steal
> passwords that the user enters in his terminal, to
> selectively suppress keystrokes or to just fake program
> output. An automatic kernel-side solution to this, if it is
> even possible, would probably be complicated.

This is precisely the problem I have with this - it's airport security,
it sounds good but has no value at all. Remember that anyone wanting to
attack you today is using scripts so a week after your sysctl appears the
script will be updated and everyone's robots will have the new attack that
bypasses it.

So instead of attacking a leaked pty/tty handle the opponent uses the
leaked X11 handle and posts X events, or if its a console fd they use the
console interfaces to fake up keypresses.

There are IMHO two things you need to make any attempt to solve this
properly in the usual circumstances

- You need a secure event channel between the keyboard and the root shell
  you create

- You need a way to switch reliably to that secure channel

That all comes down to having usable SAK (secure attention keu) support.
With the current graphics DRM and with Wayland we are actually fairly
close to that being feasible. Until then anyone who types su on an
untrusted console is (and always has been) asking for trouble.

As an aside - you also need to include documentation if adding sysctls.

Alan

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

* Re: [PATCH] drivers/tty: add kernel.restrict_pushback sysctl
  2015-12-20 16:36 ` One Thousand Gnomes
@ 2015-12-20 19:16   ` Jann Horn
  2015-12-20 19:42     ` One Thousand Gnomes
  0 siblings, 1 reply; 4+ messages in thread
From: Jann Horn @ 2015-12-20 19:16 UTC (permalink / raw)
  To: One Thousand Gnomes; +Cc: Greg Kroah-Hartman, Jiri Slaby, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5673 bytes --]

On Sun, Dec 20, 2015 at 04:36:43PM +0000, One Thousand Gnomes wrote:
> On Sun, 20 Dec 2015 16:45:26 +0100
> Jann Horn <jann@thejh.net> wrote:
> 
> > This new sysctl can be set to 1 to require CAP_SYS_ADMIN for
> > the TIOCSTI ioctl (which lets the caller push input back into
> > the TTY and thereby fake input to other processes that read
> > from the same TTY).
> 
> You can already do tbis with an LSM, you don't need to add random
> unstructured extra options nobody will know about. Your extra code also
> doesn't log anything so the user who does hit a usage case will have
> nightmares debugging it.

Pretty much nothing in the kernel, at least outside of LSMs, logs
anything when an access is denied. IIRC I included logging in another
security patch that might break stuff and was asked to remove the
logging.

True, it looks like you can already do this with SELinux or probably
also Tomoyo. I didn't realize that it gives you that granularity.

I don't really like the idea of putting a hardening measure like this
into an LSM that many distros don't turn on by default, but I get your
point about duplicating existing functionality inconsistently.


> Am LSM can also do the job properly because it can use labels to
> ascertain the action to perform dependant upon the tty and how it is
> currently being used. An LSM can also protect you far better as it can
> taint the input (for example it can arrange that any TIOCSTI input
> character from a non root user causes the receiving process to be
> untrusted - so you attach the su session and your input just makes the
> shell executing it untrusted so unable to run the command).

Eh. As far as I can tell, that doesn't take into account that the
shell might already have secrets in virtual memory or so, and it
would require the LSM to emulate the normal DAC checks for following
access checks with the creds of the tainting process, duplicating
quite a bit of security-relevant code.


> > This is a well-known problem that hasn't been handled
> > particularly well in userland, e.g. allowing a user to whose
> > account root switches using "su" (or using "sudo" in the
> > default config) to write input to root's shell, resulting
> > in a privilege escalation. Additionally, it has increased
> 
> And the same attack works via X events and keyboard programming games. If
> you leak file handles you lose. Again an LSM can mitigate here in ways
> your sysctl can't.

I'm mostly concerned about servers where an admin logs in as root,
then changes to various users to configure different services,
because that's the typical multi-user environment - and you usually
don't have X there.

Can you elaborate on the "keyboard programming" bit?

> > Note that this does not make it completely safe to leak pty
> > FDs to unprivileged code: They could still be used to steal
> > passwords that the user enters in his terminal, to
> > selectively suppress keystrokes or to just fake program
> > output. An automatic kernel-side solution to this, if it is
> > even possible, would probably be complicated.
> 
> This is precisely the problem I have with this - it's airport security,
> it sounds good but has no value at all. Remember that anyone wanting to
> attack you today is using scripts so a week after your sysctl appears the
> script will be updated and everyone's robots will have the new attack that
> bypasses it.
> 
> So instead of attacking a leaked pty/tty handle the opponent uses the
> leaked X11 handle and posts X events, or if its a console fd they use the
> console interfaces to fake up keypresses.

The attack scenario I have in mind is "someone ssh'es into a server as
root, then changes to another user to run some commands". In this case,
the only potential leaks I see are the pty slave fd, the environment
and the cwd.

I'm aware that this is not as simple when X is involved.


> There are IMHO two things you need to make any attempt to solve this
> properly in the usual circumstances
> 
> - You need a secure event channel between the keyboard and the root shell
>   you create
> 
> - You need a way to switch reliably to that secure channel
> 
> That all comes down to having usable SAK (secure attention keu) support.

I think SAK wouldn't be so great because I don't see an easy solution to
make it work nicely with nested shells: E.g. if you ssh into a server,
then su to a lower privilege level on the server, you might want to get
back either to the local shell or to the remote shell.

I think a nicer way would be to allow creation of sub-tty files that are
bound to a "parent" tty, but whose connection to the parent tty can be
revoked. Then, either the shell or programs like sudo could ensure that
only such a sub-tty is passed down and that it is revoked before the
shell prompt is shown the next time. To ensure that the shell prompt is
not faked, a simple approach might be to show a small secret word and/or
color as part of the shell prompt. This way, the user wouldn't have to
do anything additional (like pressing the SAK) apart from checking the
prompt correctness.

Of course, this breaks if there is a way to tell the TTY to copy some
old prompt to the bottom of the screen. Does anything like that exist?
I'm not familiar enough with TTYs to know the answer.


> With the current graphics DRM and with Wayland we are actually fairly
> close to that being feasible. Until then anyone who types su on an
> untrusted console is (and always has been) asking for trouble.

> As an aside - you also need to include documentation if adding sysctls.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH] drivers/tty: add kernel.restrict_pushback sysctl
  2015-12-20 19:16   ` Jann Horn
@ 2015-12-20 19:42     ` One Thousand Gnomes
  0 siblings, 0 replies; 4+ messages in thread
From: One Thousand Gnomes @ 2015-12-20 19:42 UTC (permalink / raw)
  To: Jann Horn; +Cc: Greg Kroah-Hartman, Jiri Slaby, linux-kernel

> Pretty much nothing in the kernel, at least outside of LSMs, logs
> anything when an access is denied. IIRC I included logging in another
> security patch that might break stuff and was asked to remove the
> logging.

And the LSMs log it for good reason.

> True, it looks like you can already do this with SELinux or probably
> also Tomoyo. I didn't realize that it gives you that granularity.

With the various filters and BPF we have today you can do extremely fine
grained protection.
 
> I don't really like the idea of putting a hardening measure like this
> into an LSM that many distros don't turn on by default, but I get your
> point about duplicating existing functionality inconsistently.

And the distributions will presumably not turn on your sysctl either,
because they won't know about it - and in the enterprise case it might
break back compatibility with some app.

> Eh. As far as I can tell, that doesn't take into account that the
> shell might already have secrets in virtual memory or so, and it
> would require the LSM to emulate the normal DAC checks for following
> access checks with the creds of the tainting process, duplicating
> quite a bit of security-relevant code.

The LSMs sit on top of DAC so code doesn't get duplicated.

> I'm mostly concerned about servers where an admin logs in as root,
> then changes to various users to configure different services,
> because that's the typical multi-user environment - and you usually
> don't have X there.

So you are dealing with just a network connection. In which case

1. You shouldn't be logging in as root, and most systems don't allow it
in the first place

2. If you were you would exec su - username from root to the unprivileged
user and do actions,

3. If you really wanted to do it then you would allocate a pty/tty pair,
run the user process over that and then vhangup() on it, repeating for
each user you wanted to create sessions for.

> Can you elaborate on the "keyboard programming" bit?

With console access and the right permissions you can reprogram the
keyboard mappings. It's another way of adding extra events in a console
environment - doesn't apply in the ssh case. Another oddity is you can
make some terminals send back identification codes (VT series), although
these days most emulations have that disabled.

> The attack scenario I have in mind is "someone ssh'es into a server as
> root, then changes to another user to run some commands". In this case,
> the only potential leaks I see are the pty slave fd, the environment
> and the cwd.

I think every normal policy on that is already "Don't log in as root"

> > That all comes down to having usable SAK (secure attention keu) support.
> 
> I think SAK wouldn't be so great because I don't see an easy solution to
> make it work nicely with nested shells: E.g. if you ssh into a server,
> then su to a lower privilege level on the server, you might want to get
> back either to the local shell or to the remote shell.

Assuming you trust the ssh client and and the ssh server then all the
bits are already there to allocate a new session over a pty/tty pair and
use that to get full isolation.

> I think a nicer way would be to allow creation of sub-tty files that are
> bound to a "parent" tty, but whose connection to the parent tty can be
> revoked. Then, either the shell or programs like sudo could ensure that

pty/tty pairs do exactly this.

> only such a sub-tty is passed down and that it is revoked before the
> shell prompt is shown the next time. To ensure that the shell prompt is
> not faked, a simple approach might be to show a small secret word and/or
> color as part of the shell prompt. This way, the user wouldn't have to
> do anything additional (like pressing the SAK) apart from checking the
> prompt correctness.

SAK is not overridable so whatever you SAK key or sequence is you
interpret it within your trusted code (so the one that creates the
subshells and copies traffic to them). You don't need hacks like shell
prompt colours because you *know* that some sequence such as CTRL-^
*always* gets you to the controlling interface.

So you'd write a bit of C or Go or similar code to put the subshell on a
pty/tty pair, copy all bytes back and forth but always trap CTRL-^ or
similar, to go back to a control interface.

> Of course, this breaks if there is a way to tell the TTY to copy some
> old prompt to the bottom of the screen. Does anything like that exist?
> I'm not familiar enough with TTYs to know the answer.

In VT terminal cases not that I know of. Some other terminal types can do
copies.

Alan

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

end of thread, other threads:[~2015-12-20 19:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-20 15:45 [PATCH] drivers/tty: add kernel.restrict_pushback sysctl Jann Horn
2015-12-20 16:36 ` One Thousand Gnomes
2015-12-20 19:16   ` Jann Horn
2015-12-20 19:42     ` One Thousand Gnomes

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.