[Intel-gfx] [PATCH 8/9] external/drm: Validate all memory allocations

Praveen Paneri praveen.paneri at intel.com
Thu Mar 5 21:45:13 PST 2015


This patch adds check for various malloc/calloc function if they
were able to allocate memory as requested or not. Return
appropriate error if the allocation fails.

Signed-off-by: Praveen Paneri <praveen.paneri at intel.com>
---
 intel/intel_bufmgr_fake.c |  4 ++++
 intel/intel_bufmgr_gem.c  |  3 +++
 intel/intel_decode.c      |  2 ++
 xf86drm.c                 | 54 +++++++++++++++++++++++++++++++++++++----------
 xf86drmHash.c             |  9 ++++++++
 xf86drmSL.c               |  2 ++
 6 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/intel/intel_bufmgr_fake.c b/intel/intel_bufmgr_fake.c
index ed31c23..c00aa80 100644
--- a/intel/intel_bufmgr_fake.c
+++ b/intel/intel_bufmgr_fake.c
@@ -1277,6 +1277,8 @@ drm_intel_fake_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 	if (bo_fake->relocs == NULL) {
 		bo_fake->relocs =
 		    malloc(sizeof(struct fake_buffer_reloc) * MAX_RELOCS);
+		if (!bo_fake->relocs)
+			return -ENOMEM;
 	}
 
 	r = &bo_fake->relocs[bo_fake->nr_relocs++];
