CVE-2015-5232: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') (CWE-362)
value: Race conditions in opa-fm before 10.4.0.0.196 and opa-ff before 10.4.0.0.197.
CWE description: The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.
CVSS v3 base score: 8.1
Published: 2017-06-07T20:29Z
Repository: https://github.com/01org/opa-fm
Language: C
Files changed: Esm/ib/include/hsm_config_srvr_data.h, Esm/ib/src/linux/fm_cmd/fm_cmd.c, Esm/ib/src/linux/fm_cmd/hsm_com_client.c, Esm/ib/src/linux/fm_cmd/hsm_com_client_api.c, Esm/ib/src/linux/fm_cmd/hsm_config_client.c, Esm/ib/src/linux/fm_cmd/hsm_config_client_data.h, Esm/ib/src/linux/rem_conf/hsm_config_data.h, Esm/ib/src/linux/startup/opafm.sh, Esm/ib/src/linux/startup/opafmctrl.sh
Commit date: 2015-09-18 11:47:10 -0400
Commit message: Fix scripts and code that use well-known tmp files.

Diff: diff --git a/Esm/ib/include/hsm_config_srvr_data.h b/Esm/ib/include/hsm_config_srvr_data.h
index 5675cec..9bdb156 100755
--- a/Esm/ib/include/hsm_config_srvr_data.h
+++ b/Esm/ib/include/hsm_config_srvr_data.h
@@ -30,14 +30,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef HSM_CONFIG_SRVR_DATA
 #define	HSM_CONFIG_SRVR_DATA
 
 #include "hsm_config_srvr_api.h"
 
-#define HSM_FM_SCK_PREFIX	"/tmp/"
+#define HSM_FM_SCK_PREFIX	"/opt/opafm/"
 #define HSM_FM_SCK_SM		"sm_"
 #define HSM_FM_SCK_PM		"pm_"
-#define HSM_FM_SCK_BM		"bm_"
 #define HSM_FM_SCK_FE		"fe_"
 
 typedef struct	_fm_config_conx_hdl{
 	unsigned				instance;
 	unsigned				conx_mask; // Mask to store which services are currently connected.
diff --git a/Esm/ib/src/linux/fm_cmd/fm_cmd.c b/Esm/ib/src/linux/fm_cmd/fm_cmd.c
index aa6cecd..7fcae69 100644
--- a/Esm/ib/src/linux/fm_cmd/fm_cmd.c
+++ b/Esm/ib/src/linux/fm_cmd/fm_cmd.c
@@ -39,17 +39,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
+#include <unistd.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <sys/stat.h>
 #include <signal.h>
 #include <time.h>
 #include "hsm_config_client_api.h"
 #include "hsm_config_client_data.h"
+#include "hsm_com_client_data.h"
 
 extern int   getopt(int, char *const *, const char *);
 
 typedef struct command_s{
 	char *name;
@@ -1043,11 +1045,11 @@ int sm_skip_attr_write(p_fm_config_conx_hdlt hdl, fm_mgr_type_t mgr, int argc, c
 	}
 	return 0;
 }
 
 int main(int argc, char *argv[]) {
-	p_fm_config_conx_hdlt	hdl;
+	p_fm_config_conx_hdlt	hdl = NULL;
 	int						instance = 0;
 	fm_mgr_config_errno_t	res;
 	char					*rem_addr = NULL;
 	char					*community = "public";
 	char            		Opts[256];
@@ -1085,28 +1087,48 @@ int main(int argc, char *argv[]) {
 	command = argv[optind++];
 	printf("Connecting to %s FM instance %d\n", (rem_addr==NULL) ? "LOCAL":rem_addr, instance);
 	if((res = fm_mgr_config_init(&hdl,instance, rem_addr, community)) != FM_CONF_OK)
 	{
 		fprintf(stderr, "Failed to initialize the client handle: %d\n", res);
-		goto die_clean;
+		goto cleanup;
 	}
 
 	if((res = fm_mgr_config_connect(hdl)) != FM_CONF_OK)
 	{
 		fprintf(stderr, "Failed to connect: (%d) %s\n",res,fm_mgr_get_error_str(res));
-		goto die_clean;
+		goto cleanup;
 	}
 
 	for(i=0;i<commandListLen;i++){
 		if(strcmp(command,commandList[i].name) == 0){
-			return commandList[i].cmdPtr(hdl, commandList[i].mgr, (argc - optind), &argv[optind]);
+			res = commandList[i].cmdPtr(hdl, commandList[i].mgr, (argc - optind), &argv[optind]);
+			goto cleanup;
 		}
 	}
 
 	fprintf(stderr, "Command (%s) is not valid\n",command);
 	usage(argv[0]);
 	res = -1;
 
-die_clean:
-	if (hdl) free(hdl);
+cleanup:
+	if (hdl)
+	{
+		if (hdl->sm_hdl)
+		{
+			if (hdl->sm_hdl->c_path[0])
+				unlink(hdl->sm_hdl->c_path);
+		}
+		if (hdl->pm_hdl)
+		{
+			if (hdl->pm_hdl->c_path[0])
+				unlink(hdl->pm_hdl->c_path);
+		}
+		if (hdl->fe_hdl)
+		{
+			if (hdl->fe_hdl->c_path[0])
+				unlink(hdl->fe_hdl->c_path);
+		}
+		free(hdl);
+	}
+
 	return res;
 }
diff --git a/Esm/ib/src/linux/fm_cmd/hsm_com_client.c b/Esm/ib/src/linux/fm_cmd/hsm_com_client.c
index 4efd68c..cb9877a 100755
--- a/Esm/ib/src/linux/fm_cmd/hsm_com_client.c
+++ b/Esm/ib/src/linux/fm_cmd/hsm_com_client.c
@@ -243,10 +243,11 @@ unix_sck_send_data(hsm_com_client_hdl_t *hdl, int timeout,
 hsm_com_errno_t
 unix_client_connect(hsm_com_client_hdl_t *hdl)
 {
 	int					fd, len;
 	struct sockaddr_un	unix_addr;
+	hsm_com_errno_t		res = HSM_COM_OK;
 
 	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 
 	{
 		return HSM_COM_ERROR;
 	}
@@ -255,33 +256,30 @@ unix_client_connect(hsm_com_client_hdl_t *hdl)
 
 	unix_addr.sun_family = AF_UNIX;
 	
 	if(strlen(hdl->c_path) >= sizeof(unix_addr.sun_path))
 	{
-		close(fd);
-		return HSM_COM_PATH_ERR;
+		res = HSM_COM_PATH_ERR;
+		goto cleanup;
 	}
 
 	snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path), "%s", hdl->c_path);
 
 	len = SUN_LEN(&unix_addr);
 
 	unlink(unix_addr.sun_path);
 
 	if(bind(fd, (struct sockaddr *)&unix_addr, len) < 0)
 	{
-		unlink(hdl->c_path);
-		close(fd);
-
-		return HSM_COM_BIND_ERR;
+		res = HSM_COM_BIND_ERR;
+		goto cleanup;
 	}
 
 	if(chmod(unix_addr.sun_path, S_IRWXU) < 0)
 	{
-		unlink(hdl->c_path);
-		close(fd);
-		return HSM_COM_CHMOD_ERR;
+		res = HSM_COM_CHMOD_ERR;
+		goto cleanup;
 	}
 
 	memset(&unix_addr,0,sizeof(unix_addr));
 
 	unix_addr.sun_family = AF_UNIX;
@@ -290,28 +288,29 @@ unix_client_connect(hsm_com_client_hdl_t *hdl)
 
 	len = SUN_LEN(&unix_addr);
 
 	if (connect(fd, (struct sockaddr *) &unix_addr, len) < 0) 
 	{
-		unlink(hdl->c_path);
-		close(fd);
-		return HSM_COM_CONX_ERR;
+		res = HSM_COM_CONX_ERR;
+		goto cleanup;
 	}
 
 	hdl->client_fd = fd;
 	hdl->client_state = HSM_COM_C_STATE_CT;
 
 	// Send connection data packet
 	if(unix_sck_send_conn(hdl, 2) != HSM_COM_OK)
 	{
 		hdl->client_state = HSM_COM_C_STATE_IN;
-		return HSM_COM_SEND_ERR;
+		res = HSM_COM_SEND_ERR;
 	}
 
+	return res;
 
-
-	return HSM_COM_OK;
+cleanup:
+	close(fd);
+	return res;
 
 }
 
 
 hsm_com_errno_t
diff --git a/Esm/ib/src/linux/fm_cmd/hsm_com_client_api.c b/Esm/ib/src/linux/fm_cmd/hsm_com_client_api.c
index 8917d0b..6878ccc 100755
--- a/Esm/ib/src/linux/fm_cmd/hsm_com_client_api.c
+++ b/Esm/ib/src/linux/fm_cmd/hsm_com_client_api.c
@@ -96,10 +96,15 @@ hcom_client_init
 
 
 	strcpy(hdl->s_path,server_path);
 	strcpy(hdl->c_path,client_path);
 
+	if (mkstemp(hdl->c_path) == -1)
+	{
+		res = HSM_COM_PATH_ERR;
+		goto cleanup;
+	}
 
 	hdl->client_state = HSM_COM_C_STATE_IN;
 
 	*p_hdl = hdl;
 
diff --git a/Esm/ib/src/linux/fm_cmd/hsm_config_client.c b/Esm/ib/src/linux/fm_cmd/hsm_config_client.c
index f2a42c8..d07b890 100755
--- a/Esm/ib/src/linux/fm_cmd/hsm_config_client.c
+++ b/Esm/ib/src/linux/fm_cmd/hsm_config_client.c
@@ -50,17 +50,14 @@ fm_mgr_config_mgr_connect
 {
 	char                    s_path[256];
 	char                    c_path[256];
 	char                    *mgr_prefix;
 	p_hsm_com_client_hdl_t  *mgr_hdl;
-	pid_t                   pid;
 
 	memset(s_path,0,sizeof(s_path));
 	memset(c_path,0,sizeof(c_path));
 
-	pid = getpid();
-
 	switch ( mgr )
 	{
 		case FM_MGR_SM:
 			mgr_prefix  = HSM_FM_SCK_SM;
 			mgr_hdl     = &hdl->sm_hdl;
@@ -78,12 +75,11 @@ fm_mgr_config_mgr_connect
 	}
 
 	// Fill in the paths for the server and client sockets.
 	sprintf(s_path,"%s%s%d",HSM_FM_SCK_PREFIX,mgr_prefix,hdl->instance);
 
-	sprintf(c_path,"%s%s%d_C_%lu",HSM_FM_SCK_PREFIX,mgr_prefix,
-			hdl->instance, (long unsigned)pid);
+	sprintf(c_path,"%s%s%d_C_XXXXXX",HSM_FM_SCK_PREFIX,mgr_prefix,hdl->instance);
 
 	if ( *mgr_hdl == NULL )
 	{
 		if ( hcom_client_init(mgr_hdl,s_path,c_path,32768) != HSM_COM_OK )
 		{
@@ -145,21 +141,11 @@ fm_mgr_config_init
 			res = FM_CONF_INIT_ERR;
 			goto cleanup;
 		}
 	}
 
-
-	return res;
-
-
-	cleanup:
-
-	if ( hdl ) {
-		free(hdl);
-		hdl = NULL;
-	}
-
+cleanup:
 	return res;
 }
 
 
 // connect
diff --git a/Esm/ib/src/linux/fm_cmd/hsm_config_client_data.h b/Esm/ib/src/linux/fm_cmd/hsm_config_client_data.h
index f43bd29..64479ce 100755
--- a/Esm/ib/src/linux/fm_cmd/hsm_config_client_data.h
+++ b/Esm/ib/src/linux/fm_cmd/hsm_config_client_data.h
@@ -30,11 +30,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef HSM_CONFIG_CLIENT_DATA
 #define	HSM_CONFIG_CLIENT_DATA
 
 #include "hsm_config_client_api.h"
 
-#define HSM_FM_SCK_PREFIX	"/tmp/"
+#define HSM_FM_SCK_PREFIX	"/opt/opafm/"
 #define HSM_FM_SCK_SM		"sm_"
 #define HSM_FM_SCK_PM		"pm_"
 #define HSM_FM_SCK_FE		"fe_"
 
 typedef struct	_fm_config_conx_hdl{
diff --git a/Esm/ib/src/linux/rem_conf/hsm_config_data.h b/Esm/ib/src/linux/rem_conf/hsm_config_data.h
index f91b5f1..040c815 100755
--- a/Esm/ib/src/linux/rem_conf/hsm_config_data.h
+++ b/Esm/ib/src/linux/rem_conf/hsm_config_data.h
@@ -31,14 +31,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define	HSM_CONFIG_DATA
 
 #include "hsm_config_api.h"
 #include "snmp_com_api.h"
 
-#define HSM_FM_SCK_PREFIX	"/tmp/"
+#define HSM_FM_SCK_PREFIX	"/opt/opafm/"
 #define HSM_FM_SCK_SM		"sm_"
 #define HSM_FM_SCK_PM		"pm_"
-#define HSM_FM_SCK_BM		"bm_"
 #define HSM_FM_SCK_FE		"fe_"
 
 typedef struct	_fm_config_conx_hdl{
 	unsigned				instance;
 	unsigned				conx_mask; // Mask to store which services are currently connected.
diff --git a/Esm/ib/src/linux/startup/opafm.sh b/Esm/ib/src/linux/startup/opafm.sh
index 016565e..2197c09 100644
--- a/Esm/ib/src/linux/startup/opafm.sh
+++ b/Esm/ib/src/linux/startup/opafm.sh
@@ -87,11 +87,11 @@ fi
 
 my_rc_status_all=0
 my_rc_exit()     { exit $my_rc_status_all; }
 my_rc_status()   { my_rc_status_all=$(($my_rc_status_all || $?)); }
 
-temp=/tmp/ifsfm$$
+temp=$(mktemp "/tmp/ifsfmXXXXX")
 
 trap "rm -rf $tempdir; exit 1" 1 2 3 9 1
 
 CONFIG_DIR=/etc/sysconfig
 CONFIG_FILE=$CONFIG_DIR/opafm.xml	# opafm.info can override
diff --git a/Esm/ib/src/linux/startup/opafmctrl.sh b/Esm/ib/src/linux/startup/opafmctrl.sh
index b45efa4..75f067e 100755
--- a/Esm/ib/src/linux/startup/opafmctrl.sh
+++ b/Esm/ib/src/linux/startup/opafmctrl.sh
@@ -85,11 +85,11 @@ running_manager()
 
 my_rc_status_all=0
 my_rc_exit()     { exit $my_rc_status_all; }
 my_rc_status()   { my_rc_status_all=$(($my_rc_status_all || $?)); }
 
-temp=/tmp/ifsfm$$
+temp=$(mktemp "/tmp/ifsfmXXXXX")
 invalid_config()
 {
 	local i
 
 	VALID_CONFIG=n

Vulnerable code: #define HSM_FM_SCK_PREFIX	"/tmp/"
#define HSM_FM_SCK_BM		"bm_"
	p_fm_config_conx_hdlt	hdl;
		goto die_clean;
		goto die_clean;
			return commandList[i].cmdPtr(hdl, commandList[i].mgr, (argc - optind), &argv[optind]);
die_clean:
	if (hdl) free(hdl);
		close(fd);
		return HSM_COM_PATH_ERR;
		unlink(hdl->c_path);
		close(fd);

		return HSM_COM_BIND_ERR;
		unlink(hdl->c_path);
		close(fd);
		return HSM_COM_CHMOD_ERR;
		unlink(hdl->c_path);
		close(fd);
		return HSM_COM_CONX_ERR;
		return HSM_COM_SEND_ERR;

	return HSM_COM_OK;
	pid_t                   pid;
	pid = getpid();

	sprintf(c_path,"%s%s%d_C_%lu",HSM_FM_SCK_PREFIX,mgr_prefix,
			hdl->instance, (long unsigned)pid);

	return res;


	cleanup:

	if ( hdl ) {
		free(hdl);
		hdl = NULL;
	}

#define HSM_FM_SCK_PREFIX	"/tmp/"
#define HSM_FM_SCK_PREFIX	"/tmp/"
#define HSM_FM_SCK_BM		"bm_"
temp=/tmp/ifsfm$$
temp=/tmp/ifsfm$$
Fixed code: #define HSM_FM_SCK_PREFIX	"/opt/opafm/"
#include <unistd.h>
#include "hsm_com_client_data.h"
	p_fm_config_conx_hdlt	hdl = NULL;
		goto cleanup;
		goto cleanup;
			res = commandList[i].cmdPtr(hdl, commandList[i].mgr, (argc - optind), &argv[optind]);
			goto cleanup;
cleanup:
	if (hdl)
	{
		if (hdl->sm_hdl)
		{
			if (hdl->sm_hdl->c_path[0])
				unlink(hdl->sm_hdl->c_path);
		}
		if (hdl->pm_hdl)
		{
			if (hdl->pm_hdl->c_path[0])
				unlink(hdl->pm_hdl->c_path);
		}
		if (hdl->fe_hdl)
		{
			if (hdl->fe_hdl->c_path[0])
				unlink(hdl->fe_hdl->c_path);
		}
		free(hdl);
	}

	hsm_com_errno_t		res = HSM_COM_OK;
		res = HSM_COM_PATH_ERR;
		goto cleanup;
		res = HSM_COM_BIND_ERR;
		goto cleanup;
		res = HSM_COM_CHMOD_ERR;
		goto cleanup;
		res = HSM_COM_CONX_ERR;
		goto cleanup;
		res = HSM_COM_SEND_ERR;
	return res;
cleanup:
	close(fd);
	return res;
	if (mkstemp(hdl->c_path) == -1)
	{
		res = HSM_COM_PATH_ERR;
		goto cleanup;
	}
	sprintf(c_path,"%s%s%d_C_XXXXXX",HSM_FM_SCK_PREFIX,mgr_prefix,hdl->instance);
cleanup:
#define HSM_FM_SCK_PREFIX	"/opt/opafm/"
#define HSM_FM_SCK_PREFIX	"/opt/opafm/"
temp=$(mktemp "/tmp/ifsfmXXXXX")
temp=$(mktemp "/tmp/ifsfmXXXXX")