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
This commit is contained in:
Rick Macklem 2011-01-10 21:35:10 +00:00
parent ea5bef4942
commit 2a1e0fb436
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=217242
3 changed files with 10 additions and 17 deletions

View File

@ -1089,15 +1089,14 @@ clnt_dg_soupcall(struct socket *so, void *arg, int waitflag)
/*
* 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.

View File

@ -916,7 +916,7 @@ clnt_vc_soupcall(struct socket *so, void *arg, int waitflag)
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 *arg, int waitflag)
* 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);

View File

@ -559,11 +559,8 @@ svc_vc_recv(SVCXPRT *xprt, struct rpc_msg *msg,
}
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;