summaryrefslogtreecommitdiffstats
path: root/sys/rpc
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2011-01-10 21:35:10 +0000
committerrmacklem <rmacklem@FreeBSD.org>2011-01-10 21:35:10 +0000
commit03248b7340e568f9556b9d6bbce82277acf79e4e (patch)
treea0ebc945c655ec2e171a66354671046c2184315f /sys/rpc
parentab709a4e92a5f80e9e1c6ae81c13f3f58b0fae6b (diff)
downloadFreeBSD-src-03248b7340e568f9556b9d6bbce82277acf79e4e.zip
FreeBSD-src-03248b7340e568f9556b9d6bbce82277acf79e4e.tar.gz
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
Diffstat (limited to 'sys/rpc')
-rw-r--r--sys/rpc/clnt_dg.c7
-rw-r--r--sys/rpc/clnt_vc.c13
-rw-r--r--sys/rpc/svc_vc.c7
3 files changed, 10 insertions, 17 deletions
diff --git a/sys/rpc/clnt_dg.c b/sys/rpc/clnt_dg.c
index a01f598..d35a6a9 100644
--- a/sys/rpc/clnt_dg.c
+++ b/sys/rpc/clnt_dg.c
@@ -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.
diff --git a/sys/rpc/clnt_vc.c b/sys/rpc/clnt_vc.c
index 9699a8d..9882407 100644
--- a/sys/rpc/clnt_vc.c
+++ b/sys/rpc/clnt_vc.c
@@ -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);
diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c
index 85d335f..999cad1 100644
--- a/sys/rpc/svc_vc.c
+++ b/sys/rpc/svc_vc.c
@@ -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;
OpenPOWER on IntegriCloud