]> git.saurik.com Git - apple/xnu.git/commitdiff
xnu-3789.70.16.tar.gz macos-10126 v3789.70.16
authorApple <opensource@apple.com>
Tue, 22 Aug 2017 18:28:26 +0000 (18:28 +0000)
committerApple <opensource@apple.com>
Tue, 22 Aug 2017 18:28:26 +0000 (18:28 +0000)
19 files changed:
bsd/kern/kern_malloc.c
bsd/kern/posix_sem.c
bsd/net/dlil.c
bsd/net/if_var.h
bsd/net/ndrv.c
bsd/netinet/flow_divert.c
bsd/netinet/igmp.c
bsd/netinet/igmp.h
bsd/netinet6/in6.c
bsd/netinet6/in6_mcast.c
bsd/netinet6/nd6_rtr.c
bsd/netkey/key.c
bsd/sys/attr.h
bsd/vfs/vfs_attrlist.c
bsd/vm/dp_backing_file.c
config/MasterVersion
iokit/Kernel/IOUserClient.cpp
libkern/kxld/kxld_util.c
libkern/os/log_encode.h

index b75284fbd792e99c2e91ab5dbf648392104b29d3..d33382ec3c550f5c3a7254bf182e61b4479e219d 100644 (file)
@@ -720,6 +720,9 @@ __MALLOC_ZONE(
                }
        }
 
+       if (elem && (flags & M_ZERO))
+               bzero(elem, size);
+
        return (elem);
 }
 
index 54b92f059d6a65be2d31ae788cdd49a90fab3cb3..ca7ee4c6ae31af5be9528eca977e5ac74f1c466b 100644 (file)
@@ -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;
index 84fb0898f766a3b05b0b3db7204f1182f4dfae90..b38d4e5976ad51f55e0872e39af7e831544c28e2 100644 (file)
@@ -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;
@@ -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;
index f608157abc8fc827a5f0ec6a81d4b3d691fb5a03..bd3bdeba7f1d295108c96102e9a79305f2066313 100644 (file)
@@ -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);
index e171b48f37d099a549fd4ae203b552fd4ed9ee7a..87b6a77493821d3a76bf40834d582e2f40c1cfee 100644 (file)
@@ -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
index b531933cc506f0b5e7072c74d15da991cba29164..1e46e42c4167c7534eaf071a04b196381f50e7b4 100644 (file)
@@ -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;
index da146da81d3a5a3789ed3ddd94d0785781833001..f2cd0966e1fb1bd3009eabc427b3d67164cc09c9 100644 (file)
@@ -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);
index 28352317df0acb753837ede8f35a0cefc5327679..271b9855c7ba591eea1f84db196fbf7ac2283b98 100644 (file)
@@ -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)
index 976839dd160cc1cbfb96c0e2583e303460e8d95d..559815be5073daebcdef5643685ee782a5080eb1 100644 (file)
@@ -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;
        }
 
        /*
index dd27747f73bfd91af84f0fdbe0dce675b93fcf02..1fc7aca0342b8aef1c8da97cb2a5fe29c741b51f 100644 (file)
@@ -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();
index 0d6c9f0448c64954535cc30e0c9c4327843e0ad2..be938f59e82d9c91eed1bfcf12ef1b2aac8e9d7a 100644 (file)
@@ -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];
 
index 7e1a6061fa3d654d96896831f21f0feceac8b24c..a82188ec98f960cee1ba12a41241e6233a439588 100644 (file)
@@ -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.
@@ -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]) ||
index 7f20dd8f73ddad871ff7e73983d5f0f0082e06a2..3437f9cc78dbe8ce5118a1cc85d66b8ebd298755 100644 (file)
@@ -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 */
index e9f323164e4c64d3b7b91d804fe9046d7d462d0d..51eb4756f79a29488975803e89c623f2e5c6efb5 100644 (file)
@@ -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}
 };
 
@@ -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)
 
@@ -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;
@@ -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;
 }
 
index 2684c29dd21fc47377722cc8a6cc01a766e79b00..5548f11fda90c66d72d122129ce142350000531e 100644 (file)
@@ -61,7 +61,6 @@
 #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>
@@ -89,8 +88,6 @@ int
 macx_backing_store_recovery(
        __unused struct macx_backing_store_recovery_args *args)
 {
-       assert(FALSE);
-
        return ENOTSUP;
 }
 
@@ -105,8 +102,6 @@ int
 macx_backing_store_suspend(
        __unused struct macx_backing_store_suspend_args *args)
 {
-       assert(FALSE);
-
        return ENOTSUP;
 }
 
@@ -165,8 +160,6 @@ macx_triggers(
        if (flags & (SWAP_COMPACT_DISABLE | SWAP_COMPACT_ENABLE))
                return (macx_backing_store_compaction(flags));
 
-       assert(FALSE);
-
        return ENOTSUP;
 }
 
@@ -175,8 +168,6 @@ int
 macx_swapon(
        __unused struct macx_swapon_args *args)
 {
-       assert(FALSE);
-
        return ENOTSUP;
 }
 
@@ -190,8 +181,6 @@ int
 macx_swapoff(
        __unused struct macx_swapoff_args *args)
 {
-       assert(FALSE);
-
        return ENOTSUP;
 }
 
index 89b86ecd6d0767e8389e135031fe88aa7fed69f6..a02b1d1cb8f23836eb7a74fa1b958d99da255fa4 100644 (file)
@@ -1,4 +1,4 @@
-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.
index d568aaca2f2d269359effde1f8e42f09c69ad082..985e3b201286c38571cd1d2fdd55c97da161fa5d 100644 (file)
@@ -37,6 +37,7 @@
 #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>
@@ -1617,7 +1618,7 @@ IOMemoryMap * IOUserClient::mapClientMemory64(
 {
     IOReturn           err;
     IOOptionBits       options = 0;
-    IOMemoryDescriptor * memory;
+    IOMemoryDescriptor * memory = 0;
     IOMemoryMap *      map = 0;
 
     err = clientMemoryForType( (UInt32) type, &options, &memory );
@@ -3666,7 +3667,7 @@ kern_return_t is_io_connect_unmap_memory_from_task
 {
     IOReturn           err;
     IOOptionBits       options = 0;
-    IOMemoryDescriptor * memory;
+    IOMemoryDescriptor * memory = 0;
     IOMemoryMap *      map;
 
     CHECK( IOUserClient, connection, client );
@@ -3793,6 +3794,8 @@ kern_return_t is_io_connect_method_var_output
     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,
@@ -3888,6 +3891,9 @@ kern_return_t is_io_connect_method
     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,
@@ -3973,6 +3979,9 @@ kern_return_t is_io_connect_async_method
     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,
@@ -4862,6 +4871,9 @@ kern_return_t is_io_catalog_send_data(
         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;
@@ -4879,6 +4891,16 @@ kern_return_t is_io_catalog_send_data(
         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;
 
@@ -5008,9 +5030,10 @@ kern_return_t is_io_catalog_send_data(
     }
 
     if (obj) obj->release();
-    
+
     *result = kr;
     return( KERN_SUCCESS);
+#endif /* NO_KEXTD */
 }
 
 /* Routine io_catalog_terminate */
index dcf39a26b3c8d8b4dde4854ab96226aa679b3cd7..eee5dee7201600fda2cc4c5f886bdd4b8e5aa732 100644 (file)
@@ -62,7 +62,7 @@ static unsigned long bytes_freed = 0;
 #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
@@ -84,7 +84,18 @@ kxld_set_logging_callback(KXLDLoggingCallback logging_callback)
 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;
 }
 
@@ -97,14 +108,13 @@ kxld_log(KXLDLogSubsystem subsystem, KXLDLogLevel level,
     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;
@@ -112,7 +122,7 @@ kxld_log(KXLDLogSubsystem subsystem, KXLDLogLevel level,
             if (!alloc_buffer) return;
 
             snprintf(alloc_buffer, length, "kxld[%s]: %s",
-                name, in_format);
+                     s_callback_name, in_format);
             format = alloc_buffer;
         }
 
index 88839fbd79f10816f2f7a2a2ddcbce87545b4147..4f8afae5c394ac96cdbba32d905998ab8aee1b9b 100644 (file)
@@ -27,8 +27,9 @@
 #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
@@ -138,7 +139,7 @@ _os_log_parse_annotated(char *annotated, const char **visibility, const char **l
 
 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;
@@ -146,6 +147,21 @@ _os_log_encode_arg(const void *arg, uint16_t arg_len, os_log_value_type_t ctype,
 #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);