[Openib-windows] [PATCH] Handle RMPP send payload < MAD buffer length

Fab Tillier ftillier at silverstorm.com
Mon Oct 3 16:12:05 PDT 2005


Folks,

I found a bug in sending MADs where the last segment of an RMPP send would try
to send a full payload's worth of data in the MAD, which could result in copying
data beyond the end of the source buffer and the corresponding BSOD.

Here's a patch that corrects this.  It does not clear the remaining bytes of the
MAD, as I wasn't sure it was needed.  Please take a look and confirm that what
I'm doing is sane, and I'll check it in.

Thanks,

- Fab

Signed-off-by: Fab Tillier (ftillier at silverstorm.com)

Index: core/al/al_mad.c
===================================================================
--- core/al/al_mad.c    (revision 100)
+++ core/al/al_mad.c    (working copy)
@@ -1681,6 +1681,7 @@
    al_mad_element_t    *p_al_element;
    ib_rmpp_mad_t       *p_rmpp_hdr;
    uint8_t             *p_rmpp_src, *p_rmpp_dst;
+   uintn_t             hdr_len, offset, max_len;
 
    CL_ENTER( AL_DBG_MAD_SVC, g_al_dbg_lvl );
    p_send_wr = &h_send->mad_wr.send_wr;
@@ -1702,28 +1703,27 @@
        p_rmpp_dst = (uint8_t*)(uintn_t)p_al_element->mad_ds.vaddr;
 #endif
        p_rmpp_src = (uint8_t* __ptr64)h_send->p_send_mad->p_mad_buf;
-       p_rmpp_hdr = (ib_rmpp_mad_t* __ptr64)h_send->p_send_mad->p_mad_buf;
+       p_rmpp_hdr = (ib_rmpp_mad_t*)p_rmpp_src;
 
        if( h_send->p_send_mad->p_mad_buf->mgmt_class == IB_MCLASS_SUBN_ADM )
-       {
-           /* Copy the header into the registered send buffer. */
-           cl_memcpy( p_rmpp_dst, p_rmpp_src, IB_SA_MAD_HDR_SIZE );
-           /* Copy this segment's payload into the registered send buffer. */
-           p_rmpp_dst = p_rmpp_dst + IB_SA_MAD_HDR_SIZE;
-           p_rmpp_src = p_rmpp_src + IB_SA_MAD_HDR_SIZE +
-               ( (cl_ntoh32( p_rmpp_hdr->seg_num ) - 1) * IB_SA_DATA_SIZE );
-           cl_memcpy( p_rmpp_dst, p_rmpp_src, IB_SA_DATA_SIZE );
-       } 
+           hdr_len = IB_SA_MAD_HDR_SIZE;
        else
-       {
-           /* Copy the header into the registered send buffer. */
-           cl_memcpy( p_rmpp_dst, p_rmpp_src, MAD_RMPP_HDR_SIZE );   
-           /* Copy this segment's payload into the registered send buffer. */
-           p_rmpp_dst = p_rmpp_dst + MAD_RMPP_HDR_SIZE;
-           p_rmpp_src = p_rmpp_src + MAD_RMPP_HDR_SIZE +
-               ( (cl_ntoh32( p_rmpp_hdr->seg_num ) - 1) * MAD_RMPP_DATA_SIZE );
-           cl_memcpy( p_rmpp_dst, p_rmpp_src, MAD_RMPP_DATA_SIZE );
-       }
+           hdr_len = MAD_RMPP_HDR_SIZE;
+
+       max_len = MAD_BLOCK_SIZE - hdr_len;
+
+       offset = hdr_len + (max_len * (cl_ntoh32( p_rmpp_hdr->seg_num ) - 1));
+
+       /* Copy the header into the registered send buffer. */
+       cl_memcpy( p_rmpp_dst, p_rmpp_src, hdr_len );
+
+       /* Copy this segment's payload into the registered send buffer. */
+       CL_ASSERT( h_send->p_send_mad->size != offset );
+       if( (h_send->p_send_mad->size - offset) < max_len )
+           max_len = h_send->p_send_mad->size - offset;
+
+       cl_memcpy(
+           p_rmpp_dst + hdr_len, p_rmpp_src + hdr_len + offset, max_len );
    }
 
    p_send_wr->num_ds = 1;




More information about the ofw mailing list