/*
- * Copyright (c) 1998-2020 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2021 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
static int socketinit_done;
static struct zone *so_cache_zone;
-static lck_grp_t *so_cache_mtx_grp;
-static lck_attr_t *so_cache_mtx_attr;
-static lck_grp_attr_t *so_cache_mtx_grp_attr;
-static lck_mtx_t *so_cache_mtx;
+static LCK_GRP_DECLARE(so_cache_mtx_grp, "so_cache");
+static LCK_MTX_DECLARE(so_cache_mtx, &so_cache_mtx_grp);
#include <machine/limits.h>
PE_parse_boot_argn("socket_debug", &socket_debug,
sizeof(socket_debug));
- /*
- * allocate lock group attribute and group for socket cache mutex
- */
- so_cache_mtx_grp_attr = lck_grp_attr_alloc_init();
- so_cache_mtx_grp = lck_grp_alloc_init("so_cache",
- so_cache_mtx_grp_attr);
-
- /*
- * allocate the lock attribute for socket cache mutex
- */
- so_cache_mtx_attr = lck_attr_alloc_init();
-
- /* cached sockets mutex */
- so_cache_mtx = lck_mtx_alloc_init(so_cache_mtx_grp, so_cache_mtx_attr);
- if (so_cache_mtx == NULL) {
- panic("%s: unable to allocate so_cache_mtx\n", __func__);
- /* NOTREACHED */
- }
STAILQ_INIT(&so_cache_head);
so_cache_zone_element_size = (vm_size_t)(sizeof(struct socket) + 4
soextbkidlestat.so_xbkidle_rcvhiwat = SO_IDLE_BK_IDLE_RCV_HIWAT;
in_pcbinit();
- sflt_init();
socket_tclass_init();
#if MULTIPATH
mp_pcbinit();
caddr_t temp;
uintptr_t offset;
- lck_mtx_lock(so_cache_mtx);
+ lck_mtx_lock(&so_cache_mtx);
if (!STAILQ_EMPTY(&so_cache_head)) {
VERIFY(cached_sock_count > 0);
STAILQ_NEXT((*so), so_cache_ent) = NULL;
cached_sock_count--;
- lck_mtx_unlock(so_cache_mtx);
+ lck_mtx_unlock(&so_cache_mtx);
temp = (*so)->so_saved_pcb;
bzero((caddr_t)*so, sizeof(struct socket));
(*so)->so_saved_pcb = temp;
} else {
- lck_mtx_unlock(so_cache_mtx);
+ lck_mtx_unlock(&so_cache_mtx);
*so = zalloc_flags(so_cache_zone, how | Z_ZERO);
static void
cached_sock_free(struct socket *so)
{
- lck_mtx_lock(so_cache_mtx);
+ lck_mtx_lock(&so_cache_mtx);
so_cache_time = net_uptime();
if (++cached_sock_count > max_cached_sock_count) {
--cached_sock_count;
- lck_mtx_unlock(so_cache_mtx);
+ lck_mtx_unlock(&so_cache_mtx);
zfree(so_cache_zone, so);
} else {
if (so_cache_hw < cached_sock_count) {
STAILQ_INSERT_TAIL(&so_cache_head, so, so_cache_ent);
so->cache_timestamp = so_cache_time;
- lck_mtx_unlock(so_cache_mtx);
+ lck_mtx_unlock(&so_cache_mtx);
}
}
int n_freed = 0;
boolean_t rc = FALSE;
- lck_mtx_lock(so_cache_mtx);
+ lck_mtx_lock(&so_cache_mtx);
so_cache_timeouts++;
so_cache_time = net_uptime();
rc = TRUE;
}
- lck_mtx_unlock(so_cache_mtx);
+ lck_mtx_unlock(&so_cache_mtx);
return rc;
}
if (error) {
if (error == EJUSTRETURN) {
error = 0;
- clen = 0;
- control = NULL;
- top = NULL;
+ goto packet_consumed;
}
goto out_locked;
}
if (error) {
if (error == EJUSTRETURN) {
error = 0;
- clen = 0;
- control = NULL;
- top = NULL;
+ goto packet_consumed;
}
goto out_locked;
}
error = (*so->so_proto->pr_usrreqs->pru_send)
(so, sendflags, top, addr, control, p);
+packet_consumed:
if (dontroute) {
so->so_options &= ~SO_DONTROUTE;
}
return error;
}
+/*
+ * When peeking SCM_RIGHTS, the actual file descriptors are not yet created
+ * so clear the data portion in order not to leak the file pointers
+ */
+static void
+sopeek_scm_rights(struct mbuf *rights)
+{
+ struct cmsghdr *cm = mtod(rights, struct cmsghdr *);
+
+ if (cm->cmsg_type == SCM_RIGHTS) {
+ memset(cm + 1, 0, cm->cmsg_len - sizeof(*cm));
+ }
+}
+
/*
* Process one or more MT_CONTROL mbufs present before any data mbufs
* in the first mbuf chain on the socket buffer. If MSG_PEEK, we
error = ENOBUFS;
goto done;
}
+
+ sopeek_scm_rights(*controlp);
+
controlp = &(*controlp)->m_next;
}
m = m->m_next;
} else if (type == MT_OOBDATA) {
break;
}
+
+ if (m->m_type != MT_OOBDATA && m->m_type != MT_DATA &&
+ m->m_type != MT_HEADER) {
+ break;
+ }
/*
* Make sure to allways set MSG_OOB event when getting
* out of band data inline.
&ev.ev_data, sizeof(ev));
}
}
- if (socksa != NULL) {
- FREE(socksa, M_SONAME);
- }
- if (peersa != NULL) {
- FREE(peersa, M_SONAME);
- }
+ FREE(socksa, M_SONAME);
+ FREE(peersa, M_SONAME);
}