}
}
+ if (elem && (flags & M_ZERO))
+ bzero(elem, size);
+
return (elem);
}
* 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;
flags = name[2];
ifnet_head_lock_shared();
- if (idx > if_index) {
+ if (!IF_INDEX_IN_RANGE(idx)) {
ifnet_head_done();
error = ENOENT;
goto done;
}
ifnet_head_lock_shared();
- if (idx > if_index) {
+ if (!IF_INDEX_IN_RANGE(idx)) {
ifnet_head_done();
error = ENOENT;
goto done;
#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);
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
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;
* 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);
/*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)
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;
}
/*
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();
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];
}
}
+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.
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]) ||
/* 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 */
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}
};
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)
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;
}
}
+ 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;
}
#include <kern/task.h>
#include <kern/zalloc.h>
#include <kern/kalloc.h>
-#include <kern/assert.h>
#include <kern/policy_internal.h>
#include <libkern/libkern.h>
macx_backing_store_recovery(
__unused struct macx_backing_store_recovery_args *args)
{
- assert(FALSE);
-
return ENOTSUP;
}
macx_backing_store_suspend(
__unused struct macx_backing_store_suspend_args *args)
{
- assert(FALSE);
-
return ENOTSUP;
}
if (flags & (SWAP_COMPACT_DISABLE | SWAP_COMPACT_ENABLE))
return (macx_backing_store_compaction(flags));
- assert(FALSE);
-
return ENOTSUP;
}
macx_swapon(
__unused struct macx_swapon_args *args)
{
- assert(FALSE);
-
return ENOTSUP;
}
macx_swapoff(
__unused struct macx_swapoff_args *args)
{
- assert(FALSE);
-
return ENOTSUP;
}
-16.6.0
+16.7.0
# The first line of this file contains the master version number for the kernel.
# All other instances of the kernel version in xnu are derived from this file.
#include <IOKit/IOMemoryDescriptor.h>
#include <IOKit/IOBufferMemoryDescriptor.h>
#include <IOKit/IOLib.h>
+#include <IOKit/IOBSD.h>
#include <IOKit/IOStatisticsPrivate.h>
#include <IOKit/IOTimeStamp.h>
#include <IOKit/system.h>
{
IOReturn err;
IOOptionBits options = 0;
- IOMemoryDescriptor * memory;
+ IOMemoryDescriptor * memory = 0;
IOMemoryMap * map = 0;
err = clientMemoryForType( (UInt32) type, &options, &memory );
{
IOReturn err;
IOOptionBits options = 0;
- IOMemoryDescriptor * memory;
+ IOMemoryDescriptor * memory = 0;
IOMemoryMap * map;
CHECK( IOUserClient, connection, client );
args.structureInput = inband_input;
args.structureInputSize = inband_inputCnt;
+ if (ool_input && (ool_input_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError);
+
if (ool_input)
inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size,
kIODirectionOut | kIOMemoryMapCopyOnWrite,
args.structureInput = inband_input;
args.structureInputSize = inband_inputCnt;
+ if (ool_input && (ool_input_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError);
+ if (ool_output && (*ool_output_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError);
+
if (ool_input)
inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size,
kIODirectionOut | kIOMemoryMapCopyOnWrite,
args.structureInput = inband_input;
args.structureInputSize = inband_inputCnt;
+ if (ool_input && (ool_input_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError);
+ if (ool_output && (*ool_output_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError);
+
if (ool_input)
inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size,
kIODirectionOut | kIOMemoryMapCopyOnWrite,
mach_msg_type_number_t inDataCount,
kern_return_t * result)
{
+#if NO_KEXTD
+ return kIOReturnNotPrivileged;
+#else /* NO_KEXTD */
OSObject * obj = 0;
vm_offset_t data;
kern_return_t kr = kIOReturnError;
return kIOReturnBadArgument;
}
+ if (!IOTaskHasEntitlement(current_task(), "com.apple.rootless.kext-management"))
+ {
+ OSString * taskName = IOCopyLogNameForPID(proc_selfpid());
+ IOLog("IOCatalogueSendData(%s): Not entitled\n", taskName ? taskName->getCStringNoCopy() : "");
+ OSSafeReleaseNULL(taskName);
+ // For now, fake success to not break applications relying on this function succeeding.
+ // See <rdar://problem/32554970> for more details.
+ return kIOReturnSuccess;
+ }
+
if (inData) {
vm_map_offset_t map_data;
}
if (obj) obj->release();
-
+
*result = kr;
return( KERN_SUCCESS);
+#endif /* NO_KEXTD */
}
/* Routine io_catalog_terminate */
#endif
static KXLDLoggingCallback s_logging_callback = NULL;
-static const char *s_callback_name = NULL;
+static char s_callback_name[64] = "internal";
static void *s_callback_data = NULL;
#if !KERNEL
void
kxld_set_logging_callback_data(const char *name, void *user_data)
{
- s_callback_name = name;
+ if (name) {
+ (void)strlcpy(s_callback_name, name, sizeof(s_callback_name));
+ /* disallow format strings in the kxld logging callback name */
+ for (size_t i = 0; i < sizeof(s_callback_name); i++) {
+ if (s_callback_name[i] == '%') {
+ s_callback_name[i] = '.';
+ }
+ }
+ } else {
+ (void)strlcpy(s_callback_name, "internal", sizeof(s_callback_name));
+ }
+
s_callback_data = user_data;
}
char stack_buffer[256];
char *alloc_buffer = NULL;
char *format = stack_buffer;
- const char *name = (s_callback_name) ? s_callback_name : "internal";
u_int length = 0;
va_list ap;
if (s_logging_callback) {
length = snprintf(stack_buffer, sizeof(stack_buffer), "kxld[%s]: %s",
- name, in_format);
+ s_callback_name, in_format);
if (length >= sizeof(stack_buffer)) {
length += 1;
if (!alloc_buffer) return;
snprintf(alloc_buffer, length, "kxld[%s]: %s",
- name, in_format);
+ s_callback_name, in_format);
format = alloc_buffer;
}
#include "log_encode_types.h"
#include <sys/param.h>
-#if KERNEL
+#ifdef KERNEL
#define isdigit(ch) (((ch) >= '0') && ((ch) <= '9'))
+extern boolean_t doprnt_hide_pointers;
#endif
static bool
OS_ALWAYS_INLINE
static inline bool
-_os_log_encode_arg(const void *arg, uint16_t arg_len, os_log_value_type_t ctype, bool is_private, os_log_buffer_context_t context)
+_os_log_encode_arg(void *arg, uint16_t arg_len, os_log_value_type_t ctype, bool is_private, os_log_buffer_context_t context)
{
os_log_buffer_value_t content = (os_log_buffer_value_t) &context->buffer->content[context->content_off];
size_t content_sz = sizeof(*content) + arg_len;
#ifndef KERNEL
bool obj_private = true;
#endif
+
+#ifdef KERNEL
+ /* scrub kernel pointers */
+ if (doprnt_hide_pointers &&
+ ctype == OS_LOG_BUFFER_VALUE_TYPE_SCALAR &&
+ arg_len >= sizeof(void *)) {
+ unsigned long long value = 0;
+ memcpy(&value, arg, arg_len);
+
+ if (value >= VM_MIN_KERNEL_AND_KEXT_ADDRESS && value <= VM_MAX_KERNEL_ADDRESS) {
+ is_private = true;
+ bzero(arg, arg_len);
+ }
+ }
+#endif
content->type = ctype;
content->flags = (is_private ? OS_LOG_CONTENT_FLAG_PRIVATE : 0);