[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    Re: [oss-security] xscreensaver package caps gets raw socket
From:       Salvatore Bonaccorso <carnil () debian ! org>
Date:       2021-04-21 18:51:49
Message-ID: YIB0RV1MqfmtfYDG () eldamar ! lan
[Download RAW message or body]

Hi,

On Sat, Apr 17, 2021 at 07:31:05AM -0700, Tavis Ormandy wrote:
> Hello, I noticed that at least debian (maybe others) ship xscreensaver
> hack with cap_net_raw enabled:
> 
> $ getcap /usr/libexec/xscreensaver/sonar
> /usr/libexec/xscreensaver/sonar cap_net_raw=p
> 
> That seems like a bug, you can just load some driver and get a raw
> socket. I wrote a quick exploit, this script will run tcpdump without
> needing root.
> 
> $ bash sock.sh
> 17:43:55.000000 IP (tos 0x0, ttl 64, id 14541, offset 0, flags [DF], proto ICMP (1), length 84)
>     debian > sfo07s17-in-f78.1e100.net: ICMP echo request, id 59166, seq 1, length 64
> 17:43:55.000000 IP (tos 0x0, ttl 128, id 42276, offset 0, flags [none], proto ICMP (1), length 84)
>     sfo07s17-in-f78.1e100.net > debian: ICMP echo reply, id 59166, seq 1, length 64
> 
> I sent a report to debian, jwz and mesa. We concluded no embargo is
> necessary, so continuing the discussion here.
> 
> Summary of discussion so far:
> 
> - In theory, mesa support running in a privileged context, their
>   documentation says they disable dangerous features in setuid/setgid
>   binaries:
> 
>     https://mesa-docs.readthedocs.io/en/latest/egl.html
> 
>   In fact, this is broken because they only check if (geteuid() !=
>   getuid()) { ... }. That check doesn't even handle setgid, let alone file
>   caps. If mesa agree this is a bug, simply changing their checks to if
>   (getauxval(AT_SECURE)) { ... } might make this bug go away, and handle
>   file caps and setgid for free. I filed a bug for that, but there
>   hasn't been a response:
>   https://gitlab.freedesktop.org/mesa/mesa/-/issues/4549
> 
> - The code could use ping sockets instead, but they're still rarely
>   enabled by default, and users have to set the ping_group_range sysctl.
>   I personally think it's time to enable them by default, but that's a
>   different discussion :-)
> 
> - If neither of those two options work, then I guess we will have to
>   try to make using mesa safe...but it sounds really hard. The obvious
>   fix for right now is trying to clean up the environment, e.g.:
> 
>   (Note: untested)
> 
>     char *allowed[][2] = {
>         { "DISPLAY", 0 },
>         { "XAUTHORITY", 0 },
>         NULL,
>     };
>     for (int i = 0; allowed[i][0]; i++)  {
>         if (getenv(allowed[i][0])) {
>             allowed[i][1] = strdup(getenv(allowed[i][0]));
>         }
>     }
>     if (clearenv() != 0) {
>         abort();
>     }
>     for (int i = 0; allowed[i][0]; i++)  {
>         if (allowed[i][1]) {
>             setenv(allowed[i][0], allowed[i][1], 1);
>             free(allowed[i][1]);
>         }
>     }
> 
>     // ...
>     MesaInitWhatever();
> 
> I *think* this will work in main(), but it's possible there are some
> constructors somewhere that execute before main() I've missed. If that's
> the case, then I guess we will need a wrapper binary that does execve()
> and passes a non-cloexec fd with a sanitized environment?
> 
> The problem is that even if we make cleaning up the environment work,
> you're always going to need $DISPLAY, and any code exec bug connecting
> to a malicious X server will be a security bug.... and that sounds super
> hard to get right?
> 
> I dunno, thoughts on fixing this appreciated...

FTR, the xscreenserver part has been assigned CVE-2021-31523 by MITRE.

Regards,
Salvatore
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic