[PATCH xserver v2 4/4] glx: honor LIBGL_DRIVERS_PATH when loading DRI drivers

2018-03-13 Thread Ben Crocker
From: Nicolai Hähnle <nicolai.haeh...@amd.com>

Allow switching to another driver build without a full installation.

Glamor already takes LIBGL_DRIVERS_PATH into account, so this change
makes sure that the same driver is used in both parts of the server.

Signed-off-by: Nicolai Hähnle <nicolai.haeh...@amd.com>
Reviewed-by: Ben Crocker <bcroc...@redhat.com>
Reviewed-by: Antoine Martin <anto...@nagafix.co.uk>
Tested-by: Ben Crocker <bcroc...@redhat.com>
---
 glx/glxdricommon.c | 38 ++
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/glx/glxdricommon.c b/glx/glxdricommon.c
index a16e72849..a6602f930 100644
--- a/glx/glxdricommon.c
+++ b/glx/glxdricommon.c
@@ -272,14 +272,44 @@ glxProbeDriver(const char *driverName,
 char filename[PATH_MAX];
 char *get_extensions_name;
 const __DRIextension **extensions = NULL;
+const char *path = NULL;
+
+/* Search in LIBGL_DRIVERS_PATH if we're not setuid. */
+if (!PrivsElevated())
+path = getenv("LIBGL_DRIVERS_PATH");
+
+if (!path)
+path = dri_driver_path;
+
+do {
+const char *next;
+int path_len;
+
+next = strchr(path, ':');
+if (next) {
+path_len = next - path;
+next++;
+} else {
+path_len = strlen(path);
+next = NULL;
+}
 
-snprintf(filename, sizeof filename, "%s/%s_dri.so",
- dri_driver_path, driverName);
+snprintf(filename, sizeof filename, "%.*s/%s_dri.so", path_len, path,
+ driverName);
+
+driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+if (driver != NULL)
+break;
 
-driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
-if (driver == NULL) {
 LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
filename, dlerror());
+
+path = next;
+} while (path);
+
+if (driver == NULL) {
+LogMessage(X_ERROR, "AIGLX error: unable to load driver %s\n",
+  driverName);
 goto cleanup_failure;
 }
 
-- 
2.13.6

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH xserver v2 2/4] os: use PrivsElevated instead of a manual check

2018-03-13 Thread Ben Crocker
From: Nicolai Hähnle <nicolai.haeh...@amd.com>

Signed-off-by: Nicolai Hähnle <nicolai.haeh...@amd.com>
Reviewed-by: Ben Crocker <bcroc...@redhat.com>
Reviewed-by: Antoine Martin <anto...@nagafix.co.uk>
Tested-by: Ben Crocker <bcroc...@redhat.com>
---
 os/utils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/os/utils.c b/os/utils.c
index 4305dab26..6e3c16869 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1863,7 +1863,7 @@ CheckUserParameters(int argc, char **argv, char **envp)
 char *a, *e = NULL;
 
 #if CHECK_EUID
-if (geteuid() == 0 && getuid() != geteuid())
+if (PrivsElevated())
 #endif
 {
 /* Check each argv[] */
-- 
2.13.6

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

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

2018-03-13 Thread Ben Crocker
From: Nicolai Hähnle <nicolai.haeh...@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.haeh...@amd.com>
Reviewed-by: Ben Crocker <bcroc...@redhat.com>
Reviewed-by: Antoine Martin <anto...@nagafix.co.uk>
Tested-by: Ben Crocker <bcroc...@redhat.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 cdbf80c61..88d202463 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -238,64 +238,7 @@ xf86PrintBanner(void)
 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(, , ) == 0) &&
-(getresgid(, , ) == 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
diff --git a/include/os.h b/include/os.h
index e141a6b02..7b4cb9481 100644
--- a/include/os.h
+++ b/include/os.h
@@ -368,6 +368,9 @@ System(const char *cmdline);
 #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
diff --git a/os/utils.c b/os/utils.c
index 4a8d1249f..4305dab26 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1719,6 +1719,69 @@ System(const char *cmdline)
 }
 #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(, , ) == 0) &&
+(getresgid(, , ) == 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) 

