FreeBSD Bugzilla – Attachment 236266 Details for
Bug 251347
NFS hangs on client side when mounted from outside in Jail Tree (BROKEN NFS SERVER OR MIDDLEWARE)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to allow NFS inside a VNET jail
nfs_for_vnet_jails.patch (text/plain), 12.91 KB, created by
Devin Teske
on 2022-08-31 17:41:02 UTC
(
hide
)
Description:
Patch to allow NFS inside a VNET jail
Filename:
MIME Type:
Creator:
Devin Teske
Created:
2022-08-31 17:41:02 UTC
Size:
12.91 KB
patch
obsolete
>--- sys/fs/nfsclient/nfs_clvfsops.c.orig 2013-12-24 20:05:05.000000000 -0800 >+++ sys/fs/nfsclient/nfs_clvfsops.c 2013-12-24 21:52:17.000000000 -0800 >@@ -133,7 +133,7 @@ static struct vfsops nfs_vfsops = { > .vfs_unmount = nfs_unmount, > .vfs_sysctl = nfs_sysctl, > }; >-VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY); >+VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY | VFCF_JAIL); > > /* So that loader and kldload(2) can find us, wherever we are.. */ > MODULE_VERSION(nfs, 1); >--- sys/kern/kern_jail.c.orig 2013-12-24 20:05:00.000000000 -0800 >+++ sys/kern/kern_jail.c 2013-12-24 20:30:36.000000000 -0800 >@@ -225,7 +225,7 @@ static char *pr_allow_nonames[] = { > const size_t pr_allow_nonames_size = sizeof(pr_allow_nonames); > > #define JAIL_DEFAULT_ALLOW PR_ALLOW_SET_HOSTNAME >-#define JAIL_DEFAULT_ENFORCE_STATFS 2 >+#define JAIL_DEFAULT_ENFORCE_STATFS 1 > #define JAIL_DEFAULT_DEVFS_RSNUM 0 > static unsigned jail_default_allow = JAIL_DEFAULT_ALLOW; > static int jail_default_enforce_statfs = JAIL_DEFAULT_ENFORCE_STATFS; >--- sys/kern/vfs_mount.c.orig 2013-12-30 19:15:21.000000000 -0800 >+++ sys/kern/vfs_mount.c 2013-12-30 20:08:43.000000000 -0800 >@@ -1097,12 +1097,17 @@ vfs_domount( > if ((fsflags & MNT_UPDATE) == 0) { > pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); > strcpy(pathbuf, fspath); >- error = vn_path_to_global_path(td, vp, pathbuf, MNAMELEN); >- /* debug.disablefullpath == 1 results in ENODEV */ >- if (error == 0 || error == ENODEV) { >- error = vfs_domount_first(td, vfsp, pathbuf, vp, >- fsflags, optlist); >+ if (jailed(td->td_ucred) && >+ strcmp(td->td_ucred->cr_prison->pr_path, "/") != 0) { >+ if (strlen(td->td_ucred->cr_prison->pr_path) + >+ strlen(fspath) >= MNAMELEN) >+ return (ENAMETOOLONG); >+ strlcpy(pathbuf, td->td_ucred->cr_prison->pr_path, >+ sizeof(pathbuf)); >+ strlcat(pathbuf, fspath, sizeof(realfspath)); > } >+ error = vfs_domount_first(td, vfsp, pathbuf, vp, >+ fsflags, optlist); > free(pathbuf, M_TEMP); > } else > error = vfs_domount_update(td, vp, fsflags, optlist); >--- sys/net/rtsock.c.orig 2013-12-24 20:05:00.000000000 -0800 >+++ sys/net/rtsock.c 2013-12-24 21:04:41.000000000 -0800 >@@ -75,6 +75,7 @@ extern void sctp_addr_change(struct ifad > > #ifdef COMPAT_FREEBSD32 > #include <sys/mount.h> >+#include <sys/sysent.h> > #include <compat/freebsd32/freebsd32.h> > > struct if_data32 { >@@ -141,6 +142,42 @@ struct ifa_msghdrl32 { > int32_t ifam_metric; > struct if_data32 ifam_data; > }; >+ >+struct rt_metrics32 { >+ uint32_t rmx_locks; >+ uint32_t rmx_mtu; >+ uint32_t rmx_hopcount; >+ uint32_t rmx_expire; >+ uint32_t rmx_recvpipe; >+ uint32_t rmx_sendpipe; >+ uint32_t rmx_ssthresh; >+ uint32_t rmx_rtt; >+ uint32_t rmx_rttvar; >+ uint32_t rmx_pksent; >+ uint32_t rmx_weight; >+ uint32_t rmx_filler[3]; >+}; >+ >+struct rt_msghdr32 { >+ uint16_t rtm_msglen; >+ uint8_t rtm_version; >+ uint8_t rtm_type; >+ uint16_t rtm_index; >+ uint16_t rtm_hole1; >+ uint32_t rtm_flags; >+ uint32_t rtm_addrs; >+ uint32_t rtm_pid; >+ uint32_t rtm_seq; >+ uint32_t rtm_errno; >+ uint32_t rtm_fmask; >+ uint32_t rtm_inits; >+ struct rt_metrics32 rtm_rmx; >+}; >+ >+#define SA_SIZE32(sa) \ >+ ( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \ >+ sizeof(int32_t) : \ >+ 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(int32_t) - 1))) > #endif /* COMPAT_FREEBSD32 */ > > MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables"); >@@ -560,6 +597,138 @@ rtm_get_jailed(struct rt_addrinfo *info, > return (0); > } > >+#ifdef COMPAT_FREEBSD32 >+static void >+freebsd32_rt_metrics_in(struct rt_metrics32 *src, struct rt_metrics *dst) >+{ >+ >+ bzero(dst, sizeof(*dst)); >+ CP(*src, *dst, rmx_mtu); >+ CP(*src, *dst, rmx_expire); >+ CP(*src, *dst, rmx_pksent); >+ CP(*src, *dst, rmx_weight); >+} >+ >+static void >+freebsd32_rt_metrics_out(struct rt_metrics *src, struct rt_metrics32 *dst) >+{ >+ >+ bzero(dst, sizeof(*dst)); >+ CP(*src, *dst, rmx_mtu); >+ CP(*src, *dst, rmx_expire); >+ CP(*src, *dst, rmx_pksent); >+ CP(*src, *dst, rmx_weight); >+} >+ >+static void >+freebsd32_rt_msghdr_in(struct rt_msghdr32 *src, struct rt_msghdr *dst) >+{ >+ >+ bzero(dst, sizeof(*dst)); >+ /* CP(*src, *dst, rtm_msglen); */ /* updated separately */ >+ CP(*src, *dst, rtm_version); >+ CP(*src, *dst, rtm_type); >+ CP(*src, *dst, rtm_index); >+ CP(*src, *dst, rtm_flags); >+ CP(*src, *dst, rtm_addrs); >+ CP(*src, *dst, rtm_pid); >+ CP(*src, *dst, rtm_seq); >+ CP(*src, *dst, rtm_errno); >+ CP(*src, *dst, rtm_fmask); >+ CP(*src, *dst, rtm_inits); >+ freebsd32_rt_metrics_in(&src->rtm_rmx, &dst->rtm_rmx); >+} >+ >+static void >+freebsd32_rt_msghdr_out(struct rt_msghdr *src, struct rt_msghdr32 *dst) >+{ >+ >+ bzero(dst, sizeof(*dst)); >+ /* CP(*src, *dst, rtm_msglen); */ /* updated separately */ >+ CP(*src, *dst, rtm_version); >+ CP(*src, *dst, rtm_type); >+ CP(*src, *dst, rtm_index); >+ CP(*src, *dst, rtm_flags); >+ CP(*src, *dst, rtm_addrs); >+ CP(*src, *dst, rtm_pid); >+ CP(*src, *dst, rtm_seq); >+ CP(*src, *dst, rtm_errno); >+ CP(*src, *dst, rtm_fmask); >+ CP(*src, *dst, rtm_inits); >+ freebsd32_rt_metrics_out(&src->rtm_rmx, &dst->rtm_rmx); >+} >+ >+static int >+freebsd32_rt_mspace_len_in(caddr_t cp, caddr_t cplim, int *buflen) >+{ >+ struct sockaddr *sa; >+ int i; >+ >+ for (i = 0, *buflen = 0; i < RTAX_MAX && cp < cplim; i++) { >+ sa = (struct sockaddr *)cp; >+ >+ if (cp + sa->sa_len > cplim) >+ return (EINVAL); >+ cp += SA_SIZE32(sa); >+ *buflen += SA_SIZE(sa); >+ } >+ return (0); >+} >+ >+static int >+freebsd32_rt_mspace_len_out(caddr_t cp, caddr_t cplim, int *buflen) >+{ >+ struct sockaddr *sa; >+ int i; >+ >+ for (i = 0, *buflen = 0; i < RTAX_MAX && cp < cplim; i++) { >+ sa = (struct sockaddr *)cp; >+ >+ if (cp + sa->sa_len > cplim) >+ return (EINVAL); >+ cp += SA_SIZE(sa); >+ *buflen += SA_SIZE32(sa); >+ } >+ return (0); >+} >+ >+static int >+freebsd32_rt_mspace_in(caddr_t cp, caddr_t cp64, caddr_t cplim) >+{ >+ struct sockaddr *sa; >+ int i; >+ >+ for (i = 0; i < RTAX_MAX && cp < cplim; i++) { >+ sa = (struct sockaddr *)cp; >+ >+ if (cp + sa->sa_len > cplim) >+ return (EINVAL); >+ memcpy(cp64, cp, SA_SIZE32(sa)); >+ cp += SA_SIZE32(sa); >+ cp64 += SA_SIZE(sa); >+ } >+ return (0); >+} >+ >+static int >+freebsd32_rt_mspace_out(caddr_t cp, caddr_t cp32, caddr_t cplim) >+{ >+ struct sockaddr *sa; >+ int i; >+ >+ for (i = 0; i < RTAX_MAX && cp < cplim; i++) { >+ sa = (struct sockaddr *)cp; >+ >+ if (cp + sa->sa_len > cplim) >+ return (EINVAL); >+ memcpy(cp32, cp, SA_SIZE(sa)); >+ cp += SA_SIZE(sa); >+ cp32 += SA_SIZE32(sa); >+ } >+ return (0); >+} >+#endif >+ > /*ARGSUSED*/ > static int > route_output(struct mbuf *m, struct socket *so) >@@ -573,6 +742,14 @@ route_output(struct mbuf *m, struct sock > struct ifnet *ifp = NULL; > union sockaddr_union saun; > sa_family_t saf = AF_UNSPEC; >+ size_t rtmlen; >+#ifdef COMPAT_FREEBSD32 >+ struct rt_msghdr32 *rtm32 = NULL; >+ int len32 = 0, rt_mspace_len = 0, wrap32 = 0; >+ >+ if (SV_CURPROC_FLAG(SV_ILP32)) >+ wrap32 = 1; >+#endif > > #define senderr(e) { error = e; goto flush;} > if (m == NULL || ((m->m_len < sizeof(long)) && >@@ -581,17 +758,50 @@ route_output(struct mbuf *m, struct sock > if ((m->m_flags & M_PKTHDR) == 0) > panic("route_output"); > len = m->m_pkthdr.len; >- if (len < sizeof(*rtm) || >+ >+#ifdef COMPAT_FREEBSD32 >+ if (wrap32) { >+ rtmlen = sizeof(*rtm32); >+ len32 = len; >+ } else >+#endif >+ rtmlen = sizeof(*rtm); >+ >+ if (len < rtmlen || > len != mtod(m, struct rt_msghdr *)->rtm_msglen) { > info.rti_info[RTAX_DST] = NULL; > senderr(EINVAL); > } >- R_Malloc(rtm, struct rt_msghdr *, len); >+ >+#ifdef COMPAT_FREEBSD32 >+ if (wrap32) { >+ R_Malloc(rtm32, struct rt_msghdr32 *, len32); >+ if (rtm32 == NULL) { >+ info.rti_info[RTAX_DST] = NULL; >+ senderr(ENOBUFS); >+ } >+ m_copydata(m, 0, len32, (caddr_t)rtm32); >+ freebsd32_rt_mspace_len_in((caddr_t)(rtm32 + 1), len32 + (caddr_t)rtm32, &rt_mspace_len); >+ /* fixup len to alloc rtm of native size */ >+ len = rt_mspace_len + sizeof(*rtm); >+ } >+#endif >+ R_Zalloc(rtm, struct rt_msghdr *, len); > if (rtm == NULL) { > info.rti_info[RTAX_DST] = NULL; > senderr(ENOBUFS); > } >- m_copydata(m, 0, len, (caddr_t)rtm); >+ >+#ifdef COMPAT_FREEBSD32 >+ if (wrap32) { >+ freebsd32_rt_msghdr_in(rtm32, rtm); >+ freebsd32_rt_mspace_in((caddr_t)(rtm32 + 1), >+ (caddr_t)(rtm + 1), (caddr_t)rtm32 + len32); >+ rtm->rtm_msglen = len; >+ } else >+#endif >+ m_copydata(m, 0, len, (caddr_t)rtm); >+ > if (rtm->rtm_version != RTM_VERSION) { > info.rti_info[RTAX_DST] = NULL; > senderr(EPROTONOSUPPORT); >@@ -603,6 +813,16 @@ route_output(struct mbuf *m, struct sock > info.rti_info[RTAX_DST] = NULL; > senderr(EINVAL); > } >+/* >+ int i; uint16_t *j; >+ >+ for (i = 0; i * (int)sizeof(uint16_t) < len; i++) { >+ j = (uint16_t *)rtm; >+ if (i % 8 == 0) >+ printf("\n0x%04jx ", (uintmax_t)i*sizeof(uint16_t)); >+ printf("%04x ", bswap16(j[i])); >+ }; printf("\n"); >+*/ > info.rti_flags = rtm->rtm_flags; > if (info.rti_info[RTAX_DST] == NULL || > info.rti_info[RTAX_DST]->sa_family >= AF_MAX || >@@ -938,12 +1158,41 @@ flush: > rp = sotorawcb(so); > } > if (rtm) { >- m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm); >- if (m->m_pkthdr.len < rtm->rtm_msglen) { >- m_freem(m); >- m = NULL; >- } else if (m->m_pkthdr.len > rtm->rtm_msglen) >- m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len); >+#ifdef COMPAT_FREEBSD32 >+ if (wrap32) { >+ int rt_mspace_len32; >+ >+ freebsd32_rt_mspace_len_out((caddr_t)(rtm + 1), >+ len + (caddr_t)rtm, &rt_mspace_len32); >+ len32 = rt_mspace_len32 + sizeof(*rtm32); >+ if (len32 > rtm32->rtm_msglen) { >+ struct rt_msghdr32 *new_rtm32; >+ R_Malloc(new_rtm32, struct rt_msghdr32 *, len32); >+ if (new_rtm32 == NULL) >+ senderr(ENOBUFS); >+ bcopy(rtm32, new_rtm32, rtm32->rtm_msglen); >+ Free(rtm32); rtm32 = new_rtm32; >+ } >+ freebsd32_rt_msghdr_out(rtm, rtm32); >+ rtm32->rtm_msglen = len32; >+ freebsd32_rt_mspace_out((caddr_t)(rtm + 1), >+ (caddr_t)(rtm32 + 1), (caddr_t)rtm + len); >+ >+ m_copyback(m, 0, rtm32->rtm_msglen, (caddr_t)rtm32); >+ if (m->m_pkthdr.len < rtm32->rtm_msglen) { >+ m_freem(m); >+ m = NULL; >+ } else if (m->m_pkthdr.len > rtm32->rtm_msglen) >+ m_adj(m, rtm32->rtm_msglen - m->m_pkthdr.len); >+ } else { >+#endif >+ m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm); >+ if (m->m_pkthdr.len < rtm->rtm_msglen) { >+ m_freem(m); >+ m = NULL; >+ } else if (m->m_pkthdr.len > rtm->rtm_msglen) >+ m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len); >+ } > } > if (m) { > M_SETFIB(m, so->so_fibnum); >@@ -961,8 +1210,13 @@ flush: > rt_dispatch(m, saf); > } > /* info.rti_info[RTAX_DST] (used above) can point inside of rtm */ >- if (rtm) >+ if (rtm) { > Free(rtm); >+#ifdef COMPAT_FREEBSD32 >+ if (wrap32) >+ Free(rtm32); >+#endif >+ } > } > return (error); > #undef sa_equal >--- sys/netpfil/ipfw/ip_fw_nat.c.orig 2013-12-30 19:15:26.000000000 -0800 >+++ sys/netpfil/ipfw/ip_fw_nat.c 2013-12-30 23:57:24.000000000 -0800 >@@ -675,7 +675,7 @@ static moduledata_t ipfw_nat_mod = { > }; > > /* Define startup order. */ >-#define IPFW_NAT_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN >+#define IPFW_NAT_SI_SUB_FIREWALL (SI_SUB_PROTO_IFATTACHDOMAIN + 1) > #define IPFW_NAT_MODEVENT_ORDER (SI_ORDER_ANY - 255) > #define IPFW_NAT_MODULE_ORDER (IPFW_NAT_MODEVENT_ORDER + 1) > #define IPFW_NAT_VNET_ORDER (IPFW_NAT_MODEVENT_ORDER + 2) >--- sys/netsmb/smb_trantcp.c.orig 2013-12-24 20:04:50.000000000 -0800 >+++ sys/netsmb/smb_trantcp.c 2013-12-24 21:14:15.000000000 -0800 >@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD: stable/9/sys/netsmb/ > > #include <net/if.h> > #include <net/route.h> >+#include <net/vnet.h> > > #include <netinet/in.h> > #include <netinet/tcp.h> >@@ -79,13 +80,17 @@ static int > nb_setsockopt_int(struct socket *so, int level, int name, int val) > { > struct sockopt sopt; >+ int error; > > bzero(&sopt, sizeof(sopt)); > sopt.sopt_level = level; > sopt.sopt_name = name; > sopt.sopt_val = &val; > sopt.sopt_valsize = sizeof(val); >- return sosetopt(so, &sopt); >+ CURVNET_SET(so->so_vnet); >+ error = sosetopt(so, &sopt); >+ CURVNET_RESTORE(); >+ return error; > } > > static int >@@ -286,8 +291,10 @@ nbssn_recvhdr(struct nbpcb *nbp, int *le > auio.uio_offset = 0; > auio.uio_resid = sizeof(len); > auio.uio_td = td; >+ CURVNET_SET(so->so_vnet); > error = soreceive(so, (struct sockaddr **)NULL, &auio, > (struct mbuf **)NULL, (struct mbuf **)NULL, &flags); >+ CURVNET_RESTORE(); > if (error) > return error; > if (auio.uio_resid > 0) { >@@ -371,8 +378,10 @@ nbssn_recv(struct nbpcb *nbp, struct mbu > */ > do { > rcvflg = MSG_WAITALL; >+ CURVNET_SET(so->so_vnet); > error = soreceive(so, (struct sockaddr **)NULL, > &auio, &tm, (struct mbuf **)NULL, &rcvflg); >+ CURVNET_RESTORE(); > } while (error == EWOULDBLOCK || error == EINTR || > error == ERESTART); > if (error) >--- sys/nfsclient/nfs_vfsops.c.orig 2013-12-24 20:05:08.000000000 -0800 >+++ sys/nfsclient/nfs_vfsops.c 2013-12-24 21:55:31.000000000 -0800 >@@ -146,7 +146,7 @@ static struct vfsops nfs_vfsops = { > .vfs_unmount = nfs_unmount, > .vfs_sysctl = nfs_sysctl, > }; >-VFS_SET(nfs_vfsops, oldnfs, VFCF_NETWORK | VFCF_SBDRY); >+VFS_SET(nfs_vfsops, oldnfs, VFCF_NETWORK | VFCF_SBDRY | VFCF_JAIL); > > /* So that loader and kldload(2) can find us, wherever we are.. */ > MODULE_VERSION(oldnfs, 1);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 251347
:
219934
| 236266