@@ -1596,6 +1598,8 @@ drm_intel_bufmgr *drm_intel_bufmgr_fake_init(int fd,
 	drm_intel_bufmgr_fake *bufmgr_fake;
 
 	bufmgr_fake = calloc(1, sizeof(*bufmgr_fake));
+	if (!bufmgr_fake)
+		return NULL;
 
 	if (pthread_mutex_init(&bufmgr_fake->lock, NULL) != 0) {
 		free(bufmgr_fake);
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index 8251efd..5bf33c4 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -2261,6 +2261,9 @@ aub_write_bo_data(drm_intel_bo *bo, uint32_t offset, uint32_t size)
 	unsigned int i;
 
 	data = malloc(bo->size);
+	if (!data)
+		return;
+
 	drm_intel_bo_get_subdata(bo, offset, size, data);
 
 	/* Easy mode: write out bo with no relocations */
diff --git a/intel/intel_decode.c b/intel/intel_decode.c
index 5a4fc4a..015ef20 100644
--- a/intel/intel_decode.c
+++ b/intel/intel_decode.c
@@ -3907,6 +3907,8 @@ drm_intel_decode(struct drm_intel_decode *ctx)
 	 * checking in statically sized packets.
 	 */
 	temp = malloc(size + 4096);
+	if (!temp)
+		return;
 	memcpy(temp, ctx->base_data, size);
 	memset((char *)temp + size, 0xd0, 4096);
 	ctx->data = temp;
diff --git a/xf86drm.c b/xf86drm.c
index df56f9e..8b206e3 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -194,6 +194,8 @@ drmHashEntry *drmGetEntry(int fd)
 
     if (drmHashTable && drmHashLookup(drmHashTable, key, &value)) {
 	entry           = drmMalloc(sizeof(*entry));
+	if (!entry)
+	    return NULL;
 	entry->fd       = fd;
 	entry->f        = NULL;
 	entry->tagTable = drmHashCreate();
@@ -735,6 +737,8 @@ drmVersionPtr drmGetVersion(int fd)
 {
     drmVersionPtr retval;
     drm_version_t *version = drmMalloc(sizeof(*version));
+    if (!version)
+	return NULL;
 
     version->name_len    = 0;
     version->name        = NULL;
@@ -767,7 +771,9 @@ drmVersionPtr drmGetVersion(int fd)
     if (version->desc_len) version->desc[version->desc_len] = '\0';
 
     retval = drmMalloc(sizeof(*retval));
-    drmCopyVersion(retval, version);
+    if (retval)
+        drmCopyVersion(retval, version);
+
     drmFreeKernelVersion(version);
     return retval;
 }
@@ -789,6 +795,8 @@ drmVersionPtr drmGetVersion(int fd)
 drmVersionPtr drmGetLibVersion(int fd)
 {
     drm_version_t *version = drmMalloc(sizeof(*version));
+    if (!version)
+	return NULL;
 
     /* Version history:
      *   NOTE THIS MUST NOT GO ABOVE VERSION 1.X due to drivers needing it
@@ -1190,14 +1198,25 @@ drmBufInfoPtr drmGetBufInfo(int fd)
 	}
 
 	retval = drmMalloc(sizeof(*retval));
+	if (!retval) {
+	    drmFree(info.list);
+	    return NULL;
+	}
+
 	retval->count = info.count;
 	retval->list  = drmMalloc(info.count * sizeof(*retval->list));
-	for (i = 0; i < info.count; i++) {
-	    retval->list[i].count     = info.list[i].count;
-	    retval->list[i].size      = info.list[i].size;
-	    retval->list[i].low_mark  = info.list[i].low_mark;
-	    retval->list[i].high_mark = info.list[i].high_mark;
+	if (retval->list) {
+	    for (i = 0; i < info.count; i++) {
+	        retval->list[i].count     = info.list[i].count;
+	        retval->list[i].size      = info.list[i].size;
+	        retval->list[i].low_mark  = info.list[i].low_mark;
+	        retval->list[i].high_mark = info.list[i].high_mark;
+	    }
+	} else {
+	    drmFree(retval);
+	    retval = NULL;
 	}
+
 	drmFree(info.list);
 	return retval;
     }
@@ -1243,13 +1262,23 @@ drmBufMapPtr drmMapBufs(int fd)
 	}
 
 	retval = drmMalloc(sizeof(*retval));
+	if (!retval) {
+	    drmFree(bufs.list);
+            return NULL;
+	}
+
 	retval->count = bufs.count;
 	retval->list  = drmMalloc(bufs.count * sizeof(*retval->list));
-	for (i = 0; i < bufs.count; i++) {
-	    retval->list[i].idx     = bufs.list[i].idx;
-	    retval->list[i].total   = bufs.list[i].total;
-	    retval->list[i].used    = 0;
-	    retval->list[i].address = bufs.list[i].address;
+	if (retval->list) {
+	    for (i = 0; i < bufs.count; i++) {
+	        retval->list[i].idx     = bufs.list[i].idx;
+	        retval->list[i].total   = bufs.list[i].total;
+	        retval->list[i].used    = 0;
+	        retval->list[i].address = bufs.list[i].address;
+	    }
+	} else {
+	    drmFree(retval);
+	    retval = NULL;
 	}
 
 	drmFree(bufs.list);
@@ -2612,6 +2641,9 @@ int drmCSCIoctl(int fd, struct CSCCoeff_Matrix *CSC_Matrix)
     }
 
     pCSCCoeff = (struct csc_coeff *)malloc(sizeof(struct csc_coeff));
+    if (!pCSCCoeff)
+	return -ENOMEM;
+
     Calc_CSC_Param(CSC_Matrix, pCSCCoeff, devid);
     pCSCCoeff->crtc_id = CSC_Matrix->crtc_id;
 
diff --git a/xf86drmHash.c b/xf86drmHash.c
index 82cbc2a..56e9af3 100644
--- a/xf86drmHash.c
+++ b/xf86drmHash.c
@@ -70,6 +70,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #define HASH_MAIN 0
 
@@ -79,6 +80,7 @@
 
 #define HASH_MAGIC 0xdeadbeef
 #define HASH_DEBUG 0
+#define HASH_INVALID 0xffffffff	/* A value that is out of bound */
 #define HASH_SIZE  512		/* Good for about 100 entries */
 				/* If you change this value, you probably
                                    have to change the HashHash hashing
@@ -137,6 +139,8 @@ static unsigned long HashHash(unsigned long key)
     if (!init) {
 	HASH_RANDOM_DECL;
 	HASH_RANDOM_INIT(37);
+	if (!state)
+		return HASH_INVALID;
 	for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM;
 	HASH_RANDOM_DESTROY;
 	++init;
@@ -203,6 +207,9 @@ static HashBucketPtr HashFind(HashTablePtr table,
 
     if (h) *h = hash;
 
+    if (hash == HASH_INVALID)
+	return NULL;
+
     for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
 	if (bucket->key == key) {
 	    if (prev) {
@@ -244,6 +251,7 @@ int drmHashInsert(void *t, unsigned long key, void *value)
     if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
 
     if (HashFind(table, key, &hash)) return 1; /* Already in table */
+    if (hash == HASH_INVALID) return -1;
 
     bucket               = HASH_ALLOC(sizeof(*bucket));
     if (!bucket) return -1;	/* Error */
@@ -267,6 +275,7 @@ int drmHashDelete(void *t, unsigned long key)
 
     bucket = HashFind(table, key, &hash);
 
+    if (hash == HASH_INVALID) return -1;
     if (!bucket) return 1;	/* Not found */
 
     table->buckets[hash] = bucket->next;
diff --git a/xf86drmSL.c b/xf86drmSL.c
index 45f3906..00ae9f9 100644
--- a/xf86drmSL.c
+++ b/xf86drmSL.c
@@ -40,6 +40,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #define SL_MAIN 0
 
@@ -124,6 +125,7 @@ static int SLRandomLevel(void)
     SL_RANDOM_DECL;
 
     SL_RANDOM_INIT(SL_RANDOM_SEED);
+    if (!state) return -ENOMEM;
     
     while ((SL_RANDOM & 0x01) && level < SL_MAX_LEVEL) ++level;
     return level;
-- 
1.9.1



More information about the Intel-gfx mailing list