[Cbe-oss-dev] [PATCH] libspe2: Fix resource leaks in spe_context_create

Kazunori Asayama asayama at sm.sony.co.jp
Fri Apr 13 18:11:57 EST 2007


This patch fixes resource leaks in spe_context_create and
spe_gang_context_create in error conditions.

OK to apply ?

Signed-off-by: Kazunori Asayama <asayama at sm.sony.co.jp>

Index: libspe2-public/spebase/create.c
===================================================================
--- libspe2-public.orig/spebase/create.c
+++ libspe2-public/spebase/create.c
@@ -131,6 +131,44 @@ void close_if_open(struct spe_context *s
 	_base_spe_context_unlock(spe, fdesc);
 }
 
+static int free_spe_context(struct spe_context *spe)
+{
+	int i;
+
+	if(spe->base_private->psmap_mmap_base != (void*)-1) {
+		munmap(spe->base_private->psmap_mmap_base, PSMAP_SIZE);
+	}
+	else {
+		if(spe->base_private->mfc_mmap_base != (void*)-1)
+			munmap(spe->base_private->mfc_mmap_base, MFC_SIZE);
+		if(spe->base_private->mssync_mmap_base != (void*)-1)
+			munmap(spe->base_private->mssync_mmap_base, MSS_SIZE);
+		if(spe->base_private->cntl_mmap_base != (void*)-1)
+			munmap(spe->base_private->cntl_mmap_base, CNTL_SIZE);
+		if(spe->base_private->signal1_mmap_base != (void*)-1)
+			munmap(spe->base_private->signal1_mmap_base,SIGNAL_SIZE);
+		if(spe->base_private->signal2_mmap_base != (void*)-1)
+			munmap(spe->base_private->signal2_mmap_base, SIGNAL_SIZE);
+	}
+
+	if(spe->base_private->mem_mmap_base != (void*)-1)
+		munmap(spe->base_private->mem_mmap_base, LS_SIZE);
+
+	for ( i=0;i<NUM_MBOX_FDS;i++){
+		if (spe->base_private->spe_fds_array[i] >= 0)
+			close(spe->base_private->spe_fds_array[i]);
+		pthread_mutex_destroy(&spe->base_private->fd_lock[i]);
+	}
+
+	if (spe->base_private->fd_spe_dir >= 0)
+		close(spe->base_private->fd_spe_dir);
+
+	free(spe->base_private);
+	free(spe);
+
+	return 0;
+}
+
 spe_context_ptr_t _base_spe_context_create(unsigned int flags, spe_gang_context_ptr_t gctx, spe_context_ptr_t aff_spe)
 {
 	char pathname[256];
@@ -152,9 +190,12 @@ spe_context_ptr_t _base_spe_context_crea
 	spe->base_private = calloc (1, sizeof *spe->base_private);
 	if (!spe->base_private) {
 		DEBUG_PRINTF ("ERROR: Could not allocate spe->base_private context.\n");
+		free(spe);
 		errno = ENOMEM;
 		return NULL;
 	}
+
+	spe->base_private->fd_spe_dir = -1;
 	
 	spe->base_private->mem_mmap_base = (void*) -1;
 	spe->base_private->psmap_mmap_base = (void*) -1;
@@ -204,6 +245,7 @@ spe_context_ptr_t _base_spe_context_crea
 	if (spe->base_private->fd_spe_dir < 0) {
 		DEBUG_PRINTF ("ERROR: Could not create SPE %s\n", pathname);
 		perror("spu_create()");
+		free_spe_context(spe);
 		errno=EFAULT;
 		return NULL;
 	}
@@ -216,6 +258,7 @@ spe_context_ptr_t _base_spe_context_crea
 	spe->base_private->mem_mmap_base = mapfileat( spe->base_private->fd_spe_dir, "mem", LS_SIZE);
 	if ( spe->base_private->mem_mmap_base == MAP_FAILED ) {
 		DEBUG_PRINTF ("ERROR: Could not map SPE memory. \n");
+		free_spe_context(spe);
 		errno = ENOMEM;
 		return NULL;
 	}
@@ -235,6 +278,7 @@ spe_context_ptr_t _base_spe_context_crea
 		     	spe->base_private->signal1_mmap_base == MAP_FAILED || 
 		     	spe->base_private->signal2_mmap_base == MAP_FAILED ) {
 				DEBUG_PRINTF ("ERROR: Could not map SPE PS memory. \n");
+				free_spe_context(spe);
 				errno = ENOMEM;
 				return NULL;
 			}
