[PATCH xserver 1/4] os: move xf86PrivsElevated here

Nicolai Hähnle nhaehnle at gmail.com
Fri Jan 27 13:37:35 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

Having different types of code all trying to check for elevated privileges
is a bad idea. This implementation is the most thorough one.

Signed-off-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
---
 hw/xfree86/common/xf86Init.c | 59 +----------------------------------------
 include/os.h                 |  3 +++
 os/utils.c                   | 63 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+), 58 deletions(-)

diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index e61fe66..758b926 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -230,78 +230,21 @@ xf86PrintBanner(void)
     xf86ErrorFVerb(0, "Current version of pixman: %s\n",
                    pixman_version_string());
     xf86ErrorFVerb(0, "\tBefore reporting problems, check "
                    "" __VENDORDWEBSUPPORT__ "\n"
                    "\tto make sure that you have the latest version.\n");
 }
 
 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;
+    return PrivsElevated();
 }
 
 static void
 InstallSignalHandlers(void)
 {
     /*
      * Install signal handler for unexpected signals
      */
     xf86Info.caughtSignal = FALSE;
     if (!xf86Info.notrapSignals) {
diff --git a/include/os.h b/include/os.h
index d2c41b4..686f6d6 100644
--- a/include/os.h
+++ b/include/os.h
@@ -355,20 +355,23 @@ Fclose(void *);
 extern const char *
 Win32TempDir(void);
 
 extern int
 System(const char *cmdline);
 
 #define Fopen(a,b) fopen(a,b)
 #define Fclose(a) fclose(a)
 #endif
 
+extern _X_EXPORT Bool
+PrivsElevated(void);
+
 extern _X_EXPORT void
 CheckUserParameters(int argc, char **argv, char **envp);
 extern _X_EXPORT void
 CheckUserAuthorization(void);
 
 extern _X_EXPORT int
 AddHost(ClientPtr /*client */ ,
         int /*family */ ,
         unsigned /*length */ ,
         const void * /*pAddr */ );
diff --git a/os/utils.c b/os/utils.c
index ac55cd7..024989e 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1717,20 +1717,83 @@ System(const char *cmdline)
 
     /* Close process and thread handles. */
     CloseHandle(pi.hProcess);
     CloseHandle(pi.hThread);
     free(cmd);
 
     return dwExitCode;
 }
 #endif
 
+Bool
+PrivsElevated(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;
+}
+
 /*
  * CheckUserParameters: check for long command line arguments and long
  * environment variables.  By default, these checks are only done when
  * the server's euid != ruid.  In 3.3.x, these checks were done in an
  * external wrapper utility.
  */
 
 /* Consider LD* variables insecure? */
 #ifndef REMOVE_ENV_LD
 #define REMOVE_ENV_LD 1
-- 
2.7.4



More information about the xorg-devel mailing list