summaryrefslogtreecommitdiffstats
path: root/sys/nfs
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2005-07-14 20:08:27 +0000
committerps <ps@FreeBSD.org>2005-07-14 20:08:27 +0000
commit3494397059c3dddd62077d8fe77cbcbbab71e4f9 (patch)
treecea0925fcb3fee95388e7d022a1a58a965f2f200 /sys/nfs
parentfc39b92b3793131311838fd90a4793aec7c942f7 (diff)
downloadFreeBSD-src-3494397059c3dddd62077d8fe77cbcbbab71e4f9.zip
FreeBSD-src-3494397059c3dddd62077d8fe77cbcbbab71e4f9.tar.gz
Fixes for NFS crashes on architectures that require strict alignment.
- Fix nfsm_disct() so that after pulling up data, the remaining data is aligned if necessary. - Fix nfs_clnt_tcp_soupcall() to bcopy() the rpc length out of the mbuf (instead of casting m_data to a uint32). Submitted by: Pyun YongHyeon Reviewed by: Mohan Srinivasan
Diffstat (limited to 'sys/nfs')
-rw-r--r--sys/nfs/nfs_common.c15
-rw-r--r--sys/nfs/nfs_common.h6
2 files changed, 18 insertions, 3 deletions
diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c
index c9270db..54c3f41 100644
--- a/sys/nfs/nfs_common.c
+++ b/sys/nfs/nfs_common.c
@@ -170,7 +170,7 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how)
{
struct mbuf *mp, *mp2;
int siz2, xfer;
- caddr_t ptr;
+ caddr_t ptr, npos = NULL;
void *ret;
mp = *mdp;
@@ -192,6 +192,7 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how)
MGET(mp2, how, MT_DATA);
if (mp2 == NULL)
return NULL;
+ mp2->m_len = siz;
mp2->m_next = mp->m_next;
mp->m_next = mp2;
mp->m_len -= left;
@@ -202,6 +203,7 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how)
siz2 = siz-left;
ptr += left;
mp2 = mp->m_next;
+ npos = mtod(mp2, caddr_t);
/* Loop around copying up the siz2 bytes */
while (siz2 > 0) {
if (mp2 == NULL)
@@ -214,12 +216,19 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how)
ptr += xfer;
siz2 -= xfer;
}
- if (siz2 > 0)
+ if (siz2 > 0) {
mp2 = mp2->m_next;
+ if (mp2 != NULL)
+ npos = mtod(mp2, caddr_t);
+ }
}
- mp->m_len = siz;
*mdp = mp2;
*dposp = mtod(mp2, caddr_t);
+ if (!nfsm_aligned(*dposp, u_int32_t)) {
+ bcopy(*dposp, npos, mp2->m_len);
+ mp2->m_data = npos;
+ *dposp = npos;
+ }
}
return ret;
}
diff --git a/sys/nfs/nfs_common.h b/sys/nfs/nfs_common.h
index 32ce4af..7c06130 100644
--- a/sys/nfs/nfs_common.h
+++ b/sys/nfs/nfs_common.h
@@ -127,4 +127,10 @@ do { \
nfsm_dcheck(t1, mrep); \
} while (0)
+#ifdef __NO_STRICT_ALIGNMENT
+#define nfsm_aligned(p, t) 1
+#else
+#define nfsm_aligned(p, t) ((((u_long)(p)) & (sizeof(t) - 1)) == 0)
+#endif
+
#endif
OpenPOWER on IntegriCloud