Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default Saved GID seems to always match utmp group, and confuses GTK's setuid safety check #2072

Closed
rib opened this issue May 7, 2017 · 8 comments

Comments

@rib
Copy link

rib commented May 7, 2017

  • Your Windows build number: 10.0.15063

  • What you're doing and what's happening:

Firstly run VcXsrv X11 server on windows: https://sourceforge.net/projects/vcxsrv/
Then in bash:

$ sudo apt-get install vim-gtk3-py2
$ gvim

results in:

(gvim:29224): Gtk-WARNING **: This process is currently running setuid or setgid.
This is not a supported use of GTK+. You must create a helper
program instead. For further details, see:

    http://www.gtk.org/setuid.html

Refusing to initialize GTK+.
E852: The child process failed to start the GUI
Press ENTER or type command to continue

(and it will then run the terminal UI for vim)

  • What's wrong / what should be happening instead:
    This code in gtk/gtkmain.c is getting confused:
/* This checks to see if the process is running suid or sgid
 * at the current time. If so, we don’t allow GTK+ to be initialized.
 * This is meant to be a mild check - we only error out if we
 * can prove the programmer is doing something wrong, not if
 * they could be doing something wrong. For this reason, we
 * don’t use issetugid() on BSD or prctl (PR_GET_DUMPABLE).
 */
static gboolean
check_setugid (void)
{
/* this isn't at all relevant on MS Windows and doesn't compile ... --hb */
#ifndef G_OS_WIN32
  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */

#ifdef HAVE_GETRESUID
  if (getresuid (&ruid, &euid, &suid) != 0 ||
      getresgid (&rgid, &egid, &sgid) != 0)
#endif /* HAVE_GETRESUID */
    {
      suid = ruid = getuid ();
      sgid = rgid = getgid ();
      euid = geteuid ();
      egid = getegid ();
    }

  if (ruid != euid || ruid != suid ||
      rgid != egid || rgid != sgid)
    {
      g_warning ("This process is currently running setuid or setgid.\n"
                 "This is not a supported use of GTK+. You must create a helper\n"
                 "program instead. For further details, see:\n\n"
                 "    http://www.gtk.org/setuid.html\n\n"
                 "Refusing to initialize GTK+.");
      exit (1);
    }
#endif
  return TRUE;
}

In particular getresgid will report a saved GID of 43 - corresponding to the utmp group which results in this code believing that the application has been run with a setuid binary.

This code factored out into a standalone test reproduces the issue:

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */

  if (getresuid (&ruid, &euid, &suid) != 0 ||
      getresgid (&rgid, &egid, &sgid) != 0)
    {
      suid = ruid = getuid ();
      sgid = rgid = getgid ();
      euid = geteuid ();
      egid = getegid ();
    }

  if (ruid != euid || ruid != suid ||
      rgid != egid || rgid != sgid)
    {
      fprintf(stderr, "This process is currently running setuid or setgid.\n"
                 "This is not a supported use of GTK+. You must create a helper\n"
                 "program instead. For further details, see:\n\n"
                 "    http://www.gtk.org/setuid.html\n\n"
                 "Refusing to initialize GTK+: ruid=%d,rgid=%d,euid=%d,egid=%d,suid=%d,sgid=%d\n",
                 ruid,rgid,euid,egid,suid,sgid);
      exit (1);
    }

  printf("OK\n");
  return 0;
}

If I run that, I see this output (showing all the uid/gid values being checked):

This process is currently running setuid or setgid.
This is not a supported use of GTK+. You must create a helper
program instead. For further details, see:

    http://www.gtk.org/setuid.html

Refusing to initialize GTK+: ruid=1000,rgid=1000,euid=1000,egid=1000,suid=1000,sgid=43
  • Workaround
    For now 'm currently compiling the following code into a DSO which I load via LD_PRELOAD to hack around this issue so I can manage to launch the graphical UI for Vim:
#define _GNU_SOURCE
#include <sys/types.h>
#include <dlfcn.h>

int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
{
    static int (*__real_getresgid)(gid_t *, gid_t *, gid_t *);
    int ret;

    if (!__real_getresgid)
        __real_getresgid = dlsym(RTLD_NEXT, "getresgid");

    ret = __real_getresgid(rgid, egid, sgid);
    if (*sgid == 43)
        *sgid = *egid;

    return ret;
}

E.g. this works:

$ gcc -shared -fPIC -o fixsgid.so ./fix-sgid.c
$ export LD_PRELOAD=$PWD/fixsgid.so
$ gvim
@sunjoong
Copy link

sunjoong commented May 7, 2017

@rib - Interesting! I'm a gentoo linux user, not ubuntu, on WSL. I use VcXsrv too and installed gtk+2 but not installed gtk+3. When I ran your test code, I only saw OK. Then... what make that problem? I had to have compiled glibc with suid use flag because I could not (re-)mount devpts with gid=5 option, but standard glibc could be compiled with this new setuid(), I think. Might be it relevant?

UPDATE: I ran your test code in ubuntu, but could not see the error message but saw OK like gentoo.

sunjoong@SUNJOONG-DESKTOP:~$ ./a.out
OK
sunjoong@SUNJOONG-DESKTOP:~$ sudo apt-get install vim-gtk3-py2
[sudo] password for sunjoong:
Reading package lists... Done
Building dependency tree
Reading state information... Done
...... snip ...... snip ...... snip ......
Processing triggers for libgdk-pixbuf2.0-0:amd64 (2.32.2-1ubuntu1.2) ...
Processing triggers for dbus (1.10.6-1ubuntu3.3) ...
sunjoong@SUNJOONG-DESKTOP:~$ export DISPLAY=:0
sunjoong@SUNJOONG-DESKTOP:~$ gvim
process 3425: D-Bus library appears to be incorrectly set up; failed to read machine uuid: UUID file '/etc/machine-id' should contain a hex string of length 32, not length 0, with no other text
See the manual page for dbus-uuidgen to correct this issue.
sunjoong@SUNJOONG-DESKTOP:~$ dbus-uuidgen | sudo tee /etc/machine-id
22b0bd1e2a488104c99d639e590f513a
sunjoong@SUNJOONG-DESKTOP:~$ gvim
sunjoong@SUNJOONG-DESKTOP:~$

@rib
Copy link
Author

rib commented May 8, 2017

Ah, so another important detail is that I'm running under screen.

It seems that the test case passes for me too without running under screen but fails if I do.

@sunjoong
Copy link

sunjoong commented May 8, 2017

@rib - Ah... I saw the error message after launching screen. So, I ran ls;

sunjoong@SUNJOONG-DESKTOP:~$ ls -l /usr/bin/screen
-rwxr-sr-x 1 root utmp 434216 Feb  7  2016 /usr/bin/screen
sunjoong@SUNJOONG-DESKTOP:~$

After command sodu chmod g-s /usr/bin/screen, the error was disappeared.

@benhillis benhillis added the bug label Jun 6, 2017
@benhillis
Copy link
Member

@rib - I'm having trouble reproducing this. When I run gvim I'm not seeing the error, and when I run your short test I see the output "OK"

Which directory are you running the test out of?

@sunjoong
Copy link

sunjoong commented Jul 7, 2017

@benhillis - Did you test it within screen? I had seen the output "OK" on my first test without screen, and then error message with screen after I heard @rib had done it "under screen".

@benhillis
Copy link
Member

@sunjoong - ah good call, I missed that in the repro steps. I'll give that a shot!

@benhillis
Copy link
Member

benhillis commented Jul 10, 2017

I have a fix for this, marking as a duplicate of #962.

@benhillis
Copy link
Member

Fixed in 16251.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants