diff mbox series

osm_sa_mcmember_record.c: log before cleanup mgrp to avoid use-after-free

Message ID 20180807122742.9938-1-honli@redhat.com (mailing list archive)
State Not Applicable
Headers show
Series osm_sa_mcmember_record.c: log before cleanup mgrp to avoid use-after-free | expand

Commit Message

Honggang LI Aug. 7, 2018, 12:27 p.m. UTC
From: Honggang Li <honli@redhat.com>

Issue was found by Coverity.

Error: USE_AFTER_FREE (CWE-825): [#def11]
opensm-3.3.20/opensm/osm_sa_mcmember_record.c:1340: freed_arg: "osm_mgrp_cleanup" frees "p_mgrp".
opensm-3.3.20/opensm/osm_multicast.c:184:2: freed_arg: "free" frees parameter "mgrp".
opensm-3.3.20/opensm/osm_sa_mcmember_record.c:1342: deref_after_free: Dereferencing freed pointer "p_mgrp".
|# 1340|   			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
|# 1341|   		CL_PLOCK_RELEASE(sa->p_lock);
|# 1342|-> 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B12: "
|# 1343|   			"validate_more_comp_fields, validate_port_caps, "
|# 1344|   			"or JoinState = 0 failed for MGID: %s port 0x%016" PRIx64

Error: USE_AFTER_FREE (CWE-825): [#def12]
opensm-3.3.20/opensm/osm_sa_mcmember_record.c:1357: freed_arg: "osm_mgrp_cleanup" frees "p_mgrp".
opensm-3.3.20/opensm/osm_multicast.c:184:2: freed_arg: "free" frees parameter "mgrp".
opensm-3.3.20/opensm/osm_sa_mcmember_record.c:1360: deref_after_free: Dereferencing freed pointer "p_mgrp".
|# 1358|   		CL_PLOCK_RELEASE(sa->p_lock);
|# 1359|   		memset(gid_str, 0, sizeof(gid_str));
|# 1360|-> 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B14: "
|# 1361|   			"Cannot join port 0x%016" PRIx64 " to MGID %s - "
|# 1362|

Signed-off-by: Honggang Li <honli@redhat.com>
---
 opensm/osm_sa_mcmember_record.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

Comments

Hal Rosenstock Aug. 7, 2018, 1:43 p.m. UTC | #1
On 8/7/2018 8:27 AM, Honggang LI wrote:
> From: Honggang Li <honli@redhat.com>
> 
> Issue was found by Coverity.
> 
> Error: USE_AFTER_FREE (CWE-825): [#def11]
> opensm-3.3.20/opensm/osm_sa_mcmember_record.c:1340: freed_arg: "osm_mgrp_cleanup" frees "p_mgrp".
> opensm-3.3.20/opensm/osm_multicast.c:184:2: freed_arg: "free" frees parameter "mgrp".
> opensm-3.3.20/opensm/osm_sa_mcmember_record.c:1342: deref_after_free: Dereferencing freed pointer "p_mgrp".
> |# 1340|   			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
> |# 1341|   		CL_PLOCK_RELEASE(sa->p_lock);
> |# 1342|-> 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B12: "
> |# 1343|   			"validate_more_comp_fields, validate_port_caps, "
> |# 1344|   			"or JoinState = 0 failed for MGID: %s port 0x%016" PRIx64
> 
> Error: USE_AFTER_FREE (CWE-825): [#def12]
> opensm-3.3.20/opensm/osm_sa_mcmember_record.c:1357: freed_arg: "osm_mgrp_cleanup" frees "p_mgrp".
> opensm-3.3.20/opensm/osm_multicast.c:184:2: freed_arg: "free" frees parameter "mgrp".
> opensm-3.3.20/opensm/osm_sa_mcmember_record.c:1360: deref_after_free: Dereferencing freed pointer "p_mgrp".
> |# 1358|   		CL_PLOCK_RELEASE(sa->p_lock);
> |# 1359|   		memset(gid_str, 0, sizeof(gid_str));
> |# 1360|-> 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B14: "
> |# 1361|   			"Cannot join port 0x%016" PRIx64 " to MGID %s - "
> |# 1362|
> 
> Signed-off-by: Honggang Li <honli@redhat.com>
> ---
>  opensm/osm_sa_mcmember_record.c | 15 ++++++++-------
>  1 file changed, 8 insertions(+), 7 deletions(-)
> 
> diff --git a/opensm/osm_sa_mcmember_record.c b/opensm/osm_sa_mcmember_record.c
> index 9b94993e..20c3d006 100644
> --- a/opensm/osm_sa_mcmember_record.c
> +++ b/opensm/osm_sa_mcmember_record.c
> @@ -1345,10 +1345,7 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
>  	    || !validate_port_caps(sa->p_log, p_mgrp, p_physp)
>  	    || !(join_state != 0)) {
>  		char gid_str[INET6_ADDRSTRLEN];
> -		/* since we might have created the new group we need to cleanup */
> -		if (is_new_group)
> -			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
> -		CL_PLOCK_RELEASE(sa->p_lock);
> +		memset(gid_str, 0, sizeof(gid_str));
>  		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B12: "
>  			"validate_more_comp_fields, validate_port_caps, "
>  			"or JoinState = 0 failed for MGID: %s port 0x%016" PRIx64
> @@ -1356,6 +1353,10 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
>  			   inet_ntop(AF_INET6, p_mgrp->mcmember_rec.mgid.raw,
>  				     gid_str, sizeof gid_str),
>  			cl_ntoh64(portguid), p_port->p_node->print_desc);
> +		/* since we might have created the new group we need to cleanup */
> +		if (is_new_group)
> +			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
> +		CL_PLOCK_RELEASE(sa->p_lock);
>  		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
>  		goto Exit;
>  	}
> @@ -1363,9 +1364,6 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
>  	/* verify that the joining port is in the partition of the group */
>  	if (!osm_physp_has_pkey(sa->p_log, p_mgrp->mcmember_rec.pkey, p_physp)) {
>  		char gid_str[INET6_ADDRSTRLEN];
> -		if (is_new_group)
> -			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
> -		CL_PLOCK_RELEASE(sa->p_lock);
>  		memset(gid_str, 0, sizeof(gid_str));
>  		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B14: "
>  			"Cannot join port 0x%016" PRIx64 " to MGID %s - "
> @@ -1374,6 +1372,9 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
>  			inet_ntop(AF_INET6,
>  				  p_mgrp->mcmember_rec.mgid.raw,
>  				  gid_str, sizeof(gid_str)));
> +		if (is_new_group)
> +			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
> +		CL_PLOCK_RELEASE(sa->p_lock);
>  		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
>  		goto Exit;
>  	}
> 

Different approach to solve this will follow shortly. Would you try it
and make sure it passes Coverity ?

Thanks.

-- Hal
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox series

Patch

diff --git a/opensm/osm_sa_mcmember_record.c b/opensm/osm_sa_mcmember_record.c
index 9b94993e..20c3d006 100644
--- a/opensm/osm_sa_mcmember_record.c
+++ b/opensm/osm_sa_mcmember_record.c
@@ -1345,10 +1345,7 @@  static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 	    || !validate_port_caps(sa->p_log, p_mgrp, p_physp)
 	    || !(join_state != 0)) {
 		char gid_str[INET6_ADDRSTRLEN];
-		/* since we might have created the new group we need to cleanup */
-		if (is_new_group)
-			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
-		CL_PLOCK_RELEASE(sa->p_lock);
+		memset(gid_str, 0, sizeof(gid_str));
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B12: "
 			"validate_more_comp_fields, validate_port_caps, "
 			"or JoinState = 0 failed for MGID: %s port 0x%016" PRIx64
@@ -1356,6 +1353,10 @@  static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 			   inet_ntop(AF_INET6, p_mgrp->mcmember_rec.mgid.raw,
 				     gid_str, sizeof gid_str),
 			cl_ntoh64(portguid), p_port->p_node->print_desc);
+		/* since we might have created the new group we need to cleanup */
+		if (is_new_group)
+			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
+		CL_PLOCK_RELEASE(sa->p_lock);
 		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
 		goto Exit;
 	}
@@ -1363,9 +1364,6 @@  static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 	/* verify that the joining port is in the partition of the group */
 	if (!osm_physp_has_pkey(sa->p_log, p_mgrp->mcmember_rec.pkey, p_physp)) {
 		char gid_str[INET6_ADDRSTRLEN];
-		if (is_new_group)
-			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
-		CL_PLOCK_RELEASE(sa->p_lock);
 		memset(gid_str, 0, sizeof(gid_str));
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B14: "
 			"Cannot join port 0x%016" PRIx64 " to MGID %s - "
@@ -1374,6 +1372,9 @@  static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 			inet_ntop(AF_INET6,
 				  p_mgrp->mcmember_rec.mgid.raw,
 				  gid_str, sizeof(gid_str)));
+		if (is_new_group)
+			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
+		CL_PLOCK_RELEASE(sa->p_lock);
 		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
 		goto Exit;
 	}