diff options
author | Patrick J Volkerding <volkerdi@slackware.com> | 2018-05-25 23:29:36 +0000 |
---|---|---|
committer | Eric Hameleers <alien@slackware.com> | 2018-06-01 00:36:01 +0200 |
commit | 39366733c3fe943363566756e2e152c45a1b3cb2 (patch) | |
tree | 228b0735896af90ca78151c9a69aa3efd12c8cae /patches/source/xscreensaver/setuid.c | |
parent | d31c50870d0bee042ce660e445c9294a59a3a65b (diff) | |
download | current-14.2.tar.gz |
Fri May 25 23:29:36 UTC 201814.2
patches/packages/glibc-zoneinfo-2018e-noarch-2_slack14.2.txz: Rebuilt.
Handle removal of US/Pacific-New timezone. If we see that the machine is
using this, it will be automatically switched to US/Pacific.
Diffstat (limited to 'patches/source/xscreensaver/setuid.c')
-rw-r--r-- | patches/source/xscreensaver/setuid.c | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/patches/source/xscreensaver/setuid.c b/patches/source/xscreensaver/setuid.c new file mode 100644 index 00000000..343dcf09 --- /dev/null +++ b/patches/source/xscreensaver/setuid.c @@ -0,0 +1,274 @@ +/* setuid.c --- management of runtime privileges. + * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <jwz@jwz.org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <X11/Xlib.h> /* not used for much... */ + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" + +#ifndef EPERM +#include <errno.h> +#endif + +#include <pwd.h> /* for getpwnam() and struct passwd */ +#include <grp.h> /* for getgrgid() and struct group */ + +static const char * +uid_gid_string (uid_t uid, gid_t gid) +{ + static char buf[255]; + struct passwd *p = 0; + struct group *g = 0; + p = getpwuid (uid); + g = getgrgid (gid); + sprintf (buf, "%s/%s (%ld/%ld)", + (p && p->pw_name ? p->pw_name : "???"), + (g && g->gr_name ? g->gr_name : "???"), + (long) uid, (long) gid); + return buf; +} + + +void +describe_uids (saver_info *si, FILE *out) +{ + uid_t uid = getuid(); + gid_t gid = getgid(); + uid_t euid = geteuid(); + gid_t egid = getegid(); + char *s1 = strdup (uid_gid_string (uid, gid)); + char *s2 = strdup (uid_gid_string (euid, egid)); + + if (si->orig_uid && *si->orig_uid && + (!!strcmp (si->orig_uid, s1) || + !!strcmp (si->orig_uid, s2))) + fprintf (out, "%s: initial effective uid/gid was %s\n", blurb(), + si->orig_uid); + + fprintf (out, "%s: running as %s", blurb(), s1); + if (uid != euid || gid != egid) + fprintf (out, "; effectively %s", s2); + fprintf(out, "\n"); + free(s1); + free(s2); +} + + +static int +set_ids_by_number (uid_t uid, gid_t gid, char **message_ret) +{ + int uid_errno = 0; + int gid_errno = 0; + struct passwd *p = getpwuid (uid); + struct group *g = getgrgid (gid); + + if (message_ret) + *message_ret = 0; + + /* Rumor has it that some implementations of of setuid() do nothing + when called with -1; therefore, if the "nobody" user has a uid of + -1, then that would be Really Bad. Rumor further has it that such + systems really ought to be using -2 for "nobody", since that works. + So, if we get a uid (or gid, for good measure) of -1, switch to -2 + instead. Note that this must be done after we've looked up the + user/group names with getpwuid(-1) and/or getgrgid(-1). + */ + if (gid == (gid_t) -1) gid = (gid_t) -2; + if (uid == (uid_t) -1) uid = (uid_t) -2; + + errno = 0; + if (setgid (gid) != 0) + gid_errno = errno ? errno : -1; + + errno = 0; + if (setuid (uid) != 0) + uid_errno = errno ? errno : -1; + + if (uid_errno == 0 && gid_errno == 0) + { + static char buf [1024]; + sprintf (buf, "changed uid/gid to %s/%s (%ld/%ld).", + (p && p->pw_name ? p->pw_name : "???"), + (g && g->gr_name ? g->gr_name : "???"), + (long) uid, (long) gid); + if (message_ret) + *message_ret = buf; + return 0; + } + else + { + char buf [1024]; + if (gid_errno) + { + sprintf (buf, "%s: couldn't set gid to %s (%ld)", + blurb(), + (g && g->gr_name ? g->gr_name : "???"), + (long) gid); + if (gid_errno == -1) + fprintf(stderr, "%s: unknown error\n", buf); + else + perror(buf); + } + + if (uid_errno) + { + sprintf (buf, "%s: couldn't set uid to %s (%ld)", + blurb(), + (p && p->pw_name ? p->pw_name : "???"), + (long) uid); + if (uid_errno == -1) + fprintf(stderr, "%s: unknown error\n", buf); + else + perror(buf); + } + + return -1; + } +} + + +/* If we've been run as setuid or setgid to someone else (most likely root) + turn off the extra permissions so that random user-specified programs + don't get special privileges. (On some systems it is necessary to install + this program as setuid root in order to read the passwd file to implement + lock-mode.) + + *** WARNING: DO NOT DISABLE ANY OF THE FOLLOWING CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ +void +hack_uid (saver_info *si) +{ + + /* Discard privileges, and set the effective user/group ids to the + real user/group ids. That is, give up our "chmod +s" rights. + */ + { + uid_t euid = geteuid(); + gid_t egid = getegid(); + uid_t uid = getuid(); + gid_t gid = getgid(); + + si->orig_uid = strdup (uid_gid_string (euid, egid)); + + if (uid != euid || gid != egid) + if (set_ids_by_number (uid, gid, &si->uid_message) != 0) + saver_exit (si, 1, 0); + } + + + /* Locking can't work when running as root, because we have no way of + knowing what the user id of the logged in user is (so we don't know + whose password to prompt for.) + + *** WARNING: DO NOT DISABLE THIS CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ + if (getuid() == (uid_t) 0) + { + si->locking_disabled_p = True; + si->nolock_reason = "running as root"; + } + + + /* If we're running as root, switch to a safer user. This is above and + beyond the fact that we've disabling locking, above -- the theory is + that running graphics demos as root is just always a stupid thing + to do, since they have probably never been security reviewed and are + more likely to be buggy than just about any other kind of program. + (And that assumes non-malicious code. There are also attacks here.) + + *** WARNING: DO NOT DISABLE THIS CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ + if (getuid() == (uid_t) 0) + { + struct passwd *p; + + p = getpwnam ("nobody"); + if (! p) p = getpwnam ("noaccess"); + if (! p) p = getpwnam ("daemon"); + if (! p) + { + fprintf (stderr, + "%s: running as root, and couldn't find a safer uid.\n", + blurb()); + saver_exit(si, 1, 0); + } + + if (set_ids_by_number (p->pw_uid, p->pw_gid, &si->uid_message) != 0) + saver_exit (si, -1, 0); + } + + + /* If there's anything even remotely funny looking about the passwd struct, + or if we're running as some other user from the list below (a + non-comprehensive selection of users known to be privileged in some way, + and not normal end-users) then disable locking. If it was possible, + switching to "nobody" would be the thing to do, but only root itself has + the privs to do that. + + *** WARNING: DO NOT DISABLE THIS CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ + { + uid_t uid = getuid (); /* get it again */ + struct passwd *p = getpwuid (uid); /* get it again */ + + if (!p || + uid == (uid_t) 0 || + uid == (uid_t) -1 || + uid == (uid_t) -2 || + p->pw_uid == (uid_t) 0 || + p->pw_uid == (uid_t) -1 || + p->pw_uid == (uid_t) -2 || + !p->pw_name || + !*p->pw_name || + !strcmp (p->pw_name, "root") || + !strcmp (p->pw_name, "nobody") || + !strcmp (p->pw_name, "noaccess") || + !strcmp (p->pw_name, "operator") || + !strcmp (p->pw_name, "daemon") || + !strcmp (p->pw_name, "bin") || + !strcmp (p->pw_name, "adm") || + !strcmp (p->pw_name, "sys") || + !strcmp (p->pw_name, "games")) + { + static char buf [1024]; + sprintf (buf, "running as %s", + (p && p->pw_name && *p->pw_name + ? p->pw_name : "<unknown>")); + si->nolock_reason = buf; + si->locking_disabled_p = True; + si->dangerous_uid_p = True; + } + } +} |