Skip to content
This repository has been archived by the owner on May 22, 2023. It is now read-only.

Commit

Permalink
xnu-3789.70.16
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Sep 28, 2017
1 parent 82975e5 commit 82dda5e
Show file tree
Hide file tree
Showing 19 changed files with 228 additions and 105 deletions.
3 changes: 3 additions & 0 deletions bsd/kern/kern_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,9 @@ __MALLOC_ZONE(
}
}

if (elem && (flags & M_ZERO))
bzero(elem, size);

return (elem);
}

Expand Down
2 changes: 1 addition & 1 deletion bsd/kern/posix_sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ sem_open(proc_t p, struct sem_open_args *uap, user_addr_t *retval)
* Preallocate everything we might need up front to avoid taking
* and dropping the lock, opening us up to race conditions.
*/
MALLOC_ZONE(pnbuf, caddr_t, MAXPATHLEN, M_NAMEI, M_WAITOK);
MALLOC_ZONE(pnbuf, caddr_t, MAXPATHLEN, M_NAMEI, M_WAITOK | M_ZERO);
if (pnbuf == NULL) {
error = ENOSPC;
goto bad;
Expand Down
4 changes: 2 additions & 2 deletions bsd/net/dlil.c
Original file line number Diff line number Diff line change
Expand Up @@ -8345,7 +8345,7 @@ sysctl_get_ports_used SYSCTL_HANDLER_ARGS
flags = name[2];

ifnet_head_lock_shared();
if (idx > if_index) {
if (!IF_INDEX_IN_RANGE(idx)) {
ifnet_head_done();
error = ENOENT;
goto done;
Expand Down Expand Up @@ -8432,7 +8432,7 @@ sysctl_get_kao_frames SYSCTL_HANDLER_ARGS
}

ifnet_head_lock_shared();
if (idx > if_index) {
if (!IF_INDEX_IN_RANGE(idx)) {
ifnet_head_done();
error = ENOENT;
goto done;
Expand Down
3 changes: 3 additions & 0 deletions bsd/net/if_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -1366,6 +1366,9 @@ typedef enum {
#define IF_LLADDR(_ifp) \
(LLADDR(SDL(((_ifp)->if_lladdr)->ifa_addr)))

#define IF_INDEX_IN_RANGE(_ind_) ((_ind_) > 0 && \
(unsigned int)(_ind_) <= (unsigned int)if_index)

__private_extern__ void ifnet_lock_assert(struct ifnet *, ifnet_lock_assert_t);
__private_extern__ void ifnet_lock_shared(struct ifnet *ifp);
__private_extern__ void ifnet_lock_exclusive(struct ifnet *ifp);
Expand Down
1 change: 1 addition & 0 deletions bsd/net/ndrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ ndrv_bind(struct socket *so, struct sockaddr *nam, __unused struct proc *p)
return(ENOMEM);
bcopy((caddr_t) sa, (caddr_t) np->nd_laddr, sizeof(struct sockaddr_ndrv));
dname = (char *) sa->snd_name;
np->nd_laddr->snd_len = sizeof(struct sockaddr_ndrv);
if (*dname == '\0')
return(EINVAL);
#if NDRV_DEBUG
Expand Down
3 changes: 3 additions & 0 deletions bsd/netinet/flow_divert.c
Original file line number Diff line number Diff line change
Expand Up @@ -3377,6 +3377,9 @@ flow_divert_token_set(struct socket *so, struct sockopt *sopt)
error = flow_divert_packet_get_tlv(token, 0, FLOW_DIVERT_TLV_KEY_UNIT, sizeof(key_unit), (void *)&key_unit, NULL);
if (!error) {
key_unit = ntohl(key_unit);
if (key_unit >= GROUP_COUNT_MAX) {
key_unit = 0;
}
} else if (error != ENOENT) {
FDLOG(LOG_ERR, &nil_pcb, "Failed to get the key unit from the token: %d", error);
goto done;
Expand Down
11 changes: 11 additions & 0 deletions bsd/netinet/igmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,17 @@ igmp_input(struct mbuf *m, int off)
* Validate length based on source count.
*/
nsrc = ntohs(igmpv3->igmp_numsrc);
/*
* The max vaue of nsrc is limited by the
* MTU of the network on which the datagram
* is received
*/
if (nsrc < 0 || nsrc > IGMP_V3_QUERY_MAX_SRCS) {
IGMPSTAT_INC(igps_rcv_tooshort);
OIGMPSTAT_INC(igps_rcv_tooshort);
m_freem(m);
return;
}
srclen = sizeof(struct in_addr) * nsrc;
if (igmplen < (IGMP_V3_QUERY_MINLEN + srclen)) {
IGMPSTAT_INC(igps_rcv_tooshort);
Expand Down
1 change: 1 addition & 0 deletions bsd/netinet/igmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ struct igmpv3 {
/*struct in_addr igmp_sources[1];*/ /* source addresses */
};
#define IGMP_V3_QUERY_MINLEN 12
#define IGMP_V3_QUERY_MAX_SRCS 366 /* From RFC 3376, section 4.1.8 */
#define IGMP_EXP(x) (((x) >> 4) & 0x07)
#define IGMP_MANT(x) ((x) & 0x0f)
#define IGMP_QRESV(x) (((x) >> 4) & 0x0f)
Expand Down
13 changes: 13 additions & 0 deletions bsd/netinet6/in6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,19 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
bcopy(&ifr->ifr_addr, &sin6, sizeof (sin6));
sa6 = &sin6;
break;
case SIOCGIFDSTADDR:
case SIOCSIFDSTADDR:
case SIOCGIFBRDADDR:
case SIOCSIFBRDADDR:
case SIOCGIFNETMASK:
case SIOCSIFNETMASK:
case SIOCGIFADDR:
case SIOCSIFADDR:
case SIOCAIFADDR:
case SIOCDIFADDR:
/* Do not handle these AF_INET commands in AF_INET6 path */
error = EINVAL;
goto done;
}

/*
Expand Down
2 changes: 2 additions & 0 deletions bsd/netinet6/in6_mcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -2470,6 +2470,8 @@ in6p_leave_group(struct inpcb *inp, struct sockopt *sopt)
ip6_sprintf(&gsa->sin6.sin6_addr)));
ifp = in6p_lookup_mcast_ifp(inp, &gsa->sin6);
} else {
if (!IF_INDEX_IN_RANGE(ifindex))
return (EADDRNOTAVAIL);
ifnet_head_lock_shared();
ifp = ifindex2ifnet[ifindex];
ifnet_head_done();
Expand Down
6 changes: 6 additions & 0 deletions bsd/netinet6/nd6_rtr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,12 @@ defrtrlist_ioctl(u_long cmd, caddr_t data)
dr0.ifp = dr_ifp;
ifnet_head_done();

if (ND_IFINFO(dr_ifp) == NULL ||
!ND_IFINFO(dr_ifp)->initialized) {
error = ENXIO;
break;
}

if (IN6_IS_SCOPE_EMBED(&dr0.rtaddr)) {
uint16_t *scope = &dr0.rtaddr.s6_addr16[1];

Expand Down
180 changes: 103 additions & 77 deletions bsd/netkey/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -9266,6 +9266,82 @@ bzero_keys(const struct sadb_msghdr *mh)
}
}

static int
key_validate_address_pair(struct sadb_address *src0,
struct sadb_address *dst0)
{
u_int plen = 0;

/* check upper layer protocol */
if (src0->sadb_address_proto != dst0->sadb_address_proto) {
ipseclog((LOG_DEBUG, "key_parse: upper layer protocol mismatched.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
return (EINVAL);
}

/* check family */
if (PFKEY_ADDR_SADDR(src0)->sa_family !=
PFKEY_ADDR_SADDR(dst0)->sa_family) {
ipseclog((LOG_DEBUG, "key_parse: address family mismatched.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
return (EINVAL);
}
if (PFKEY_ADDR_SADDR(src0)->sa_len !=
PFKEY_ADDR_SADDR(dst0)->sa_len) {
ipseclog((LOG_DEBUG,
"key_parse: address struct size mismatched.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
return (EINVAL);
}

switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
case AF_INET:
if (PFKEY_ADDR_SADDR(src0)->sa_len != sizeof(struct sockaddr_in)) {
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
return (EINVAL);
}
break;
case AF_INET6:
if (PFKEY_ADDR_SADDR(src0)->sa_len != sizeof(struct sockaddr_in6)) {
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
return (EINVAL);
}
break;
default:
ipseclog((LOG_DEBUG,
"key_parse: unsupported address family.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
return (EAFNOSUPPORT);
}

switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
case AF_INET:
plen = sizeof(struct in_addr) << 3;
break;
case AF_INET6:
plen = sizeof(struct in6_addr) << 3;
break;
default:
plen = 0; /*fool gcc*/
break;
}

/* check max prefix length */
if (src0->sadb_address_prefixlen > plen ||
dst0->sadb_address_prefixlen > plen) {
ipseclog((LOG_DEBUG,
"key_parse: illegal prefixlen.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
return (EINVAL);
}

/*
* prefixlen == 0 is valid because there can be a case when
* all addresses are matched.
*/
return (0);
}

/*
* parse sadb_msg buffer to process PFKEYv2,
* and create a data to response if needed.
Expand Down Expand Up @@ -9438,91 +9514,41 @@ key_parse(
goto senderror;
}

/* check field of upper layer protocol and address family */
if (mh.ext[SADB_EXT_ADDRESS_SRC] != NULL
&& mh.ext[SADB_EXT_ADDRESS_DST] != NULL) {
struct sadb_address *src0, *dst0;
u_int plen;

src0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_SRC]);
dst0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_DST]);

/* check upper layer protocol */
if (src0->sadb_address_proto != dst0->sadb_address_proto) {
ipseclog((LOG_DEBUG, "key_parse: upper layer protocol mismatched.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
error = EINVAL;
/* Validate address fields for matching families, lengths, etc. */
void *src0 = mh.ext[SADB_EXT_ADDRESS_SRC];
void *dst0 = mh.ext[SADB_EXT_ADDRESS_DST];
if (mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_START] != NULL &&
mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_END] != NULL) {

error = key_validate_address_pair((struct sadb_address *)(mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_START]),
(struct sadb_address *)(mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_END]));
if (error != 0) {
goto senderror;
}

/* check family */
if (PFKEY_ADDR_SADDR(src0)->sa_family !=
PFKEY_ADDR_SADDR(dst0)->sa_family) {
ipseclog((LOG_DEBUG, "key_parse: address family mismatched.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
error = EINVAL;
goto senderror;

if (src0 == NULL) {
src0 = mh.ext[SADB_X_EXT_ADDR_RANGE_SRC_START];
}
if (PFKEY_ADDR_SADDR(src0)->sa_len !=
PFKEY_ADDR_SADDR(dst0)->sa_len) {
ipseclog((LOG_DEBUG,
"key_parse: address struct size mismatched.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
error = EINVAL;
}
if (mh.ext[SADB_X_EXT_ADDR_RANGE_DST_START] != NULL &&
mh.ext[SADB_X_EXT_ADDR_RANGE_DST_END] != NULL) {

error = key_validate_address_pair((struct sadb_address *)(mh.ext[SADB_X_EXT_ADDR_RANGE_DST_START]),
(struct sadb_address *)(mh.ext[SADB_X_EXT_ADDR_RANGE_DST_END]));
if (error != 0) {
goto senderror;
}

switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
case AF_INET:
if (PFKEY_ADDR_SADDR(src0)->sa_len !=
sizeof(struct sockaddr_in)) {
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
error = EINVAL;
goto senderror;
}
break;
case AF_INET6:
if (PFKEY_ADDR_SADDR(src0)->sa_len !=
sizeof(struct sockaddr_in6)) {
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
error = EINVAL;
goto senderror;
}
break;
default:
ipseclog((LOG_DEBUG,
"key_parse: unsupported address family.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
error = EAFNOSUPPORT;
goto senderror;
}

switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
case AF_INET:
plen = sizeof(struct in_addr) << 3;
break;
case AF_INET6:
plen = sizeof(struct in6_addr) << 3;
break;
default:
plen = 0; /*fool gcc*/
break;

if (dst0 == NULL) {
dst0 = mh.ext[SADB_X_EXT_ADDR_RANGE_DST_START];
}

/* check max prefix length */
if (src0->sadb_address_prefixlen > plen ||
dst0->sadb_address_prefixlen > plen) {
ipseclog((LOG_DEBUG,
"key_parse: illegal prefixlen.\n"));
PFKEY_STAT_INCREMENT(pfkeystat.out_invaddr);
error = EINVAL;
}
if (src0 != NULL && dst0 != NULL) {
error = key_validate_address_pair((struct sadb_address *)(src0),
(struct sadb_address *)(dst0));
if (error != 0) {
goto senderror;
}

/*
* prefixlen == 0 is valid because there can be a case when
* all addresses are matched.
*/
}

if (msg->sadb_msg_type >= sizeof(key_typesw)/sizeof(key_typesw[0]) ||
Expand Down
5 changes: 4 additions & 1 deletion bsd/sys/attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,11 @@ typedef struct vol_attributes_attr {
/* CMNEXT attributes extend the common attributes, but in the forkattr field */
#define ATTR_CMNEXT_RELPATH 0x00000004
#define ATTR_CMNEXT_PRIVATESIZE 0x00000008
#ifdef PRIVATE
#define ATTR_CMNEXT_LINKID 0x00000010
#endif /* PRIVATE */

#define ATTR_CMNEXT_VALIDMASK 0x0000000c
#define ATTR_CMNEXT_VALIDMASK 0x0000001c
#define ATTR_CMNEXT_SETMASK 0x00000000

/* Deprecated fork attributes */
Expand Down
17 changes: 15 additions & 2 deletions bsd/vfs/vfs_attrlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ static struct getattrlist_attrtab getattrlist_file_tab[] = {
static struct getattrlist_attrtab getattrlist_common_extended_tab[] = {
{ATTR_CMNEXT_RELPATH, 0, sizeof(struct attrreference), KAUTH_VNODE_READ_ATTRIBUTES},
{ATTR_CMNEXT_PRIVATESIZE, VATTR_BIT(va_private_size), sizeof(off_t), KAUTH_VNODE_READ_ATTRIBUTES},
{ATTR_CMNEXT_LINKID, VATTR_BIT(va_fileid) | VATTR_BIT(va_linkid), sizeof(uint64_t), KAUTH_VNODE_READ_ATTRIBUTES},
{0, 0, 0, 0}
};

Expand Down Expand Up @@ -596,7 +597,7 @@ static struct getattrlist_attrtab getattrlistbulk_common_extended_tab[] = {
ATTR_CMN_DOCUMENT_ID | ATTR_CMN_GEN_COUNT | \
ATTR_CMN_DATA_PROTECT_FLAGS)

#define VFS_DFLT_ATT_CMN_EXT (ATTR_CMNEXT_PRIVATESIZE)
#define VFS_DFLT_ATTR_CMN_EXT (ATTR_CMNEXT_PRIVATESIZE | ATTR_CMNEXT_LINKID)

#define VFS_DFLT_ATTR_DIR (ATTR_DIR_LINKCOUNT | ATTR_DIR_MOUNTSTATUS)

Expand Down Expand Up @@ -1006,7 +1007,7 @@ getvolattrlist(vfs_context_t ctx, vnode_t vp, struct attrlist *alp,
attrp->validattr.volattr = VFS_DFLT_ATTR_VOL;
attrp->validattr.dirattr = VFS_DFLT_ATTR_DIR;
attrp->validattr.fileattr = VFS_DFLT_ATTR_FILE;
attrp->validattr.forkattr = 0;
attrp->validattr.forkattr = VFS_DFLT_ATTR_CMN_EXT;

attrp->nativeattr.commonattr = 0;
attrp->nativeattr.volattr = 0;
Expand Down Expand Up @@ -2183,6 +2184,18 @@ attr_pack_common_extended(struct vnode *vp, struct attrlist *alp,
}
}

if (alp->forkattr & ATTR_CMNEXT_LINKID) {
uint64_t linkid;

if (VATTR_IS_SUPPORTED(vap, va_linkid))
linkid = vap->va_linkid;
else
linkid = vap->va_fileid;

ATTR_PACK8((*abp), linkid);
abp->actual.forkattr |= ATTR_CMNEXT_LINKID;
}

return 0;
}

Expand Down
Loading

0 comments on commit 82dda5e

Please sign in to comment.