[PATCH xserver v2 0/4] Improve elevated priv check, honor LIBGL_DRIVERS_PATH

2018-03-13 Thread Ben Crocker
Submit Nicolai Hähnle's four-patch series improving the checks for
elevated privileges and culminating in using the runtime environmental
control LIBGL_DRIVERS_PATH when searching for driver .so's, as
Mesa, and hence Glamor, already do.

The fourth patch prevents a conflict that can arise if, for example,
different versions of a driver reside in user's LIBGL_DRIVER_PATH
(e.g. $HOME/local/lib/dri) and Xserver's (build-time) DRI_DRIVER_PATH
(by default /usr/local/lib64/dri).

Nicolai Hähnle (4):
  os: move xf86PrivsElevated here
  os: use PrivsElevated instead of a manual check
  xfree86: replace all uses of xf86PrivsElevated with PrivsElevated
  glx: honor LIBGL_DRIVERS_PATH when loading DRI drivers

 glx/glxdricommon.c | 38 ---
 hw/xfree86/common/xf86Config.c |  2 +-
 hw/xfree86/common/xf86Init.c   | 69 ++
 hw/xfree86/common/xf86Priv.h   |  2 --
 include/os.h   |  3 ++
 os/utils.c | 65 ++-
 6 files changed, 105 insertions(+), 74 deletions(-)

-- 
2.13.6

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH xserver v2 3/4] xfree86: replace all uses of xf86PrivsElevated with PrivsElevated

2018-03-13 Thread Ben Crocker
From: Nicolai Hähnle <nicolai.haeh...@amd.com>

Signed-off-by: Nicolai Hähnle <nicolai.haeh...@amd.com>
Reviewed-by: Ben Crocker <bcroc...@redhat.com>
Reviewed-by: Antoine Martin <anto...@nagafix.co.uk>
Tested-by: Ben Crocker <bcroc...@redhat.com>
---
 hw/xfree86/common/xf86Config.c |  2 +-
 hw/xfree86/common/xf86Init.c   | 12 +++-
 hw/xfree86/common/xf86Priv.h   |  2 --
 3 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 2f72c2f76..05991d319 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -2275,7 +2275,7 @@ xf86HandleConfigFile(Bool autoconfig)
 MessageType filefrom = X_DEFAULT;
 MessageType dirfrom = X_DEFAULT;
 
-if (!xf86PrivsElevated()) {
+if (!PrivsElevated()) {
 filesearch = ALL_CONFIGPATH;
 dirsearch = ALL_CONFIGDIRPATH;
 }
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 88d202463..53e8a25dd 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -235,12 +235,6 @@ xf86PrintBanner(void)
"\tto make sure that you have the latest version.\n");
 }
 
