xserver: check for elevated privileges not uid=0
This allows us to run the server as a normal user whilst still being able to use the -modulepath, -logfile and -config switches We define a xf86PrivsElevated which will do the checks and cache the result in case it is called more than once. Also renamed the paths #defines to match their new meaning. Original discussion which led to this patch can be found here: http://lists.freedesktop.org/archives/xorg-devel/2011-September/025853.html Signed-off-by: Antoine Martin <antoine@nagafix.co.uk> Tested-by: Michal Suchanek <hramrach at centrum.cz> Reviewed-by: Jamey Sharp <jamey at minilop.net> Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
parent
2c1d0a539c
commit
ead968a430
|
@ -212,7 +212,7 @@ AC_CHECK_FUNC([dlopen], [],
|
|||
AC_SUBST(DLOPEN_LIBS)
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS([backtrace ffs \
|
||||
AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \
|
||||
getdtablesize getifaddrs getpeereid getpeerucred getzoneid \
|
||||
mmap shmctl64 strncasecmp vasprintf vsnprintf walkcontext])
|
||||
AC_REPLACE_FUNCS([strcasecmp strcasestr strlcat strlcpy strndup])
|
||||
|
|
|
@ -72,8 +72,8 @@
|
|||
* These paths define the way the config file search is done. The escape
|
||||
* sequences are documented in parser/scan.c.
|
||||
*/
|
||||
#ifndef ROOT_CONFIGPATH
|
||||
#define ROOT_CONFIGPATH "%A," "%R," \
|
||||
#ifndef ALL_CONFIGPATH
|
||||
#define ALL_CONFIGPATH "%A," "%R," \
|
||||
"/etc/X11/%R," "%P/etc/X11/%R," \
|
||||
"%E," "%F," \
|
||||
"/etc/X11/%F," "%P/etc/X11/%F," \
|
||||
|
@ -83,8 +83,8 @@
|
|||
"%P/lib/X11/%X.%H," \
|
||||
"%P/lib/X11/%X"
|
||||
#endif
|
||||
#ifndef USER_CONFIGPATH
|
||||
#define USER_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
|
||||
#ifndef RESTRICTED_CONFIGPATH
|
||||
#define RESTRICTED_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
|
||||
"/etc/X11/%G," "%P/etc/X11/%G," \
|
||||
"/etc/X11/%X," "/etc/%X," \
|
||||
"%P/etc/X11/%X.%H," \
|
||||
|
@ -92,14 +92,14 @@
|
|||
"%P/lib/X11/%X.%H," \
|
||||
"%P/lib/X11/%X"
|
||||
#endif
|
||||
#ifndef ROOT_CONFIGDIRPATH
|
||||
#define ROOT_CONFIGDIRPATH "%A," "%R," \
|
||||
#ifndef ALL_CONFIGDIRPATH
|
||||
#define ALL_CONFIGDIRPATH "%A," "%R," \
|
||||
"/etc/X11/%R," "%C/X11/%R," \
|
||||
"/etc/X11/%X," "%C/X11/%X"
|
||||
#endif
|
||||
#ifndef USER_CONFIGDIRPATH
|
||||
#define USER_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
|
||||
"/etc/X11/%X," "%C/X11/%X"
|
||||
#ifndef RESTRICTED_CONFIGDIRPATH
|
||||
#define RESTRICTED_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
|
||||
"/etc/X11/%X," "%C/X11/%X"
|
||||
#endif
|
||||
#ifndef SYS_CONFIGDIRPATH
|
||||
#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
|
||||
|
@ -2310,12 +2310,12 @@ xf86HandleConfigFile(Bool autoconfig)
|
|||
MessageType filefrom = X_DEFAULT;
|
||||
MessageType dirfrom = X_DEFAULT;
|
||||
|
||||
if (getuid() == 0) {
|
||||
filesearch = ROOT_CONFIGPATH;
|
||||
dirsearch = ROOT_CONFIGDIRPATH;
|
||||
if (!xf86PrivsElevated()) {
|
||||
filesearch = ALL_CONFIGPATH;
|
||||
dirsearch = ALL_CONFIGDIRPATH;
|
||||
} else {
|
||||
filesearch = USER_CONFIGPATH;
|
||||
dirsearch = USER_CONFIGDIRPATH;
|
||||
filesearch = RESTRICTED_CONFIGPATH;
|
||||
dirsearch = RESTRICTED_CONFIGDIRPATH;
|
||||
}
|
||||
|
||||
if (xf86ConfigFile)
|
||||
|
|
|
@ -238,6 +238,65 @@ xf86PrintMarkers(void)
|
|||
LogPrintMarkers();
|
||||
}
|
||||
|
||||
Bool xf86PrivsElevated(void)
|
||||
{
|
||||
static Bool privsTested = FALSE;
|
||||
static Bool privsElevated = TRUE;
|
||||
|
||||
if (!privsTested) {
|
||||
#if defined(WIN32)
|
||||
privsElevated = FALSE;
|
||||
#else
|
||||
if ((getuid() != geteuid()) || (getgid() != getegid())) {
|
||||
privsElevated = TRUE;
|
||||
} else {
|
||||
#if defined(HAVE_ISSETUGID)
|
||||
privsElevated = issetugid();
|
||||
#elif defined(HAVE_GETRESUID)
|
||||
uid_t ruid, euid, suid;
|
||||
gid_t rgid, egid, sgid;
|
||||
|
||||
if ((getresuid(&ruid, &euid, &suid) == 0) &&
|
||||
(getresgid(&rgid, &egid, &sgid) == 0)) {
|
||||
privsElevated = (euid != suid) || (egid != sgid);
|
||||
}
|
||||
else {
|
||||
printf("Failed getresuid or getresgid");
|
||||
/* Something went wrong, make defensive assumption */
|
||||
privsElevated = TRUE;
|
||||
}
|
||||
#else
|
||||
if (getuid()==0) {
|
||||
/* running as root: uid==euid==0 */
|
||||
privsElevated = FALSE;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* If there are saved ID's the process might still be privileged
|
||||
* even though the above test succeeded. If issetugid() and
|
||||
* getresgid() aren't available, test this by trying to set
|
||||
* euid to 0.
|
||||
*/
|
||||
unsigned int oldeuid;
|
||||
oldeuid = geteuid();
|
||||
|
||||
if (seteuid(0) != 0) {
|
||||
privsElevated = FALSE;
|
||||
} else {
|
||||
if (seteuid(oldeuid) != 0) {
|
||||
FatalError("Failed to drop privileges. Exiting\n");
|
||||
}
|
||||
privsElevated = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
privsTested = TRUE;
|
||||
}
|
||||
return privsElevated;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86CreateRootWindow(WindowPtr pWin)
|
||||
{
|
||||
|
@ -872,7 +931,7 @@ OsVendorInit(void)
|
|||
|
||||
#ifdef O_NONBLOCK
|
||||
if (!beenHere) {
|
||||
if (geteuid() == 0 && getuid() != geteuid())
|
||||
if (xf86PrivsElevated())
|
||||
{
|
||||
int status;
|
||||
|
||||
|
@ -1043,10 +1102,11 @@ ddxProcessArgument(int argc, char **argv, int i)
|
|||
FatalError("Required argument to %s not specified\n", argv[i]); \
|
||||
}
|
||||
|
||||
/* First the options that are only allowed for root */
|
||||
/* First the options that are not allowed with elevated privileges */
|
||||
if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
|
||||
if ( (geteuid() == 0) && (getuid() != 0) ) {
|
||||
FatalError("The '%s' option can only be used by root.\n", argv[i]);
|
||||
if (xf86PrivsElevated()) {
|
||||
FatalError("The '%s' option cannot be used with "
|
||||
"elevated privileges.\n", argv[i]);
|
||||
}
|
||||
else if (!strcmp(argv[i], "-modulepath"))
|
||||
{
|
||||
|
@ -1074,9 +1134,9 @@ ddxProcessArgument(int argc, char **argv, int i)
|
|||
if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
|
||||
{
|
||||
CHECK_FOR_REQUIRED_ARGUMENT();
|
||||
if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
|
||||
if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) {
|
||||
FatalError("\nInvalid argument for %s\n"
|
||||
"\tFor non-root users, the file specified with %s must be\n"
|
||||
"\tWith elevated privileges, the file specified with %s must be\n"
|
||||
"\ta relative path and must not contain any \"..\" elements.\n"
|
||||
"\tUsing default "__XCONFIGFILE__" search path.\n\n",
|
||||
argv[i], argv[i]);
|
||||
|
@ -1087,9 +1147,9 @@ ddxProcessArgument(int argc, char **argv, int i)
|
|||
if (!strcmp(argv[i], "-configdir"))
|
||||
{
|
||||
CHECK_FOR_REQUIRED_ARGUMENT();
|
||||
if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
|
||||
if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) {
|
||||
FatalError("\nInvalid argument for %s\n"
|
||||
"\tFor non-root users, the file specified with %s must be\n"
|
||||
"\tWith elevated privileges, the file specified with %s must be\n"
|
||||
"\ta relative path and must not contain any \"..\" elements.\n"
|
||||
"\tUsing default "__XCONFIGDIR__" search path.\n\n",
|
||||
argv[i], argv[i]);
|
||||
|
@ -1375,7 +1435,7 @@ ddxUseMsg(void)
|
|||
ErrorF("\n");
|
||||
ErrorF("\n");
|
||||
ErrorF("Device Dependent Usage\n");
|
||||
if (getuid() == 0 || geteuid() != 0)
|
||||
if (!xf86PrivsElevated())
|
||||
{
|
||||
ErrorF("-modulepath paths specify the module search path\n");
|
||||
ErrorF("-logfile file specify a log file name\n");
|
||||
|
|
|
@ -145,6 +145,7 @@ extern _X_EXPORT Bool xf86LoadModules(char **list, pointer *optlist);
|
|||
extern _X_EXPORT int xf86SetVerbosity(int verb);
|
||||
extern _X_EXPORT int xf86SetLogVerbosity(int verb);
|
||||
extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only );
|
||||
extern _X_EXPORT Bool xf86PrivsElevated(void);
|
||||
|
||||
#endif /* _NO_XF86_PROTOTYPES */
|
||||
|
||||
|
|
|
@ -130,4 +130,10 @@
|
|||
/* Use libpciaccess */
|
||||
#undef XSERVER_LIBPCIACCESS
|
||||
|
||||
/* Have setugid */
|
||||
#undef HAVE_ISSETUGID
|
||||
|
||||
/* Have getresuid */
|
||||
#undef HAVE_GETRESUID
|
||||
|
||||
#endif /* _XORG_CONFIG_H_ */
|
||||
|
|
Loading…
Reference in New Issue
Block a user