@@ -250,6 +294,7 @@ spe_context_ptr_t _base_spe_context_crea
 	if ( flags & SPE_CFG_SIGNOTIFY1_OR ) {
 		if (setsignotify(spe->base_private->fd_spe_dir, "signal1_type")) {
 			DEBUG_PRINTF ("ERROR: Could not open SPE signal1_type file.\n");
+			free_spe_context(spe);
 			errno = EFAULT;
 			return NULL;
 		}
@@ -258,6 +303,7 @@ spe_context_ptr_t _base_spe_context_crea
 	if ( flags & SPE_CFG_SIGNOTIFY2_OR ) {
 		if (setsignotify(spe->base_private->fd_spe_dir, "signal2_type")) {
 			DEBUG_PRINTF ("ERROR: Could not open SPE signal2_type file.\n");
+			free_spe_context(spe);
 			errno = EFAULT;
 			return NULL;
 		}
@@ -267,6 +313,17 @@ spe_context_ptr_t _base_spe_context_crea
 	return spe;
 }
 
+static int free_spe_gang_context(struct spe_gang_context *gctx)
+{
+	if (gctx->base_private->fd_gang_dir >= 0)
+		close(gctx->base_private->fd_gang_dir);
+
+	free(gctx->base_private);
+	free(gctx);
+
+	return 0;
+}
+
 spe_gang_context_ptr_t _base_spe_gang_context_create(unsigned int flags)
 {
 	char pathname[256];
@@ -283,6 +340,7 @@ spe_gang_context_ptr_t _base_spe_gang_co
 	pgctx = calloc (1, sizeof *pgctx);
 	if (!pgctx) {
 		DEBUG_PRINTF ("ERROR: Could not allocate spe context.\n");
+		free(gctx);
 		errno = ENOMEM;
 		return NULL;
 	}
@@ -295,6 +353,7 @@ spe_gang_context_ptr_t _base_spe_gang_co
 	gctx->base_private->fd_gang_dir = spu_create(pathname, 2, S_IRUSR | S_IWUSR | S_IXUSR);
 	if (gctx->base_private->fd_gang_dir < 0) {
 		DEBUG_PRINTF ("ERROR: Could not create Gang %s\n", pathname);
+		free_spe_gang_context(gctx);
 		errno=EFAULT;
 		return NULL;
 	}
@@ -306,47 +365,15 @@ spe_gang_context_ptr_t _base_spe_gang_co
 
 int _base_spe_context_destroy(spe_context_ptr_t spe)
 {
-	int i;
-	
-	if(spe->base_private->psmap_mmap_base != (void*)-1) {
-		munmap(spe->base_private->psmap_mmap_base, PSMAP_SIZE);
-	}
-	else {
-		if(spe->base_private->mfc_mmap_base != (void*)-1)
-			munmap(spe->base_private->mfc_mmap_base, MFC_SIZE);
-		if(spe->base_private->mssync_mmap_base != (void*)-1)
-			munmap(spe->base_private->mssync_mmap_base, MSS_SIZE);
-		if(spe->base_private->cntl_mmap_base != (void*)-1)
-			munmap(spe->base_private->cntl_mmap_base, CNTL_SIZE);
-		if(spe->base_private->signal1_mmap_base != (void*)-1)
-			munmap(spe->base_private->signal1_mmap_base,SIGNAL_SIZE);
-		if(spe->base_private->signal2_mmap_base != (void*)-1)
-			munmap(spe->base_private->signal2_mmap_base, SIGNAL_SIZE);
-	}
-
-	if(spe->base_private->mem_mmap_base != (void*)-1)
-		munmap(spe->base_private->mem_mmap_base, LS_SIZE);
-
-	for ( i=0;i<NUM_MBOX_FDS;i++){
-		close(spe->base_private->spe_fds_array[i]);
-		pthread_mutex_destroy(&spe->base_private->fd_lock[i]);
-	}
-	
-	close(spe->base_private->fd_spe_dir);
-	
-	free(spe->base_private);
-	free(spe);
+	int ret = free_spe_context(spe);
 
 	__spe_context_update_event();
 
-	return 0;
+	return ret;
 }
 
 int _base_spe_gang_context_destroy(spe_gang_context_ptr_t gctx)
 {
-	close(gctx->base_private->fd_gang_dir);
-	free(gctx->base_private);
-	free(gctx);
-	return 0;
+	return free_spe_gang_context(gctx);
 }
 



More information about the cbe-oss-dev mailing list