Commit d1f9c16b authored by José Hiram Soltren's avatar José Hiram Soltren Committed by Aaron Plattner
Browse files

Use secure_getenv(3) to improve security



This patch is in response to the following security vulnerabilities
(CVEs) reported to NVIDIA against libvdpau:

CVE-2015-5198
CVE-2015-5199
CVE-2015-5200

To address these CVEs, this patch:

- replaces all uses of getenv(3) with secure_getenv(3);
- uses secure_getenv(3) when available, with a fallback option;
- protects VDPAU_DRIVER against directory traversal by checking for '/'

On platforms where secure_getenv(3) is not available, the C preprocessor
will print a warning at compile time. Then, a preprocessor macro will
replace secure_getenv(3) with our getenv_wrapper(), which utilizes the check:

  getuid() == geteuid() && getgid() == getegid()

See getuid(2) and getgid(2) for further details.
Signed-off-by: default avatarAaron Plattner <aplattner@nvidia.com>
Reviewed-by: default avatarFlorian Weimer <fweimer@redhat.com>
parent 47fd4e8e
...@@ -5,6 +5,10 @@ AM_INIT_AUTOMAKE([dist-bzip2 foreign]) ...@@ -5,6 +5,10 @@ AM_INIT_AUTOMAKE([dist-bzip2 foreign])
AC_CONFIG_HEADERS(config.h) AC_CONFIG_HEADERS(config.h)
# Check for secure_getenv
AC_USE_SYSTEM_EXTENSIONS
AC_CHECK_FUNCS([__secure_getenv secure_getenv])
# Disable static libraries by default. Use --enable-static if you really want # Disable static libraries by default. Use --enable-static if you really want
# them. # them.
AC_DISABLE_STATIC AC_DISABLE_STATIC
......
...@@ -9,6 +9,7 @@ lib_LTLIBRARIES = libvdpau.la ...@@ -9,6 +9,7 @@ lib_LTLIBRARIES = libvdpau.la
libvdpau_la_SOURCES = \ libvdpau_la_SOURCES = \
vdpau_wrapper.c \ vdpau_wrapper.c \
util.h \
$(DRI2_SOURCES) $(DRI2_SOURCES)
if DRI2 if DRI2
......
/* /*
* Copyright © 2008 Red Hat, Inc. * Copyright © 2008 Red Hat, Inc.
* Copyright © 2010 NVIDIA Corporation * Copyright © 2010-2015 NVIDIA Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft- * copy of this software and associated documentation files (the "Soft-
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
* Authors: * Authors:
* Kristian Høgsberg (krh@redhat.com) * Kristian Høgsberg (krh@redhat.com)
* Modified for VDPAU by Aaron Plattner (aplattner@nvidia.com) * Modified for VDPAU by Aaron Plattner (aplattner@nvidia.com)
* and José Hiram Soltren (jsoltren@nvidia.com)
*/ */
...@@ -39,6 +40,7 @@ ...@@ -39,6 +40,7 @@
#include <X11/extensions/extutil.h> #include <X11/extensions/extutil.h>
#include <X11/extensions/dri2proto.h> #include <X11/extensions/dri2proto.h>
#include "mesa_dri2.h" #include "mesa_dri2.h"
#include "util.h"
static char dri2ExtensionName[] = DRI2_NAME; static char dri2ExtensionName[] = DRI2_NAME;
static XExtensionInfo *dri2Info; static XExtensionInfo *dri2Info;
...@@ -130,7 +132,7 @@ _vdp_DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName ...@@ -130,7 +132,7 @@ _vdp_DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName
req->driverType = DRI2DriverVDPAU; req->driverType = DRI2DriverVDPAU;
#ifdef DRI2DriverPrimeShift #ifdef DRI2DriverPrimeShift
{ {
char *prime = getenv("DRI_PRIME"); char *prime = secure_getenv("DRI_PRIME");
if (prime) { if (prime) {
unsigned int primeid; unsigned int primeid;
errno = 0; errno = 0;
......
/*
* Copyright (c) 2015 NVIDIA Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include <stdlib.h>
static char * getenv_wrapper(const char *name)
{
if (getuid() == geteuid() && getgid() == getegid()) {
return getenv(name);
}
else {
return NULL;
}
}
#ifndef HAVE_SECURE_GETENV
# ifdef HAVE___SECURE_GETENV
# define secure_getenv __secure_getenv
# else
# warning Neither secure_getenv nor __secure_getenv is available.
# define secure_getenv getenv_wrapper
# endif
#endif
/* /*
* Copyright (c) 2008-2009 NVIDIA, Corporation * Copyright (c) 2008-2015 NVIDIA Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "mesa_dri2.h" #include "mesa_dri2.h"
#include <X11/Xlib.h> #include <X11/Xlib.h>
#endif #endif
#include "util.h"
typedef void SetDllHandle( typedef void SetDllHandle(
void * driver_dll_handle void * driver_dll_handle
...@@ -117,7 +118,12 @@ static VdpStatus _vdp_open_driver( ...@@ -117,7 +118,12 @@ static VdpStatus _vdp_open_driver(
char const * vdpau_trace; char const * vdpau_trace;
char const * func_name; char const * func_name;
vdpau_driver = getenv("VDPAU_DRIVER"); vdpau_driver = secure_getenv("VDPAU_DRIVER");
if (vdpau_driver) {
if (strchr(vdpau_driver, '/')) {
vdpau_driver = NULL;
}
}
if (!vdpau_driver) { if (!vdpau_driver) {
vdpau_driver = vdpau_driver_dri2 = vdpau_driver = vdpau_driver_dri2 =
_vdp_get_driver_name_from_dri2(display, screen); _vdp_get_driver_name_from_dri2(display, screen);
...@@ -126,16 +132,14 @@ static VdpStatus _vdp_open_driver( ...@@ -126,16 +132,14 @@ static VdpStatus _vdp_open_driver(
vdpau_driver = "nvidia"; vdpau_driver = "nvidia";
} }
if (geteuid() == getuid()) { /* Don't allow setuid apps to use VDPAU_DRIVER_PATH */
/* don't allow setuid apps to use VDPAU_DRIVER_PATH */ vdpau_driver_path = secure_getenv("VDPAU_DRIVER_PATH");
vdpau_driver_path = getenv("VDPAU_DRIVER_PATH");
if (vdpau_driver_path && if (vdpau_driver_path &&
snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib), snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib),
DRIVER_LIB_FORMAT, vdpau_driver_path, vdpau_driver) < DRIVER_LIB_FORMAT, vdpau_driver_path, vdpau_driver) <
sizeof(vdpau_driver_lib)) { sizeof(vdpau_driver_lib)) {
_vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL); _vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
} }
}
/* Fallback to VDPAU_MODULEDIR when VDPAU_DRIVER_PATH is not set, /* Fallback to VDPAU_MODULEDIR when VDPAU_DRIVER_PATH is not set,
* or if we fail to create the driver path/dlopen the library. */ * or if we fail to create the driver path/dlopen the library. */
...@@ -177,7 +181,7 @@ static VdpStatus _vdp_open_driver( ...@@ -177,7 +181,7 @@ static VdpStatus _vdp_open_driver(
_vdp_backend_dll = _vdp_driver_dll; _vdp_backend_dll = _vdp_driver_dll;
vdpau_trace = getenv("VDPAU_TRACE"); vdpau_trace = secure_getenv("VDPAU_TRACE");
if (vdpau_trace && atoi(vdpau_trace)) { if (vdpau_trace && atoi(vdpau_trace)) {
SetDllHandle * set_dll_handle; SetDllHandle * set_dll_handle;
......
/* /*
* Copyright (c) 2008-2009 NVIDIA, Corporation * Copyright (c) 2008-2015 NVIDIA Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <string.h> #include <string.h>
#include <vdpau/vdpau_x11.h> #include <vdpau/vdpau_x11.h>
#include "../src/util.h"
#define _VDP_TRACE_ARSIZE(_x_) ((sizeof (_x_)) / (sizeof ((_x_)[0]))) #define _VDP_TRACE_ARSIZE(_x_) ((sizeof (_x_)) / (sizeof ((_x_)[0])))
#if DEBUG #if DEBUG
...@@ -4795,13 +4797,13 @@ VdpStatus vdp_trace_device_create_x11( ...@@ -4795,13 +4797,13 @@ VdpStatus vdp_trace_device_create_x11(
} }
else { else {
_vdp_cap_data.level = 0; _vdp_cap_data.level = 0;
char const * vdpau_trace = getenv("VDPAU_TRACE"); char const * vdpau_trace = secure_getenv("VDPAU_TRACE");
if (vdpau_trace) { if (vdpau_trace) {
_vdp_cap_data.level = atoi(vdpau_trace); _vdp_cap_data.level = atoi(vdpau_trace);
} }
_vdp_cap_data.fp = 0; _vdp_cap_data.fp = 0;
char const * vdpau_trace_file = getenv("VDPAU_TRACE_FILE"); char const * vdpau_trace_file = secure_getenv("VDPAU_TRACE_FILE");
if (vdpau_trace_file && strlen(vdpau_trace_file)) { if (vdpau_trace_file && strlen(vdpau_trace_file)) {
if (vdpau_trace_file[0] == '&') { if (vdpau_trace_file[0] == '&') {
int fd = atoi(&vdpau_trace_file[1]); int fd = atoi(&vdpau_trace_file[1]);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment