[VDPAU] [PATCH] Save the result from secure_getenv
Zach Angold
zangold at nvidia.com
Tue Feb 16 22:18:14 UTC 2016
The return value from secure_getenv is not guaranteed to be kept after
another call to secure_getenv, so we replace it with safe_secure_getenv,
which places the result of secure_getenv in a specified buffer.
---
src/mesa_dri2.c | 10 +++++++++-
src/util.h | 28 ++++++++++++++++++++++++++++
src/vdpau_wrapper.c | 29 ++++++++++++++++++++++++++---
3 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/src/mesa_dri2.c b/src/mesa_dri2.c
index 420ccee..d591a97 100644
--- a/src/mesa_dri2.c
+++ b/src/mesa_dri2.c
@@ -38,6 +38,7 @@
#endif
#define NEED_REPLIES
+#include <stdio.h>
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
@@ -135,7 +136,14 @@ _vdp_DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName
req->driverType = DRI2DriverVDPAU;
#ifdef DRI2DriverPrimeShift
{
- char *prime = secure_getenv("DRI_PRIME");
+ char primebuf[256];
+ const char *prime;
+ if (!safe_secure_getenv(&prime, "DRI_PRIME", primebuf, sizeof(primebuf))) {
+ fprintf(stderr, "Could not get DRI_PRIME: variable too long\n");
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
if (prime) {
unsigned int primeid;
errno = 0;
diff --git a/src/util.h b/src/util.h
index 39227ea..1d46d70 100644
--- a/src/util.h
+++ b/src/util.h
@@ -46,3 +46,31 @@ static inline char * getenv_wrapper(const char *name)
# define secure_getenv getenv_wrapper
# endif
#endif
+
+/*
+ * Copies the result of secure_getenv() to a buffer.
+ * (*result) will be equal to buf if secure_getenv succeeds, or NULL if
+ * there is no match or secure execution is required (see man page for getenv).
+ * Returns zero if the result of secure_getenv() does not fit in buf and buf,
+ * nonzero otherwise.
+ */
+static inline int safe_secure_getenv(const char **result,
+ const char *name,
+ char *buf,
+ size_t buflen)
+{
+ const char * env = secure_getenv(name);
+ if (env == NULL) {
+ (*result) = NULL;
+ return 1;
+ }
+
+ if (buf == NULL) {
+ return 1;
+ }
+
+ (*result) = buf;
+ strncpy(buf, env, buflen);
+
+ return strlen(env) < buflen;
+}
diff --git a/src/vdpau_wrapper.c b/src/vdpau_wrapper.c
index 79dcb94..325ea09 100644
--- a/src/vdpau_wrapper.c
+++ b/src/vdpau_wrapper.c
@@ -112,13 +112,22 @@ static VdpStatus _vdp_open_driver(
int screen)
{
char const * vdpau_driver;
+ char vdpau_driver_copy[PATH_MAX];
char * vdpau_driver_dri2 = NULL;
const char * vdpau_driver_path = NULL;
+ char vdpau_driver_path_copy[PATH_MAX];
char vdpau_driver_lib[PATH_MAX];
char const * vdpau_trace;
+ char vdpau_trace_copy[PATH_MAX];
char const * func_name;
- vdpau_driver = secure_getenv("VDPAU_DRIVER");
+ if (!safe_secure_getenv(&vdpau_driver, "VDPAU_DRIVER", vdpau_driver_copy,
+ sizeof(vdpau_driver_copy))) {
+ fprintf(stderr, "Failed to save VDPAU driver name: name too long\n");
+ _VDP_ERROR_BREAKPOINT();
+ return VDP_STATUS_NO_IMPLEMENTATION;
+ }
+
if (vdpau_driver) {
if (strchr(vdpau_driver, '/')) {
vdpau_driver = NULL;
@@ -133,7 +142,16 @@ static VdpStatus _vdp_open_driver(
}
/* Don't allow setuid apps to use VDPAU_DRIVER_PATH */
- vdpau_driver_path = secure_getenv("VDPAU_DRIVER_PATH");
+ if (!safe_secure_getenv(&vdpau_driver_path, "VDPAU_DRIVER_PATH",
+ vdpau_driver_path_copy, sizeof(vdpau_driver_path_copy))) {
+ fprintf(stderr, "Failed to save VDPAU driver path: path too long\n");
+ if (vdpau_driver_dri2) {
+ XFree(vdpau_driver_dri2);
+ vdpau_driver_dri2 = NULL;
+ }
+ _VDP_ERROR_BREAKPOINT();
+ return VDP_STATUS_NO_IMPLEMENTATION;
+ }
if (vdpau_driver_path &&
snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib),
DRIVER_LIB_FORMAT, vdpau_driver_path, vdpau_driver) <
@@ -181,7 +199,12 @@ static VdpStatus _vdp_open_driver(
_vdp_backend_dll = _vdp_driver_dll;
- vdpau_trace = secure_getenv("VDPAU_TRACE");
+ if (!safe_secure_getenv(&vdpau_trace, "VDPAU_TRACE", vdpau_trace_copy,
+ sizeof(vdpau_trace_copy))) {
+ fprintf(stderr, "Failed to save VDPAU_TRACE: result too long\n");
+ _VDP_ERROR_BREAKPOINT();
+ return VDP_STATUS_NO_IMPLEMENTATION;
+ }
if (vdpau_trace && atoi(vdpau_trace)) {
SetDllHandle * set_dll_handle;
--
2.1.4
More information about the VDPAU
mailing list