--- 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 +#include #include 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 #include +#include #include #include @@ -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);