[openib-general] [PATCH] Opensm - bug in osm_sa_path_record with 0 records

Yael Kalka yael at mellanox.co.il
Thu Nov 3 05:07:42 PST 2005


Hi Hal,

During some testing of path record we found a bug in the code.
If the number of records return is zero, then there is clearing of 
non allocated memory.
I've added some changes to the __osm_pr_rcv_respond function, to match
other sa responses.
Attached is a patch to fix it.
Thanks,
Yael

Thanks,
Yael

Signed-off-by:  Yael Kalka <yael at mellanox.co.il>

Index: opensm/osm_sa_path_record.c
===================================================================
--- opensm/osm_sa_path_record.c	(revision 3955)
+++ opensm/osm_sa_path_record.c	(working copy)
@@ -1448,7 +1448,7 @@ __osm_pr_rcv_respond(
   osm_madw_t*              p_resp_madw;
   const ib_sa_mad_t*       p_sa_mad;
   ib_sa_mad_t*          p_resp_sa_mad;
-  size_t                num_rec, num_copied;
+  size_t                num_rec, num_copied, pre_trim_num_rec;
 #ifndef VENDOR_RMPP_SUPPORT
   size_t		trim_num_rec;
 #endif
@@ -1456,6 +1456,7 @@ __osm_pr_rcv_respond(
   ib_api_status_t          status;
   const ib_sa_mad_t*    p_rcvd_mad = osm_madw_get_sa_mad_ptr( p_madw );
   osm_pr_item_t*        p_pr_item;
+  uint32_t              i;
 
   OSM_LOG_ENTER( p_rcv->p_log, __osm_pr_rcv_respond );
 
@@ -1483,6 +1484,7 @@ __osm_pr_rcv_respond(
     goto Exit;
   }
 
+  pre_trim_num_rec = num_rec;
 #ifndef VENDOR_RMPP_SUPPORT
   trim_num_rec = (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_path_rec_t);
   if (trim_num_rec < num_rec)
@@ -1495,11 +1497,15 @@ __osm_pr_rcv_respond(
   }
 #endif
 
-  if( osm_log_is_active( p_rcv->p_log, OSM_LOG_DEBUG ) )
-  {
     osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
              "__osm_pr_rcv_respond: "
              "Generating response with %u records.\n", num_rec );
+
+  if ((p_rcvd_mad->method == IB_MAD_METHOD_GET) && (num_rec == 0))
+  {
+    osm_sa_send_error( p_rcv->p_resp, p_madw,
+                       IB_SA_MAD_STATUS_NO_RECORDS );
+    goto Exit;
   }
 
   /*
@@ -1514,6 +1520,16 @@ __osm_pr_rcv_respond(
     osm_log( p_rcv->p_log, OSM_LOG_ERROR,
              "__osm_pr_rcv_respond: ERR 1F14: "
              "Unable to allocate MAD.\n" );
+
+    for( i = 0; i < num_rec; i++ )
+    {
+      p_pr_item = (osm_pr_item_t*)cl_qlist_remove_head( p_list );
+      cl_qlock_pool_put( &p_rcv->pr_pool, &p_pr_item->pool_item );
+    }
+
+    osm_sa_send_error( p_rcv->p_resp, p_madw,
+                       IB_SA_MAD_STATUS_NO_RESOURCES );
+
     goto Exit;
   }
 
@@ -1528,6 +1544,8 @@ __osm_pr_rcv_respond(
   p_resp_sa_mad->attr_offset =
     ib_get_attr_offset( sizeof(ib_path_rec_t) );
 
+  p_resp_pr = (ib_path_rec_t*)ib_sa_mad_get_payload_ptr( p_resp_sa_mad );
+
 #ifndef VENDOR_RMPP_SUPPORT
   /* we support only one packet RMPP - so we will set the first and
      last flags for gettable */
@@ -1542,37 +1560,19 @@ __osm_pr_rcv_respond(
     p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
 #endif
 
-  p_resp_pr = (ib_path_rec_t*)ib_sa_mad_get_payload_ptr( p_resp_sa_mad );
-
-  if ( num_rec == 0 )
-  {
-    if (p_resp_sa_mad->method == IB_MAD_METHOD_GET_RESP)
-      p_resp_sa_mad->status = IB_SA_MAD_STATUS_NO_RECORDS;
-    cl_memclr( p_resp_pr, sizeof(*p_resp_pr) );
-  }
-  else
+  for ( i = 0; i < pre_trim_num_rec; i++ )
   {
     p_pr_item = (osm_pr_item_t*)cl_qlist_remove_head( p_list );
-
-    /* we need to track the number of copied items so we can
-     * stop the copy - but clear them all
-     */
-    num_copied = 0;
-
-    while( p_pr_item != (osm_pr_item_t*)cl_qlist_end( p_list ) )
-    {
-      /*  Copy the Path Records from the list into the MAD */
-      if (num_copied < num_rec)
-      {
+    /* copy only if not trimmed */
+    if (i < num_rec)
         *p_resp_pr = p_pr_item->path_rec;
-        num_copied++;
-      }
+
       cl_qlock_pool_put( &p_rcv->pr_pool, &p_pr_item->pool_item );
       p_resp_pr++;
-      p_pr_item = (osm_pr_item_t*)cl_qlist_remove_head( p_list );
-    }
   }
 
+  CL_ASSERT( cl_is_qlist_empty( p_list ) );
+
   status = osm_vendor_send( p_resp_madw->h_bind, p_resp_madw, FALSE );
 
   if( status != IB_SUCCESS )




More information about the general mailing list