diff mbox

[3/3] libdrm: fix potential security issues in xf86drmSL.c

Message ID 1398437920-17394-4-git-send-email-tim.gore@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

tim.gore@intel.com April 25, 2014, 2:58 p.m. UTC
From: Tim Gore <tim.gore@intel.com>

A static analysis of libdrm source code has identified several
potential bugs. This commit addresses the critical issues in
xf86drmSL.c, which are mostly potential null pointer dereferences.
NOTE: I have kept to the indenting style already used in this file,
which is a mixture of spaces and tabs.

Signed-off-by: Tim Gore <tim.gore@intel.com>
---
 xf86drmSL.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/xf86drmSL.c b/xf86drmSL.c
index acddb54..7af5ada 100644
--- a/xf86drmSL.c
+++ b/xf86drmSL.c
@@ -62,12 +62,14 @@ 
 #define SL_RANDOM_DECL        static int state = 0;
 #define SL_RANDOM_INIT(seed)  if (!state) { srandom(seed); ++state; }
 #define SL_RANDOM             random()
+#define SL_RANDOM_OK          (1)
 #else
 #define SL_ALLOC drmMalloc
 #define SL_FREE  drmFree
 #define SL_RANDOM_DECL        static void *state = NULL
 #define SL_RANDOM_INIT(seed)  if (!state) state = drmRandomCreate(seed)
 #define SL_RANDOM             drmRandom(state)
+#define SL_RANDOM_OK          (state != NULL)
 
 #endif
 
@@ -124,8 +126,13 @@  static int SLRandomLevel(void)
     SL_RANDOM_DECL;
 
     SL_RANDOM_INIT(SL_RANDOM_SEED);
-    
-    while ((SL_RANDOM & 0x01) && level < SL_MAX_LEVEL) ++level;
+    if (SL_RANDOM_OK) {
+	while ((SL_RANDOM & 0x01) && level < SL_MAX_LEVEL) ++level;
+    } else {
+	/* if we failed to allocate our random number state, fall back on random() */
+	srandom(SL_RANDOM_SEED);
+	while ((random() & 0x01) && level < SL_MAX_LEVEL) ++level;
+    }
     return level;
 }
 
@@ -139,6 +146,10 @@  void *drmSLCreate(void)
     list->magic    = SL_LIST_MAGIC;
     list->level    = 0;
     list->head     = SLCreateEntry(SL_MAX_LEVEL, 0, NULL);
+    if (!list->head) {
+	SL_FREE(list);
+	return NULL;
+    }
     list->count    = 0;
 
     for (i = 0; i <= SL_MAX_LEVEL; i++) list->head->forward[i] = NULL;
@@ -205,8 +216,9 @@  int drmSLInsert(void *l, unsigned long key, void *value)
     }
 
     entry = SLCreateEntry(level, key, value);
+    if (!entry) return -1; /* couldn't allocate a new entry */
 
-				/* Fix up forward pointers */
+    /* Fix up forward pointers */
     for (i = 0; i <= level; i++) {
 	entry->forward[i]     = update[i]->forward[i];
 	update[i]->forward[i] = entry;
@@ -270,6 +282,8 @@  int drmSLLookupNeighbors(void *l, unsigned long key,
     *prev_key   = *next_key   = key;
     *prev_value = *next_value = NULL;
 	
+    (void) SLLocate(list, key, update);
+
     if (update[0]) {
 	*prev_key   = update[0]->key;
 	*prev_value = update[0]->value;