-Bool
-xf86PrivsElevated(void)
-{
-return PrivsElevated();
-}
-
 static void
 TrapSignals(void)
 {
@@ -853,7 +847,7 @@ OsVendorInit(void)
 
 #ifdef O_NONBLOCK
 if (!beenHere) {
-if (xf86PrivsElevated()) {
+if (PrivsElevated()) {
 int status;
 
 status = fcntl(fileno(stderr), F_GETFL, 0);
@@ -1002,7 +996,7 @@ xf86PrintDefaultLibraryPath(void)
 static void
 xf86CheckPrivs(const char *option, const char *arg)
 {
-if (xf86PrivsElevated() && !xf86PathIsSafe(arg)) {
+if (PrivsElevated() && !xf86PathIsSafe(arg)) {
 FatalError("\nInvalid argument for %s - \"%s\"\n"
 "\tWith elevated privileges %s must specify a relative 
path\n"
 "\twithout any \"..\" elements.\n\n", option, arg, option);
@@ -1299,7 +1293,7 @@ ddxUseMsg(void)
 ErrorF("\n");
 ErrorF("\n");
 ErrorF("Device Dependent Usage\n");
-if (!xf86PrivsElevated()) {
+if (!PrivsElevated()) {
 ErrorF("-modulepath paths  specify the module search path\n");
 ErrorF("-logfile file  specify a log file name\n");
 ErrorF("-configure probe for devices and write an "
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 4fe2b5f33..06e359e6a 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -156,8 +156,6 @@ 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 */
 
-- 
2.13.6

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [xserver,1/4] os: move xf86PrivsElevated here

2018-03-13 Thread Ben Crocker
Antoine, thanks for the suggestion and the additional review.  V2 patch
series forthcoming.

-- Ben


On Sat, Mar 10, 2018 at 11:58 PM, Antoine Martin <anto...@nagafix.co.uk>
wrote:

> On 09/03/18 05:11, Ben Crocker wrote:
> > Sent that a little too soon; please consider "Reviewed-by: Ben Crocker
> > <bcroc...@redhat.com <mailto:bcroc...@redhat.com>>" to be
> > added after each of the "Signed-off-by: Nicolai Haehnle
> > <nicolai.haeh...@amd.com <mailto:nicolai.haeh...@amd.com>>" lines.
> You can add:
> Reviewed-by: Antoine Martin <anto...@nagafix.co.uk>
>
> You should probably re-send the patch series as individual emails.
>
> Cheers
> Antoine
>
>
> >
> > Also please note that I rebased Nicolai's original patch,
> > https://patchwork.freedesktop.org/series/18684/,
> > against a very recent copy of master.
> >
> >   Thanks,
> >   Ben
> >
> >
> > On Thu, Mar 8, 2018 at 4:53 PM, Ben Crocker <bcroc...@redhat.com
> > <mailto:bcroc...@redhat.com>> wrote:
> >
> > From: Nicolai Hähnle <nhaeh...@gmail.com <mailto:nhaeh...@gmail.com
> >>
> >
> > From: Nicolai Hähnle <nicolai.haeh...@amd.com
> > <mailto:nicolai.haeh...@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.haeh...@amd.com
> > <mailto:nicolai.haeh...@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(, , ) == 0) &&
> > -(getresgid(, , ) == 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 

Re: [xserver,1/4] os: move xf86PrivsElevated here

2018-03-08 Thread Ben Crocker
Sent that a little too soon; please consider "Reviewed-by: Ben Crocker <
bcroc...@redhat.com>" to be
added after each of the "Signed-off-by: Nicolai Haehnle <
nicolai.haeh...@amd.com>" lines.

Also please note that I rebased Nicolai's original patch,
https://patchwork.freedesktop.org/series/18684/,
against a very recent copy of master.

  Thanks,
  Ben


On Thu, Mar 8, 2018 at 4:53 PM, Ben Crocker <bcroc...@redhat.com> wrote:

> From: Nicolai Hähnle <nhaeh...@gmail.com>
>
> From: Nicolai Hähnle <nicolai.haeh...@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.haeh...@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(, , ) == 0) &&
> -(getresgid(, , ) == 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
>  TrapSignals(void)
>  {
>  if (xf86Info.notrapSignals) {
>  OsSignal(SIGSEGV, SIG_DFL);
>  OsSignal(SIGABRT, SIG_DFL);
>  OsSignal(SIGILL, SIG_DFL);
>  #ifdef SIGEMT
> 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

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

2018-03-08 Thread Ben Crocker
From: Nicolai Hähnle 

From: Nicolai Hähnle 

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 
---
 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(, , ) == 0) &&
-(getresgid(, , ) == 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
 TrapSignals(void)
 {
 if (xf86Info.notrapSignals) {
 OsSignal(SIGSEGV, SIG_DFL);
 OsSignal(SIGABRT, SIG_DFL);
 OsSignal(SIGILL, SIG_DFL);
 #ifdef SIGEMT
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(, , ) == 0) &&
+(getresgid(, , ) == 0)) {
+privsElevated = (euid != suid) || (egid != sgid);
+}
+else {
+printf("Failed getresuid or getresgid");
+/* Something went wrong, make defensive assumption */
+privsElevated = TRUE;
+}
+#else
+

[PATCH xserver] Fix a segfault that occurs if xorg.conf.d is absent:

2016-11-15 Thread Ben Crocker
In InitOutput, if xf86HandleConfigFile returns CONFIG_NOFILE
(which it does if no config file or directory is present), the
autoconfig flag is set, causing xf86AutoConfig to be called
later on.

xf86AutoConfig calls xf86OutputClassDriverList via the
call tree:

xf86AutoConfig =>
  listPossibleVideoDrivers =>
xf86PlatformMatchDriver =>
  xf86OutputClassDriverList

and xf86OutputClassDriverList attempts to traverse a linked list
that is a member of the XF86ConfigRec struct pointed to by the
global xf86configptr, which is NULL at this point because the
XF86ConfigRec struct is only allocated (by xf86readConfigFile)
AFTER the config file and directory have been successfully
opened; the CONFIG_NOFILE return from xf86HandleConfigFile
occurs BEFORE the call to xf86readConfigFile which allocates
the XF86ConfigRec struct.

Rx: In read.c (for symmetry with xf86freeConfig, which already
appears in this file), add a new function xf86allocateConfig
which tests the value of xf86configptr and, if it's NULL,
allocates the XF86ConfigRec struct and deposits the pointer
in xf86configptr.  In xf86Parser.h, add a prototype for the
new xf86allocateConfig function.

Back in read.c, #include "xf86Config.h".  In xf86readConfigFile,
change the open-code call to calloc to a call to the new
xf86allocateConfig function.

In xf86AutoConfig.c, add a call to the new xf86allocateConfig function
to the beginning of xf86AutoConfig to make sure the XF86ConfigRec struct
is allocated.

Signed-off-by: Ben Crocker <bcroc...@redhat.com>
---
 hw/xfree86/common/xf86AutoConfig.c |  9 +
 hw/xfree86/parser/read.c   | 16 +++-
 hw/xfree86/parser/xf86Parser.h |  1 +
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/hw/xfree86/common/xf86AutoConfig.c 
b/hw/xfree86/common/xf86AutoConfig.c
index 9402651..c3e17be 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -149,6 +149,15 @@ xf86AutoConfig(void)
 char buf[1024];
 ConfigStatus ret;
 
+/* Make sure config rec is there */
+if (xf86allocateConfig() != NULL) {
+ret = CONFIG_OK;/* OK so far */
+}
+else {
+xf86Msg(X_ERROR, "Couldn't allocate Config record.\n");
+return FALSE;
+}
+
 listPossibleVideoDrivers(deviceList, 20);
 
 for (p = deviceList; *p; p++) {
diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
index ec038ae..d7e7312 100644
--- a/hw/xfree86/parser/read.c
+++ b/hw/xfree86/parser/read.c
@@ -56,6 +56,7 @@
 #include 
 #endif
 
+#include "xf86Config.h"
 #include "xf86Parser.h"
 #include "xf86tokens.h"
 #include "Configint.h"
@@ -91,7 +92,7 @@ xf86readConfigFile(void)
 int token;
 XF86ConfigPtr ptr = NULL;
 
-if ((ptr = calloc(1, sizeof(XF86ConfigRec))) == NULL) {
+if ((ptr = xf86allocateConfig()) == NULL) {
 return NULL;
 }
 
@@ -270,6 +271,19 @@ xf86itemNotSublist(GenericListPtr list_1, GenericListPtr 
list_2)
 return (!(last_1 == last_2));
 }
 
+/*
+ * Conditionally allocate config struct, but only allocate it
+ * if it's not already there.  In either event, return the pointer
+ * to the global config struct.
+ */
+XF86ConfigPtr xf86allocateConfig(void)
+{
+if (!xf86configptr) {
+xf86configptr = calloc(1, sizeof(XF86ConfigRec));
+}
+return xf86configptr;
+}
+
 void
 xf86freeConfig(XF86ConfigPtr p)
 {
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index ff35846..9c4b403 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -449,6 +449,7 @@ extern char *xf86openConfigDirFiles(const char *path, const 
char *cmdline,
 extern void xf86setBuiltinConfig(const char *config[]);
 extern XF86ConfigPtr xf86readConfigFile(void);
 extern void xf86closeConfigFile(void);
+extern XF86ConfigPtr xf86allocateConfig(void);
 extern void xf86freeConfig(XF86ConfigPtr p);
 extern int xf86writeConfigFile(const char *, XF86ConfigPtr);
 extern _X_EXPORT XF86ConfDevicePtr xf86findDevice(const char *ident,
-- 
2.7.4

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel