Author: rmacklem
Date: Mon Jan 10 21:35:10 2011
New Revision: 217242
URL: http://svn.freebsd.org/changeset/base/217242

Log:
  Fix a bug in the client side krpc where it was, sometimes
  erroneously, assumed that 4 bytes of data were in the first
  mbuf of a list by replacing the bcopy() with m_copydata().
  Also, replace the uses of m_pullup(), which can fail for
  reasons other than not enough data, with m_copydata().
  For the cases where it isn't known that there is enough
  data in the mbuf list, check first via m_len and m_length().
  This is believed to fix a problem reported by dpd at dpdtech.com
  and george+freebsd at m5p.com.
  
  Reviewed by:  jhb
  MFC after:    8 days

Modified:
  head/sys/rpc/clnt_dg.c
  head/sys/rpc/clnt_vc.c
  head/sys/rpc/svc_vc.c

Modified: head/sys/rpc/clnt_dg.c
==============================================================================
--- head/sys/rpc/clnt_dg.c      Mon Jan 10 21:09:38 2011        (r217241)
+++ head/sys/rpc/clnt_dg.c      Mon Jan 10 21:35:10 2011        (r217242)
@@ -1089,15 +1089,14 @@ clnt_dg_soupcall(struct socket *so, void
                /*
                 * The XID is in the first uint32_t of the reply.
                 */
-               if (m->m_len < sizeof(xid))
-                       m = m_pullup(m, sizeof(xid));
-               if (!m)
+               if (m->m_len < sizeof(xid) && m_length(m, NULL) < sizeof(xid))
                        /*
                         * Should never happen.
                         */
                        continue;
 
-               xid = ntohl(*mtod(m, uint32_t *));
+               m_copydata(m, 0, sizeof(xid), (char *)&xid);
+               xid = ntohl(xid);
 
                /*
                 * Attempt to match this reply with a pending request.

Modified: head/sys/rpc/clnt_vc.c
==============================================================================
--- head/sys/rpc/clnt_vc.c      Mon Jan 10 21:09:38 2011        (r217241)
+++ head/sys/rpc/clnt_vc.c      Mon Jan 10 21:35:10 2011        (r217242)
@@ -916,7 +916,7 @@ clnt_vc_soupcall(struct socket *so, void
                                mtx_unlock(&ct->ct_lock);
                                break;
                        }
-                       bcopy(mtod(m, uint32_t *), &header, sizeof(uint32_t));
+                       m_copydata(m, 0, sizeof(uint32_t), (char *)&header);
                        header = ntohl(header);
                        ct->ct_record = NULL;
                        ct->ct_record_resid = header & 0x7fffffff;
@@ -975,14 +975,11 @@ clnt_vc_soupcall(struct socket *so, void
                                 * The XID is in the first uint32_t of
                                 * the reply.
                                 */
-                               if (ct->ct_record->m_len < sizeof(xid))
-                                       ct->ct_record =
-                                               m_pullup(ct->ct_record,
-                                                   sizeof(xid));
-                               if (!ct->ct_record)
+                               if (ct->ct_record->m_len < sizeof(xid) &&
+                                   m_length(ct->ct_record, NULL) < sizeof(xid))
                                        break;
-                               bcopy(mtod(ct->ct_record, uint32_t *),
-                                   &xid, sizeof(uint32_t));
+                               m_copydata(ct->ct_record, 0, sizeof(xid),
+                                   (char *)&xid);
                                xid = ntohl(xid);
 
                                mtx_lock(&ct->ct_lock);

Modified: head/sys/rpc/svc_vc.c
==============================================================================
--- head/sys/rpc/svc_vc.c       Mon Jan 10 21:09:38 2011        (r217241)
+++ head/sys/rpc/svc_vc.c       Mon Jan 10 21:35:10 2011        (r217242)
@@ -559,11 +559,8 @@ svc_vc_recv(SVCXPRT *xprt, struct rpc_ms
                                }
                                if (n < sizeof(uint32_t))
                                        goto readmore;
-                               if (cd->mpending->m_len < sizeof(uint32_t))
-                                       cd->mpending = m_pullup(cd->mpending,
-                                           sizeof(uint32_t));
-                               memcpy(&header, mtod(cd->mpending, uint32_t *),
-                                   sizeof(header));
+                               m_copydata(cd->mpending, 0, sizeof(header),
+                                   (char *)&header);
                                header = ntohl(header);
                                cd->eor = (header & 0x80000000) != 0;
                                cd->resid = header & 0x7fffffff;
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to