]> git.saurik.com Git - apple/xnu.git/commitdiff
xnu-4570.41.2.tar.gz macos-10133 v4570.41.2
authorApple <opensource@apple.com>
Sun, 4 Feb 2018 14:01:56 +0000 (14:01 +0000)
committerApple <opensource@apple.com>
Sun, 4 Feb 2018 14:01:56 +0000 (14:01 +0000)
52 files changed:
bsd/kern/kern_credential.c
bsd/kern/kern_cs.c
bsd/kern/kern_exec.c
bsd/kern/kern_exit.c
bsd/kern/kern_mman.c
bsd/kern/kern_ntptime.c
bsd/kern/kern_persona.c
bsd/kern/kern_proc.c
bsd/kern/kern_resource.c
bsd/kern/kern_sig.c
bsd/kern/mach_loader.c
bsd/kern/policy_check.c
bsd/kern/sys_coalition.c
bsd/kern/sys_persona.c
bsd/kern/uipc_socket.c
bsd/kern/uipc_syscalls.c
bsd/net/if.c
bsd/net/if_llreach.c
bsd/net/necp_client.c
bsd/net/pf_ioctl.c
bsd/net/rtsock.c
bsd/netinet/in_mcast.c
bsd/netinet/in_tclass.c
bsd/netinet/ip_fw2.c
bsd/netinet/mptcp_usrreq.c
bsd/netinet/tcp_usrreq.c
bsd/netinet/udp_usrreq.c
bsd/netinet6/in6_mcast.c
bsd/nfs/nfs_subs.c
bsd/nfs/nfs_vfsops.c
bsd/sys/persona.h
bsd/sys/proc.h
bsd/vfs/vfs_cluster.c
bsd/vfs/vfs_subr.c
bsd/vfs/vfs_syscalls.c
config/MACFramework.exports
config/MASTER
config/MASTER.x86_64
config/MasterVersion
iokit/IOKit/IOUserClient.h
iokit/Kernel/IOUserClient.cpp
libsyscall/wrappers/spawn/posix_spawn.c
osfmk/kern/clock.c
osfmk/kern/clock_oldops.c
osfmk/kern/task.c
osfmk/kern/task.h
security/mac_base.c
security/mac_framework.h
security/mac_policy.h
security/mac_vfs.c
tools/tests/darwintests/socket_bind_35243417.c [new file with mode: 0644]
tools/tests/personas/persona_mgr.c

index bac6af26f313fc74b540a5880a92e6e3aa540fca..c433affeaacc05b86deb890846d7ec4a42c7e984 100644 (file)
@@ -593,7 +593,7 @@ identitysvc(__unused struct proc *p, struct identitysvc_args *uap, __unused int3
        int opcode = uap->opcode;
        user_addr_t message = uap->message;
        struct kauth_resolver_work *workp;
-       struct kauth_cache_sizes sz_arg;
+       struct kauth_cache_sizes sz_arg = {};
        int error;
        pid_t new_id;
 
@@ -5657,7 +5657,7 @@ sysctl_dump_creds( __unused struct sysctl_oid *oidp, __unused void *arg1, __unus
                return 0;
        }
 
-       MALLOC( cred_listp, debug_ucred *, req->oldlen, M_TEMP, M_WAITOK );
+       MALLOC( cred_listp, debug_ucred *, req->oldlen, M_TEMP, M_WAITOK | M_ZERO);
        if ( cred_listp == NULL ) {
                return (ENOMEM);
        }
@@ -5756,7 +5756,7 @@ sysctl_dump_cred_backtraces( __unused struct sysctl_oid *oidp, __unused void *ar
                return (ENOMEM);
        }
 
-       MALLOC( bt_bufp, cred_debug_buffer *, req->oldlen, M_TEMP, M_WAITOK );
+       MALLOC( bt_bufp, cred_debug_buffer *, req->oldlen, M_TEMP, M_WAITOK | M_ZERO);
        if ( bt_bufp == NULL ) {
                return (ENOMEM);
        }
index 7a3d22baf6907ed3d9a90f4a87ca2aa2aed17373..0bf85095552c25cdbd8aa315c00c10293cc03f1d 100644 (file)
@@ -325,7 +325,7 @@ cs_system_require_lv(void)
 /*
  * Function: csblob_get_base_offset
  *
- * Description: This function returns the base offset into the Mach-O binary
+ * Description: This function returns the base offset into the (possibly universal) binary
  *             for a given blob.
 */
 
@@ -413,11 +413,15 @@ csproc_get_blob(struct proc *p)
        if (NULL == p->p_textvp)
                return NULL;
 
+       if ((p->p_csflags & CS_SIGNED) == 0) {
+               return NULL;
+       }
+
        return ubc_cs_blob_get(p->p_textvp, -1, p->p_textoff);
 }
 
 /*
- * Function: csproc_get_blob
+ * Function: csvnode_get_blob
  *
  * Description: This function returns the cs_blob
  *             for the vnode vp
@@ -579,7 +583,9 @@ csproc_get_platform_binary(struct proc *p)
 int
 csproc_get_platform_path(struct proc *p)
 {
-       struct cs_blob *csblob = csproc_get_blob(p);
+       struct cs_blob *csblob;
+
+    csblob = csproc_get_blob(p);
 
        return (csblob == NULL) ? 0 : csblob->csb_platform_path;
 }
@@ -858,6 +864,10 @@ cs_entitlements_blob_get(proc_t p, void **out_start, size_t *out_length)
        *out_start = NULL;
        *out_length = 0;
 
+       if ((p->p_csflags & CS_SIGNED) == 0) {
+               return 0;
+       }
+
        if (NULL == p->p_textvp)
                return EINVAL;
 
@@ -878,6 +888,10 @@ cs_identity_get(proc_t p)
 {
        struct cs_blob *csblob;
 
+       if ((p->p_csflags & CS_SIGNED) == 0) {
+               return NULL;
+       }
+
        if (NULL == p->p_textvp)
                return NULL;
 
@@ -887,15 +901,13 @@ cs_identity_get(proc_t p)
        return csblob_get_identity(csblob);
 }
 
-
-/* Retrieve the codesign blob for a process.
- * Returns:
- *   EINVAL    no text vnode associated with the process
- *   0         no error occurred
+/*
+ * DO NOT USE THIS FUNCTION!
+ * Use the properly guarded csproc_get_blob instead.
  *
- * On success, out_start and out_length will point to the
- * cms blob if found; or will be set to NULL/zero
- * if there were no blob.
+ * This is currently here to allow detached signatures to work
+ * properly. The only user of this function is also checking
+ * for CS_VALID.
  */
 
 int
@@ -927,6 +939,10 @@ cs_get_cdhash(struct proc *p)
 {
        struct cs_blob *csblob;
 
+       if ((p->p_csflags & CS_SIGNED) == 0) {
+               return NULL;
+       }
+
        if (NULL == p->p_textvp)
                return NULL;
 
index 3ccb12119150b7bc2eab719167fca3253c62eda8..90334a7903019da29ef5749e02d163746274a0f7 100644 (file)
@@ -2082,7 +2082,7 @@ static int spawn_validate_persona(struct _posix_spawn_persona_info *px_persona)
                        }
                }
                if (px_persona->pspi_flags & POSIX_SPAWN_PERSONA_GROUPS) {
-                       int ngroups = 0;
+                       unsigned ngroups = 0;
                        gid_t groups[NGROUPS_MAX];
 
                        if (persona_get_groups(persona, &ngroups, groups,
@@ -2090,7 +2090,7 @@ static int spawn_validate_persona(struct _posix_spawn_persona_info *px_persona)
                                error = EINVAL;
                                goto out;
                        }
-                       if (ngroups != (int)px_persona->pspi_ngroups) {
+                       if (ngroups != px_persona->pspi_ngroups) {
                                error = EINVAL;
                                goto out;
                        }
@@ -5469,67 +5469,6 @@ static void cdhash_to_string(char str[CS_CDHASH_STRING_SIZE], uint8_t const * co
           str[CS_CDHASH_STRING_SIZE - 1] = 0;
 }
 
-/*
- * If the process is not signed or if it contains entitlements, we
- * need to communicate through the task_access_port to taskgated.
- *
- * taskgated will provide a detached code signature if present, and
- * will enforce any restrictions on entitlements.
- */
-
-static boolean_t
-taskgated_required(proc_t p, boolean_t *require_success)
-{
-       size_t length;
-       void *blob;
-       int error;
-
-       if (cs_debug > 2)
-               csvnode_print_debug(p->p_textvp);
-
-#if !CONFIG_EMBEDDED
-       const int can_skip_taskgated = csproc_get_platform_binary(p) && !csproc_get_platform_path(p);
-#else
-       const int can_skip_taskgated = csproc_get_platform_binary(p);
-#endif
-       if (can_skip_taskgated) {
-               if (cs_debug) printf("taskgated not required for: %s\n", p->p_name);
-               *require_success = FALSE;
-               return FALSE;
-       }
-
-       if ((p->p_csflags & CS_VALID) == 0) {
-               *require_success = FALSE;
-               return TRUE;
-       }
-
-       error = cs_entitlements_blob_get(p, &blob, &length);
-       if (error == 0 && blob != NULL) {
-#if !CONFIG_EMBEDDED
-               /*
-                * fatal on the desktop when entitlements are present,
-                * unless we started in single-user mode 
-                */
-               if ((boothowto & RB_SINGLE) == 0)
-                       *require_success = TRUE;
-               /*
-                * Allow initproc to run without causing taskgated to launch
-                */
-               if (p == initproc) {
-                       *require_success = FALSE;
-                       return FALSE;
-               }
-
-#endif
-               if (cs_debug) printf("taskgated required for: %s\n", p->p_name);
-
-               return TRUE;
-       }
-
-       *require_success = FALSE;
-       return FALSE;
-}
-
 /*
  * __EXEC_WAITING_ON_TASKGATED_CODE_SIGNATURE_UPCALL__
  * 
@@ -5550,7 +5489,7 @@ check_for_signature(proc_t p, struct image_params *imgp)
        kern_return_t kr = KERN_FAILURE;
        int error = EACCES;
        boolean_t unexpected_failure = FALSE;
-       unsigned char hash[CS_CDHASH_LEN];
+       struct cs_blob *csb;
        boolean_t require_success = FALSE;
        int spawn = (imgp->ip_flags & IMGPF_SPAWN);
        int vfexec = (imgp->ip_flags & IMGPF_VFORK_EXEC);
@@ -5592,12 +5531,17 @@ check_for_signature(proc_t p, struct image_params *imgp)
                goto done;
        }
 
-       /* check if callout to taskgated is needed */
-       if (!taskgated_required(p, &require_success)) {
+       /* If the code signature came through the image activation path, we skip the
+     * taskgated / externally attached path. */
+       if (imgp->ip_csflags & CS_SIGNED) {
                error = 0;
                goto done;
        }
 
+    /* The rest of the code is for signatures that either already have been externally
+     * attached (likely, but not necessarily by a previous run through the taskgated
+     * path), or that will now be attached by taskgated. */
+    
        kr = task_get_task_access_port(p->task, &port);
        if (KERN_SUCCESS != kr || !IPC_PORT_VALID(port)) {
                error = 0;
@@ -5642,14 +5586,42 @@ check_for_signature(proc_t p, struct image_params *imgp)
 
        /* Only do this if exec_resettextvp() did not fail */
        if (p->p_textvp != NULLVP) {
-               /*
-                * If there's a new code directory, mark this process
-                * as signed.
-                */
-               if (0 == ubc_cs_getcdhash(p->p_textvp, p->p_textoff, hash)) {
-                       proc_lock(p);
-                       p->p_csflags |= CS_VALID;
-                       proc_unlock(p);
+               csb = ubc_cs_blob_get(p->p_textvp, -1, p->p_textoff);
+
+               if (csb != NULL) {
+                       /* As the enforcement we can do here is very limited, we only allow things that
+                        * are the only reason why this code path still exists:
+                        * Adhoc signed non-platform binaries without special cs_flags and without any
+                        * entitlements (unrestricted ones still pass AMFI). */
+                       if (
+                /* Revalidate the blob if necessary through bumped generation count. */
+                (ubc_cs_generation_check(p->p_textvp) == 0 ||
+                 ubc_cs_blob_revalidate(p->p_textvp, csb, imgp, 0) == 0) &&
+                /* Only CS_ADHOC, no CS_KILL, CS_HARD etc. */
+                               (csb->csb_flags & CS_ALLOWED_MACHO) == CS_ADHOC &&
+                               /* If it has a CMS blob, it's not adhoc. The CS_ADHOC flag can lie. */
+                               csblob_find_blob_bytes((const uint8_t *)csb->csb_mem_kaddr, csb->csb_mem_size,
+                                                                          CSSLOT_SIGNATURESLOT,
+                                                                          CSMAGIC_BLOBWRAPPER) == NULL &&
+                               /* It could still be in a trust cache (unlikely with CS_ADHOC), or a magic path. */
+                               csb->csb_platform_binary == 0 &&
+                               /* No entitlements, not even unrestricted ones. */
+                csb->csb_entitlements_blob == NULL) {
+
+                               proc_lock(p);
+                               p->p_csflags |= CS_SIGNED | CS_VALID;
+                               proc_unlock(p);
+
+                       } else {
+                               uint8_t cdhash[CS_CDHASH_LEN];
+                               char cdhash_string[CS_CDHASH_STRING_SIZE];
+                               proc_getcdhash(p, cdhash);
+                               cdhash_to_string(cdhash_string, cdhash);
+                               printf("ignoring detached code signature on '%s' with cdhash '%s' "
+                                          "because it is invalid, or not a simple adhoc signature.\n", 
+                                          p->p_name, cdhash_string);
+                       }
+
                }
        }
 
index fdbee03d10c298ee814d5bd7eb2f9da12b7e4915..f5ee01dc12a39fd92f0e02dac42a7e894a18350e 100644 (file)
@@ -1791,14 +1791,14 @@ loop1:
                                        error = ENOMEM;
                                } else {
                                        if (IS_64BIT_PROCESS(q)) {
-                                               struct user64_rusage    my_rusage;
+                                               struct user64_rusage    my_rusage = {};
                                                munge_user64_rusage(&p->p_ru->ru, &my_rusage);
                                                error = copyout((caddr_t)&my_rusage,
                                                        uap->rusage,
                                                        sizeof (my_rusage));
                                        }
                                        else {
-                                               struct user32_rusage    my_rusage;
+                                               struct user32_rusage    my_rusage = {};
                                                munge_user32_rusage(&p->p_ru->ru, &my_rusage);
                                                error = copyout((caddr_t)&my_rusage,
                                                        uap->rusage,
index adb144567dbe2afe3242d67b95d84fda95369364..1c6979473b11b2027b02b29070b0e22672c67f1a 100644 (file)
@@ -1047,7 +1047,7 @@ mincore(__unused proc_t p, struct mincore_args *uap, __unused int32_t *retval)
        req_vec_size_pages = (end - addr) >> PAGE_SHIFT;
        cur_vec_size_pages = MIN(req_vec_size_pages, (int)(MAX_PAGE_RANGE_QUERY >> PAGE_SHIFT));
 
-       kernel_vec = (void*) _MALLOC(cur_vec_size_pages * sizeof(char), M_TEMP, M_WAITOK);
+       kernel_vec = (void*) _MALLOC(cur_vec_size_pages * sizeof(char), M_TEMP, M_WAITOK | M_ZERO);
 
        if (kernel_vec == NULL) {
                return (ENOMEM);
index ccbfece8da24a25cfcf241ae16d6d07d2d373f1d..915f4c4b78fdce66ae4784354118f0bff6d12331 100644 (file)
@@ -267,7 +267,7 @@ ntp_gettime(struct proc *p, struct ntp_gettime_args *uap, __unused int32_t *retv
        NTP_UNLOCK(enable);
 
        if (IS_64BIT_PROCESS(p)) {
-               struct user64_ntptimeval user_ntv;
+               struct user64_ntptimeval user_ntv = {};
                user_ntv.time.tv_sec = ntv.time.tv_sec;
                user_ntv.time.tv_nsec = ntv.time.tv_nsec;
                user_ntv.maxerror = ntv.maxerror;
@@ -276,7 +276,7 @@ ntp_gettime(struct proc *p, struct ntp_gettime_args *uap, __unused int32_t *retv
                user_ntv.time_state = ntv.time_state;
                error = copyout(&user_ntv, uap->ntvp, sizeof(user_ntv));
        } else {
-               struct user32_ntptimeval user_ntv;
+               struct user32_ntptimeval user_ntv = {};
                user_ntv.time.tv_sec = ntv.time.tv_sec;
                user_ntv.time.tv_nsec = ntv.time.tv_nsec;
                user_ntv.maxerror = ntv.maxerror;
@@ -439,7 +439,7 @@ ntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap, __unused int32_t *retv
         * returned only by ntp_gettime();
         */
        if (IS_64BIT_PROCESS(p)) {
-               struct user64_timex user_ntv;
+               struct user64_timex user_ntv = {};
 
                if (time_status & STA_NANO)
                        user_ntv.offset = L_GINT(time_offset);
@@ -463,7 +463,7 @@ ntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap, __unused int32_t *retv
 
        }
        else{
-               struct user32_timex user_ntv;
+               struct user32_timex user_ntv = {};
 
                if (time_status & STA_NANO)
                        user_ntv.offset = L_GINT(time_offset);
@@ -712,12 +712,12 @@ adjtime(struct proc *p, struct adjtime_args *uap, __unused int32_t *retval)
 
        if (uap->olddelta) {
                if (IS_64BIT_PROCESS(p)) {
-                       struct user64_timeval user_atv;
+                       struct user64_timeval user_atv = {};
                        user_atv.tv_sec = atv.tv_sec;
                        user_atv.tv_usec = atv.tv_usec;
                        error = copyout(&user_atv, uap->olddelta, sizeof(user_atv));
                } else {
-                       struct user32_timeval user_atv;
+                       struct user32_timeval user_atv = {};
                        user_atv.tv_sec = atv.tv_sec;
                        user_atv.tv_usec = atv.tv_usec;
                        error = copyout(&user_atv, uap->olddelta, sizeof(user_atv));
index 5638b792c5a568159b0fc9ff6bc6cea181e2d3fc..7d641675d95f77432c127ea0a5028c1345d79a97 100644 (file)
@@ -998,7 +998,7 @@ gid_t persona_get_gid(struct persona *persona)
        return gid;
 }
 
-int persona_set_groups(struct persona *persona, gid_t *groups, int ngroups, uid_t gmuid)
+int persona_set_groups(struct persona *persona, gid_t *groups, unsigned ngroups, uid_t gmuid)
 {
        int ret = 0;
        kauth_cred_t my_cred, new_cred;
@@ -1020,7 +1020,7 @@ int persona_set_groups(struct persona *persona, gid_t *groups, int ngroups, uid_
 
        my_cred = persona->pna_cred;
        kauth_cred_ref(my_cred);
-       new_cred = kauth_cred_setgroups(my_cred, groups, ngroups, gmuid);
+       new_cred = kauth_cred_setgroups(my_cred, groups, (int)ngroups, gmuid);
        if (new_cred != my_cred)
                persona->pna_cred = new_cred;
        kauth_cred_unref(&my_cred);
@@ -1030,17 +1030,19 @@ out_unlock:
        return ret;
 }
 
-int persona_get_groups(struct persona *persona, int *ngroups, gid_t *groups, int groups_sz)
+int persona_get_groups(struct persona *persona, unsigned *ngroups, gid_t *groups, unsigned groups_sz)
 {
        int ret = EINVAL;
-       if (!persona || !persona->pna_cred || !groups || !ngroups)
+       if (!persona || !persona->pna_cred || !groups || !ngroups || groups_sz > NGROUPS)
                return EINVAL;
 
        *ngroups = groups_sz;
 
        persona_lock(persona);
        if (persona_valid(persona)) {
-               kauth_cred_getgroups(persona->pna_cred, groups, ngroups);
+               int kauth_ngroups = (int)groups_sz;
+               kauth_cred_getgroups(persona->pna_cred, groups, &kauth_ngroups);
+               *ngroups = (unsigned)kauth_ngroups;
                ret = 0;
        }
        persona_unlock(persona);
index 83bd75cd2d8dffa88363cacf6860269c23ac2226..249d8c3553db97e05dd327b1e416b8b5d2ade481 100644 (file)
 #include <sys/bsdtask_info.h>
 #include <sys/persona.h>
 
+#ifdef CONFIG_32BIT_TELEMETRY
+#include <sys/kasl.h>
+#endif /* CONFIG_32BIT_TELEMETRY */
+
 #if CONFIG_CSR
 #include <sys/csr.h>
 #endif
 
 #include <libkern/crypto/sha1.h>
 
+#ifdef CONFIG_32BIT_TELEMETRY
+#define MAX_32BIT_EXEC_SIG_SIZE 160
+#endif /* CONFIG_32BIT_TELEMETRY */
+
 /*
  * Structure associated with user cacheing.
  */
@@ -1155,7 +1163,7 @@ proc_getexecutablevnode(proc_t p)
                if (vnode_getwithref(tvp) == 0) {
                        return tvp;
                }
-       }       
+       }
 
        return NULLVP;
 }
@@ -3431,3 +3439,80 @@ proc_get_uthread_uu_threadlist(void * uthread_v)
        uthread_t uth = (uthread_t)uthread_v;
        return (uth != NULL) ? uth->uu_threadlist : NULL;
 }
+
+#ifdef CONFIG_32BIT_TELEMETRY
+void
+proc_log_32bit_telemetry(proc_t p)
+{
+       /* Gather info */
+       char signature_buf[MAX_32BIT_EXEC_SIG_SIZE] = { 0 };
+       char * signature_cur_end = &signature_buf[0];
+       char * signature_buf_end = &signature_buf[MAX_32BIT_EXEC_SIG_SIZE - 1];
+       int bytes_printed = 0;
+
+       const char * teamid = NULL;
+       const char * identity = NULL;
+       struct cs_blob * csblob = NULL;
+
+       proc_list_lock();
+
+       /*
+        * Get proc name and parent proc name; if the parent execs, we'll get a
+        * garbled name.
+        */
+       bytes_printed = snprintf(signature_cur_end,
+                                signature_buf_end - signature_cur_end,
+                                "%s,%s,", p->p_name,
+                                (p->p_pptr ? p->p_pptr->p_name : ""));
+
+       if (bytes_printed > 0) {
+               signature_cur_end += bytes_printed;
+       }
+
+       proc_list_unlock();
+
+       /* Get developer info. */
+       vnode_t v = proc_getexecutablevnode(p);
+
+       if (v) {
+               csblob = csvnode_get_blob(v, 0);
+
+               if (csblob) {
+                       teamid = csblob_get_teamid(csblob);
+                       identity = csblob_get_identity(csblob);
+               }
+       }
+
+       if (teamid == NULL) {
+               teamid = "";
+       }
+
+       if (identity == NULL) {
+               identity = "";
+       }
+
+       bytes_printed = snprintf(signature_cur_end,
+                                signature_buf_end - signature_cur_end,
+                                "%s,%s", teamid, identity);
+
+       if (bytes_printed > 0) {
+               signature_cur_end += bytes_printed;
+       }
+
+       if (v) {
+               vnode_put(v);
+       }
+
+       /*
+        * We may want to rate limit here, although the SUMMARIZE key should
+        * help us aggregate events in userspace.
+        */
+
+       /* Emit log */
+       kern_asl_msg(LOG_DEBUG, "messagetracer", 3,
+       /* 0 */ "com.apple.message.domain", "com.apple.kernel.32bit_exec",
+       /* 1 */ "com.apple.message.signature", signature_buf,
+       /* 2 */ "com.apple.message.summarize", "YES",
+               NULL);
+}
+#endif /* CONFIG_32BIT_TELEMETRY */
index 7bc8466bcc09f32d39192af140509fa1a2088ad5..780159263d051645e27aea413e9f7592123608a2 100644 (file)
@@ -1144,7 +1144,7 @@ out:
 int
 getrlimit(struct proc *p, struct getrlimit_args *uap, __unused int32_t *retval)
 {
-       struct rlimit lim;
+       struct rlimit lim = {};
 
        /*
         * Take out flag now in case we need to use it to trigger variant
index ca7b6c584ad1b7e144a9af70e4b970f3cb1c104a..d390ded07a4aaed8a46919d4e3851ef2694bb854 100644 (file)
@@ -3440,11 +3440,16 @@ bsd_ast(thread_t thread)
        }
        proc_unlock(p);
 
+#ifdef CONFIG_32BIT_TELEMETRY
+       if (task_consume_32bit_log_flag(p->task)) {
+               proc_log_32bit_telemetry(p);
+       }
+#endif /* CONFIG_32BIT_TELEMETRY */
+
        if (!bsd_init_done) {
                bsd_init_done = 1;
                bsdinit_task();
        }
-
 }
 
 /* ptrace set runnable */
index 43f1a78b0a329d673459d4e19a9f7f87b913037b..f84a814cbc6420c2c0d78583e8780bd2e3c7d3af 100644 (file)
@@ -65,6 +65,7 @@
 #include <machine/exec.h>
 #include <machine/pal_routines.h>
 
+#include <kern/ast.h>
 #include <kern/kern_types.h>
 #include <kern/cpu_number.h>
 #include <kern/mach_loader.h>
@@ -520,6 +521,19 @@ load_machfile(
                task_rollup_accounting_info(get_threadtask(thread), task);
        }
        *mapp = map;
+
+#ifdef CONFIG_32BIT_TELEMETRY
+       if (!result->is64bit) {
+               /*
+                * This may not need to be an AST; we merely need to ensure that
+                * we gather telemetry at the point where all of the information
+                * that we want has been added to the process.
+                */
+               task_set_32bit_log_flag(get_threadtask(thread));
+               act_set_astbsd(thread);
+       }
+#endif /* CONFIG_32BIT_TELEMETRY */
+
        return(LOAD_SUCCESS);
 }
 
@@ -1121,34 +1135,9 @@ parse_machfile(
                        break;
        }
 
-       if (ret == LOAD_SUCCESS) { 
-               if (! got_code_signatures) {
-                       if (cs_enforcement(NULL)) {
-                               ret = LOAD_FAILURE;
-                       } else {
-#if !CONFIG_EMBEDDED
-                               /*
-                                * No embedded signatures: look for detached by taskgated,
-                                * this is only done on OSX, on embedded platforms we expect everything
-                                * to be have embedded signatures.
-                                */
-                               struct cs_blob *blob;
-
-                               blob = ubc_cs_blob_get(vp, -1, file_offset);
-                               if (blob != NULL) {
-                                       unsigned int cs_flag_data = blob->csb_flags;
-                                       if(0 != ubc_cs_generation_check(vp)) {
-                                               if (0 != ubc_cs_blob_revalidate(vp, blob, imgp, 0)) {
-                                                       /* clear out the flag data if revalidation fails */
-                                                       cs_flag_data = 0;
-                                                       result->csflags &= ~CS_VALID;
-                                               }
-                                       }
-                                       /* get flags to be applied to the process */
-                                       result->csflags |= cs_flag_data;
-                               }
-#endif
-                       }
+       if (ret == LOAD_SUCCESS) {
+               if(!got_code_signatures && cs_enforcement(NULL)) {
+                       ret = LOAD_FAILURE;
                }
 
                /* Make sure if we need dyld, we got it */
index 85a92f5feb043ec522c54cb6b26cb44adb692c15..75b2bb7229d73af996481674deb0450a4b4c2c28 100644 (file)
@@ -119,7 +119,7 @@ common_hook(void)
        return rv;
 }
 
-#if (MAC_POLICY_OPS_VERSION != 52)
+#if (MAC_POLICY_OPS_VERSION != 53)
 # error "struct mac_policy_ops doesn't match definition in mac_policy.h"
 #endif
 /*
@@ -281,10 +281,10 @@ const static struct mac_policy_ops policy_ops = {
        CHECK_SET_HOOK(exc_action_label_init)
        CHECK_SET_HOOK(exc_action_label_update)
 
+       CHECK_SET_HOOK(vnode_check_trigger_resolve)
        .mpo_reserved1 = (mpo_reserved_hook_t *)common_hook,
        .mpo_reserved2 = (mpo_reserved_hook_t *)common_hook,
        .mpo_reserved3 = (mpo_reserved_hook_t *)common_hook,
-       .mpo_reserved4 = (mpo_reserved_hook_t *)common_hook,
        CHECK_SET_HOOK(skywalk_flow_check_connect)
        CHECK_SET_HOOK(skywalk_flow_check_listen)
 
index 5cb3daa6b6e5773b3bc6023df4c9fdbc8885f256..fec4bfa44b16cafa59af30b99ac5714062f5ad7b 100644 (file)
@@ -216,7 +216,7 @@ static int __attribute__ ((noinline))
 coalition_info_resource_usage(coalition_t coal, user_addr_t buffer, user_size_t bufsize)
 {
        kern_return_t kr;
-       struct coalition_resource_usage cru;
+       struct coalition_resource_usage cru = {};
 
        kr = coalition_resource_usage_internal(coal, &cru);
 
index 3272922f7771afc05b2bfaa75908366bcf49d507..792043d8dc9bfa93c0cdf175b3f433c13a991e52 100644 (file)
@@ -215,7 +215,7 @@ static int kpersona_info_syscall(user_addr_t idp, user_addr_t infop)
        kinfo.persona_id = persona->pna_id;
        kinfo.persona_type = persona->pna_type;
        kinfo.persona_gid = persona_get_gid(persona);
-       int ngroups = 0;
+       unsigned ngroups = 0;
        persona_get_groups(persona, &ngroups, kinfo.persona_groups, NGROUPS);
        kinfo.persona_ngroups = ngroups;
        kinfo.persona_gmuid = persona_get_gmuid(persona);
@@ -257,7 +257,7 @@ static int kpersona_pidinfo_syscall(user_addr_t idp, user_addr_t infop)
        kinfo.persona_id = persona->pna_id;
        kinfo.persona_type = persona->pna_type;
        kinfo.persona_gid = persona_get_gid(persona);
-       int ngroups = 0;
+       unsigned ngroups = 0;
        persona_get_groups(persona, &ngroups, kinfo.persona_groups, NGROUPS);
        kinfo.persona_ngroups = ngroups;
        kinfo.persona_gmuid = persona_get_gmuid(persona);
index 1c5af8cf3023e0f217778c04034838240ed1fb57..7d744eff9154492e400b006ead6cdc06088fdd74 100644 (file)
@@ -5661,7 +5661,7 @@ integer:
                        goto integer;
 
                case SO_NP_EXTENSIONS: {
-                       struct so_np_extensions sonpx;
+                       struct so_np_extensions sonpx = {};
 
                        sonpx.npx_flags = (so->so_flags & SOF_NPX_SETOPTSHUT) ?
                            SONPX_SETOPTSHUT : 0;
index f51596c3766b1cf2843d23619fac1a1a54945a44..eb2c9fa6acca0444f668db90465129a5ff63240e 100644 (file)
@@ -1735,7 +1735,7 @@ copyout_control(struct proc *p, struct mbuf *m, user_addr_t control,
                         * different size for 32 bits and 64 bits processes
                         */
                        if (cp->cmsg_level == SOL_SOCKET && cp->cmsg_type == SCM_TIMESTAMP) {
-                               unsigned char tmp_buffer[CMSG_SPACE(sizeof(struct user64_timeval))];
+                               unsigned char tmp_buffer[CMSG_SPACE(sizeof(struct user64_timeval))] = {};
                                struct cmsghdr *tmp_cp = (struct cmsghdr *)(void *)tmp_buffer;
                                int tmp_space;
                                struct timeval *tv = (struct timeval *)(void *)CMSG_DATA(cp);
index 6b00d6cad9a1cb8d5d277c1f00a2ef9986e0487b..acd1ac75c7a58a0f691393d90ab19863d109c608 100644 (file)
@@ -2190,12 +2190,11 @@ ifioctl_iforder(u_long cmd, caddr_t data)
 
        case SIOCGIFORDER: {            /* struct if_order */
                struct if_order *ifo = (struct if_order *)(void *)data;
-
-               u_int32_t ordered_count = if_ordered_count;
+               u_int32_t ordered_count = *((volatile u_int32_t *)&if_ordered_count);
 
                if (ifo->ifo_count == 0 ||
                        ordered_count == 0) {
-                       ifo->ifo_count = ordered_count;
+                       ifo->ifo_count = 0;
                } else if (ifo->ifo_ordered_indices != USER_ADDR_NULL) {
                        u_int32_t count_to_copy =
                            MIN(ordered_count, ifo->ifo_count);
@@ -2203,7 +2202,7 @@ ifioctl_iforder(u_long cmd, caddr_t data)
                        struct ifnet *ifp = NULL;
                        u_int32_t cursor = 0;
 
-                       ordered_indices = _MALLOC(length, M_NECP, M_WAITOK);
+                       ordered_indices = _MALLOC(length, M_NECP, M_WAITOK | M_ZERO);
                        if (ordered_indices == NULL) {
                                error = ENOMEM;
                                break;
@@ -2211,7 +2210,8 @@ ifioctl_iforder(u_long cmd, caddr_t data)
 
                        ifnet_head_lock_shared();
                        TAILQ_FOREACH(ifp, &ifnet_ordered_head, if_ordered_link) {
-                               if (cursor >= count_to_copy) {
+                               if (cursor >= count_to_copy ||
+                                   cursor >= if_ordered_count) {
                                        break;
                                }
                                ordered_indices[cursor] = ifp->if_index;
@@ -2219,7 +2219,11 @@ ifioctl_iforder(u_long cmd, caddr_t data)
                        }
                        ifnet_head_done();
 
-                       ifo->ifo_count = count_to_copy;
+                       /* We might have parsed less than the original length
+                        * because the list could have changed.
+                        */
+                       length = cursor * sizeof(u_int32_t);
+                       ifo->ifo_count = cursor;
                        error = copyout(ordered_indices,
                            ifo->ifo_ordered_indices, length);
                } else {
index 764e72bd89328ce2d751ee97f339d441d71e690d..29a449936f526660c63b57998301a4fbe31964c8 100644 (file)
@@ -626,7 +626,7 @@ sysctl_llreach_ifinfo SYSCTL_HANDLER_ARGS
        unsigned int    namelen;
        uint32_t        ifindex;
        struct if_llreach *lr;
-       struct if_llreach_info lri;
+       struct if_llreach_info lri = {};
        struct ifnet    *ifp;
 
        name = (int *)arg1;
index 1588ac17738892995ef0a525ef96fe656d87692f..83666005b0843f3088f60ab9b832f37e0cb0ae66 100644 (file)
@@ -3500,7 +3500,7 @@ necp_client_copy_internal(struct necp_client *client, bool client_is_observed, s
                LIST_FOREACH(flow, &client->flow_list, flow_chain) {
                        if (flow->nexus || (flow->socket && flow->assigned)) {
                                // Write TLV headers
-                               struct necp_client_nexus_flow_header header;
+                               struct necp_client_nexus_flow_header header = {};
                                u_int32_t length = 0;
                                u_int32_t flags = 0;
                                u_int8_t tfo_cookie_len = 0;
@@ -3603,7 +3603,7 @@ necp_client_copy_internal(struct necp_client *client, bool client_is_observed, s
 
                                /* Read the protocol event and reset it */
                                if (flow->has_protoctl_event) {
-                                       struct necp_client_flow_protoctl_event_header protoctl_event_header;
+                                       struct necp_client_flow_protoctl_event_header protoctl_event_header = {};
 
                                        type = NECP_CLIENT_RESULT_PROTO_CTL_EVENT;
                                        length = sizeof(protoctl_event_header.protoctl_event);
@@ -4546,7 +4546,7 @@ necp_match_policy(struct proc *p, struct necp_match_policy_args *uap, int32_t *r
 {
 #pragma unused(retval)
        u_int8_t *parameters = NULL;
-       struct necp_aggregate_result returned_result;
+       struct necp_aggregate_result returned_result = {};
        int error = 0;
 
        if (uap == NULL) {
index 62a475f9d2b4416c315083ceadfb16242f43aed4..977751814169994df197c18fd2d9c2428bdbc74f 100644 (file)
@@ -3395,7 +3395,7 @@ pfioctl_ioc_states(u_long cmd, struct pfioc_states_32 *ps32,
                        break;
                }
 
-               pstore = _MALLOC(sizeof (*pstore), M_TEMP, M_WAITOK);
+               pstore = _MALLOC(sizeof (*pstore), M_TEMP, M_WAITOK | M_ZERO);
                if (pstore == NULL) {
                        error = ENOMEM;
                        break;
index 457eaf4eb35f3ddfb15861e709af4a72dc18ca9e..8c4387a47542b075e15bdd024bb76905f3f91d7d 100644 (file)
@@ -461,7 +461,6 @@ route_output(struct mbuf *m, struct socket *so)
        if (info.rti_info[RTAX_GATEWAY] != NULL &&
            info.rti_info[RTAX_GATEWAY]->sa_family == AF_INET)
                sin_set_ifscope(info.rti_info[RTAX_GATEWAY], IFSCOPE_NONE);
-
        switch (rtm->rtm_type) {
        case RTM_ADD:
                if (info.rti_info[RTAX_GATEWAY] == NULL)
@@ -583,24 +582,23 @@ report:
                        len = rt_msg2(rtm->rtm_type, &info, NULL, NULL, &cred);
                        if (ifa2 != NULL)
                                IFA_UNLOCK(ifa2);
-                       if (len > rtm->rtm_msglen) {
-                               struct rt_msghdr *new_rtm;
-                               R_Malloc(new_rtm, struct rt_msghdr *, len);
-                               if (new_rtm == NULL) {
-                                       RT_UNLOCK(rt);
-                                       if (ifa2 != NULL)
-                                               IFA_REMREF(ifa2);
-                                       senderr(ENOBUFS);
-                               }
-                               Bcopy(rtm, new_rtm, rtm->rtm_msglen);
-                               R_Free(rtm); rtm = new_rtm;
+                       struct rt_msghdr *out_rtm;
+                       R_Malloc(out_rtm, struct rt_msghdr *, len);
+                       if (out_rtm == NULL) {
+                               RT_UNLOCK(rt);
+                               if (ifa2 != NULL)
+                                       IFA_REMREF(ifa2);
+                               senderr(ENOBUFS);
                        }
+                       Bcopy(rtm, out_rtm, sizeof(struct rt_msghdr));
                        if (ifa2 != NULL)
                                IFA_LOCK(ifa2);
-                       (void) rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm,
+                       (void) rt_msg2(out_rtm->rtm_type, &info, (caddr_t)out_rtm,
                            NULL, &cred);
                        if (ifa2 != NULL)
                                IFA_UNLOCK(ifa2);
+                       R_Free(rtm);
+                       rtm = out_rtm;
                        rtm->rtm_flags = rt->rt_flags;
                        rt_getmetrics(rt, &rtm->rtm_rmx);
                        rtm->rtm_addrs = info.rti_addrs;
index 3d8ca9699bfe541edb87eb91dcfa3e8814d8c73b..d772cc806807ad7431062c0edbc613a4ad149f4a 100644 (file)
@@ -1697,7 +1697,7 @@ inp_findmoptions(struct inpcb *inp)
 static int
 inp_get_source_filters(struct inpcb *inp, struct sockopt *sopt)
 {
-       struct __msfilterreq64  msfr, msfr64;
+       struct __msfilterreq64  msfr = {}, msfr64;
        struct __msfilterreq32  msfr32;
        struct sockaddr_in      *gsa;
        struct ifnet            *ifp;
@@ -2719,7 +2719,7 @@ inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
 static int
 inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
 {
-       struct __msfilterreq64   msfr, msfr64;
+       struct __msfilterreq64   msfr = {}, msfr64;
        struct __msfilterreq32   msfr32;
        struct sockaddr_in      *gsa;
        struct ifnet            *ifp;
@@ -3126,7 +3126,7 @@ sysctl_ip_mcast_filters SYSCTL_HANDLER_ARGS
 {
 #pragma unused(oidp)
 
-       struct in_addr                   src, group;
+       struct in_addr                   src = {}, group;
        struct ifnet                    *ifp;
        struct in_multi                 *inm;
        struct in_multistep             step;
index 5d627e551808014b25cf4af421ee27fcbfdc9dfb..81595da9b30f11f62ef60f6092b596f2c13cf741 100644 (file)
@@ -1546,7 +1546,7 @@ sysctl_default_netsvctype_to_dscp_map SYSCTL_HANDLER_ARGS
        const size_t max_netsvctype_to_dscp_map_len =
            _NET_SERVICE_TYPE_COUNT * sizeof(struct netsvctype_dscp_map);
        size_t len;
-       struct netsvctype_dscp_map netsvctype_dscp_map[_NET_SERVICE_TYPE_COUNT];
+       struct netsvctype_dscp_map netsvctype_dscp_map[_NET_SERVICE_TYPE_COUNT] = {};
        size_t count;
 
        if (req->oldptr == USER_ADDR_NULL) {
@@ -1748,7 +1748,7 @@ sysctl_dscp_to_wifi_ac_map SYSCTL_HANDLER_ARGS
 #pragma unused(oidp, arg1, arg2)
        int error = 0;
        size_t len = DSCP_ARRAY_SIZE * sizeof(struct netsvctype_dscp_map);
-       struct netsvctype_dscp_map netsvctype_dscp_map[DSCP_ARRAY_SIZE];
+       struct netsvctype_dscp_map netsvctype_dscp_map[DSCP_ARRAY_SIZE] = {};
        struct dcsp_msc_map dcsp_msc_map[DSCP_ARRAY_SIZE];
        size_t count;
        u_int32_t i;
index 6694975b7b4f1ed014989d842d55ea846b11bcc3..3d69b2029d5edbb290ee9443d24fdba3f9ecd732 100644 (file)
@@ -3792,21 +3792,21 @@ ipfw_ctl(struct sockopt *sopt)
                                if (!error && sopt->sopt_dir == SOPT_GET) {
                                        /* convert back if necessary and copyout */
                                        if (api_version == IP_FW_VERSION_0) {
-                                               struct ip_old_fw        rule_vers0;
+                                               struct ip_old_fw        rule_vers0 = {};
                                                
                                                ipfw_convert_from_latest(rule, &rule_vers0, api_version, is64user);
                                                sopt->sopt_valsize = sizeof(struct ip_old_fw);
                                                
                                                error = sooptcopyout(sopt, &rule_vers0, sizeof(struct ip_old_fw));
                                        } else if (api_version == IP_FW_VERSION_1) {
-                                               struct ip_fw_compat     rule_vers1;
+                                               struct ip_fw_compat     rule_vers1 = {};
                                                ipfw_convert_from_latest(rule, &rule_vers1, api_version, is64user);
                                                sopt->sopt_valsize = sizeof(struct ip_fw_compat);
                                                
                                                error = sooptcopyout(sopt, &rule_vers1, sizeof(struct ip_fw_compat));
                                        } else {
                                                char *userrule;
-                                               userrule = _MALLOC(savedsopt_valsize, M_TEMP, M_WAITOK);
+                                               userrule = _MALLOC(savedsopt_valsize, M_TEMP, M_WAITOK | M_ZERO);
                                                if ( userrule == NULL )
                                                        userrule = (char*)rule;
                                                if (proc_is64bit(sopt->sopt_p)){
index 1a5589901ec81ed82c9a6b3cebc089738cceb1b1..fb199c658fe739a69b4a1a04ca6b7c58ae41d07c 100644 (file)
@@ -1539,7 +1539,7 @@ out:
 static int
 mptcp_getopt(struct mptses *mpte, struct sockopt *sopt)
 {
-       int error = 0, optval;
+       int error = 0, optval = 0;
 
        VERIFY(sopt->sopt_dir == SOPT_GET);
        mpte_lock_assert_held(mpte);    /* same as MP socket lock */
index 9d8fa7efbd5c622da36d4af90929766e61fc1692..3c368cb52f3411c64d213ae84840c10346d7a7d1 100644 (file)
@@ -1765,7 +1765,7 @@ __private_extern__ int
 tcp_sysctl_info(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
 {
        int error;
-       struct tcp_info ti;
+       struct tcp_info ti = {};
        struct info_tuple itpl;
 #if !CONFIG_EMBEDDED
        proc_t caller = PROC_NULL;
@@ -1883,11 +1883,10 @@ tcp_getconninfo(struct socket *so, struct conninfo_tcp *tcp_ci)
 int
 tcp_ctloutput(struct socket *so, struct sockopt *sopt)
 {
-       int     error, opt, optval;
+       int     error = 0, opt = 0, optval = 0;
        struct  inpcb *inp;
        struct  tcpcb *tp;
 
-       error = 0;
        inp = sotoinpcb(so);
        if (inp == NULL) {
                return (ECONNRESET);
@@ -2490,7 +2489,7 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt)
                        goto done;
                }
                case TCP_MEASURE_BW_BURST: {
-                       struct tcp_measure_bw_burst out;
+                       struct tcp_measure_bw_burst out = {};
                        if ((tp->t_flagsext & TF_MEASURESNDBW) == 0 ||
                                tp->t_bwmeas == NULL) {
                                error = EINVAL;
index 044486ec5b33c8fa97c0e8b6152465b847a2ad17..0c4945e79b07f3e149b2767993493c677a7d39a9 100644 (file)
@@ -923,7 +923,7 @@ udp_ctlinput(int cmd, struct sockaddr *sa, void *vip, __unused struct ifnet * if
 int
 udp_ctloutput(struct socket *so, struct sockopt *sopt)
 {
-       int     error, optval;
+       int     error = 0, optval = 0;
        struct  inpcb *inp;
 
        /* Allow <SOL_SOCKET,SO_FLUSH> at this level */
@@ -931,7 +931,6 @@ udp_ctloutput(struct socket *so, struct sockopt *sopt)
            !(sopt->sopt_level == SOL_SOCKET && sopt->sopt_name == SO_FLUSH))
                return (ip_ctloutput(so, sopt));
 
-       error = 0;
        inp = sotoinpcb(so);
 
        switch (sopt->sopt_dir) {
index 778bafa8d626c0ed6c5e845b60f8add9bc1e095f..3bd00c8a2162e663914534926b938541eff2e8eb 100644 (file)
@@ -1619,7 +1619,7 @@ in6p_findmoptions(struct inpcb *inp)
 static int
 in6p_get_source_filters(struct inpcb *inp, struct sockopt *sopt)
 {
-       struct __msfilterreq64  msfr, msfr64;
+       struct __msfilterreq64  msfr = {}, msfr64;
        struct __msfilterreq32  msfr32;
        struct sockaddr_in6     *gsa;
        struct ifnet            *ifp;
@@ -2650,7 +2650,7 @@ in6p_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
 static int
 in6p_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
 {
-       struct __msfilterreq64   msfr, msfr64;
+       struct __msfilterreq64   msfr = {}, msfr64;
        struct __msfilterreq32   msfr32;
        struct sockaddr_in6     *gsa;
        struct ifnet            *ifp;
index 266710149d0df757290a89a5f93b8343e9111e81..ff5ae70b6fbf4faf263f939264e2039b90c111f8 100644 (file)
@@ -3272,6 +3272,10 @@ nfsrv_export_lookup(struct nfs_export *nx, mbuf_t nam)
        /* Lookup in the export list first. */
        if (nam != NULL) {
                saddr = mbuf_data(nam);
+               if (saddr->sa_family > AF_MAX) {
+                       /* Bogus sockaddr?  Don't match anything. */
+                       return (NULL);
+               }
                rnh = nx->nx_rtable[saddr->sa_family];
                if (rnh != NULL) {
                        no = (struct nfs_netopt *)
index 67b9befc0b7ddb596ea8c121610cbb753b72443a..89f6ca9566ccf1f31bfe10f3ffe425ec46189f36 100644 (file)
@@ -5464,10 +5464,10 @@ nfs_vfs_sysctl(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
        struct nfs_exportfs *nxfs;
        struct nfs_export *nx;
        struct nfs_active_user_list *ulist;
-       struct nfs_export_stat_desc stat_desc;
+       struct nfs_export_stat_desc stat_desc = {};
        struct nfs_export_stat_rec statrec;
        struct nfs_user_stat_node *unode, *unode_next;
-       struct nfs_user_stat_desc ustat_desc;
+       struct nfs_user_stat_desc ustat_desc = {};
        struct nfs_user_stat_user_rec ustat_rec;
        struct nfs_user_stat_path_rec upath_rec;
        uint bytes_avail, bytes_total, recs_copied;
index f1efd66d4f976803d2c6fdfce9524e4ec29ab20e..0744283f2d66ae7ff3c77aec091b1658eb807b7c 100644 (file)
@@ -354,8 +354,8 @@ uid_t persona_get_uid(struct persona *persona);
 int persona_set_gid(struct persona *persona, gid_t gid);
 gid_t persona_get_gid(struct persona *persona);
 
-int persona_set_groups(struct persona *persona, gid_t *groups, int ngroups, uid_t gmuid);
-int persona_get_groups(struct persona *persona, int *ngroups, gid_t *groups, int groups_sz);
+int persona_set_groups(struct persona *persona, gid_t *groups, unsigned ngroups, uid_t gmuid);
+int persona_get_groups(struct persona *persona, unsigned *ngroups, gid_t *groups, unsigned groups_sz);
 
 uid_t persona_get_gmuid(struct persona *persona);
 
index 7878ff6442b3042bc625526e71ee790138a78228..f275e9f92bbfb9226aa4e019d71cfd76c17d8bd2 100644 (file)
@@ -364,6 +364,10 @@ extern uint64_t proc_did_throttle(proc_t);
 
 extern void proc_coalitionids(proc_t, uint64_t [COALITION_NUM_TYPES]);
 
+#ifdef CONFIG_32BIT_TELEMETRY
+extern void proc_log_32bit_telemetry(proc_t p);
+#endif /* CONFIG_32BIT_TELEMETRY */
+
 #endif /* XNU_KERNEL_PRIVATE*/
 
 #ifdef KERNEL_PRIVATE
index df1e9569fd018c9ccd0ed39d6a81b2ddc0771ae2..32fc807ffa48e80960854d24d867781149b70b14 100644 (file)
@@ -3323,7 +3323,7 @@ cluster_write_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t old
 
                        io_size += start_offset;
 
-                       if ((upl_f_offset + io_size) >= newEOF && (u_int)io_size < upl_size) {
+                       if (newEOF >= oldEOF && (upl_f_offset + io_size) >= newEOF && (u_int)io_size < upl_size) {
                                /*
                                 * if we're extending the file with this write
                                 * we'll zero fill the rest of the page so that
index 5acfa82d4f82fa3686cdea115291cd3f3bbeaf99..dc434d049f911af08e24c3690b2f00f247a59012 100644 (file)
@@ -3492,7 +3492,7 @@ again:
        if (space < req->oldlen)
                return (ENOMEM);
 
-       MALLOC(fsidlst, fsid_t *, req->oldlen, M_TEMP, M_WAITOK);
+       MALLOC(fsidlst, fsid_t *, req->oldlen, M_TEMP, M_WAITOK | M_ZERO);
        if (fsidlst == NULL) {
                return (ENOMEM);
        }
@@ -3861,7 +3861,7 @@ sysctl_vfs_generic_conf SYSCTL_HANDLER_ARGS
 {
        int *name, namelen;
        struct vfstable *vfsp;
-       struct vfsconf vfsc;
+       struct vfsconf vfsc = {};
        
        (void)oidp;
        name = arg1;
@@ -9503,6 +9503,12 @@ vnode_trigger_resolve(vnode_t vp, struct nameidata *ndp, vfs_context_t ctx)
 
        lck_mtx_unlock(&rp->vr_lock);
 
+#if CONFIG_MACF
+       int rv = mac_vnode_check_trigger_resolve(ctx, vp, &ndp->ni_cnd);
+       if (rv != 0)
+               return rv;
+#endif
+
        /*
         * XXX
         * assumes that resolver will not access this trigger vnode (otherwise the kernel will deadlock)
index 2571c94d5b2b58b36c3be7e5982e85d10af6ab77..b2209d58d18365621f7e50c14f199abca8e56776 100644 (file)
@@ -5500,13 +5500,13 @@ fstatat_internal(vfs_context_t ctx, user_addr_t path, user_addr_t ub,
        union {
                struct stat sb;
                struct stat64 sb64;
-       } source;
+       } source = {};
        union {
                struct user64_stat user64_sb;
                struct user32_stat user32_sb;
                struct user64_stat64 user64_sb64;
                struct user32_stat64 user32_sb64;
-       } dest;
+       } dest = {};
        caddr_t sbp;
        int error, my_size;
        kauth_filesec_t fsec;
index 6c190be01f05563bac1874ee1b77caba1b5c237c..67b209861e8895ad6478f9830d44d802418aa24c 100644 (file)
@@ -16,6 +16,8 @@ _mac_iokit_check_nvram_delete
 _mac_iokit_check_nvram_get
 _mac_iokit_check_nvram_set
 
+_mac_vnode_check_trigger_resolve
+
 _sbuf_cat
 _sbuf_data
 _sbuf_delete
index 2fa15892365b984ab284f40529c8ecf3cc60785e..d4561e50dbfaf1b9506bd3324ed1b4dfbf632f8f 100644 (file)
@@ -735,3 +735,8 @@ options             CONFIG_REQUIRES_U32_MUNGING     # incoming U32 argument structures must be
 #
 options                COPYOUT_SHIM                    # Shim for copyout memory analysis via kext #<copyout_shim>
 
+
+#
+# Telemetry for 32-bit process launch
+#
+options                CONFIG_32BIT_TELEMETRY # # <config_32bit_telemetry>
index 0c8b7a4e53a1631035382d421a05f229ba862988..1a934777de2cc366f4d95f25cb5289ea9fd8d984 100644 (file)
@@ -20,7 +20,7 @@
 #  KERNEL_RELEASE = [ KERNEL_BASE ]
 #  KERNEL_DEV =     [ KERNEL_BASE development mach_assert config_xnupost proc_ref_debug os_reason_debug ]
 #  KERNEL_DEBUG =   [ KERNEL_BASE debug mach_assert config_xnupost config_ltable_stats config_ltable_debug config_waitq_stats config_waitq_debug ]
-#  BSD_BASE =       [ mach_bsd sysv_sem sysv_msg sysv_shm config_imageboot config_workqueue psynch config_proc_uuid_policy config_coredump pgo ]
+#  BSD_BASE =       [ mach_bsd sysv_sem sysv_msg sysv_shm config_imageboot config_workqueue psynch config_proc_uuid_policy config_coredump pgo config_32bit_telemetry ]
 #  BSD_RELEASE =    [ BSD_BASE ]
 #  BSD_DEV =        [ BSD_BASE config_vnguard ]
 #  BSD_DEBUG =      [ BSD_BASE config_vnguard ]
index db6ac06457fe8e5c645a9d2a0fccb595036553be..7efb2c146e628fd35eb4634a83707eb0657309d3 100644 (file)
@@ -1,4 +1,4 @@
-17.3.0
+17.4.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 cce1695b9b91ece68fe6e6f461cdb9f0193662d4..2aa05be08b2532d8f9a2173a9073a4c4e2081597 100644 (file)
@@ -209,10 +209,11 @@ public:
     UInt8   __reservedA[1];
     volatile SInt32 __ipc;
     queue_head_t owners;
+    IOLock * lock;
 #if __LP64__
-    void  * __reserved[5];
-#else
     void  * __reserved[4];
+#else
+    void  * __reserved[3];
 #endif
 
 #else /* XNU_KERNEL_PRIVATE */
index 6a3fc814b113beef0832682348598ed16ae60df8..ad83881cae1f8d98c97f562e181b20a007c4e2da 100644 (file)
@@ -605,7 +605,9 @@ iokit_client_died( io_object_t obj, ipc_port_t /* port */,
        if( (client = OSDynamicCast( IOUserClient, obj )))
        {
            IOStatisticsClientCall();
+           IOLockLock(client->lock);
            client->clientDied();
+           IOLockUnlock(client->lock);
         }
     }
     else if( IKOT_IOKIT_OBJECT == type)
@@ -1544,6 +1546,7 @@ iokit_task_terminate(task_t task)
 void IOUserClient::free()
 {
     if( mappings) mappings->release();
+    if (lock) IOLockFree(lock);
                
     IOStatisticsUnregisterCounter();
 
@@ -3465,6 +3468,7 @@ kern_return_t is_io_service_open_extended(
 
            client->sharedInstance = (0 != client->getProperty(kIOUserClientSharedInstanceKey));
            client->closed = false;
+           client->lock = IOLockAlloc();
 
            disallowAccess = (crossEndian
                && (kOSBooleanTrue != service->getProperty(kIOUserClientCrossEndianCompatibleKey))
@@ -3516,7 +3520,9 @@ kern_return_t is_io_service_close(
 
     if (client->sharedInstance || OSCompareAndSwap8(0, 1, &client->closed)) 
     {
+       IOLockLock(client->lock);
        client->clientClose();
+       IOLockUnlock(client->lock);
     }
     else
     {
@@ -3552,11 +3558,15 @@ kern_return_t is_io_connect_set_notification_port(
        mach_port_t port,
        uint32_t reference)
 {
+    kern_return_t ret;
     CHECK( IOUserClient, connection, client );
 
     IOStatisticsClientCall();
-    return( client->registerNotificationPort( port, notification_type,
-                                               (io_user_reference_t) reference ));
+    IOLockLock(client->lock);
+    ret = client->registerNotificationPort( port, notification_type,
+                                               (io_user_reference_t) reference );
+    IOLockUnlock(client->lock);
+    return (ret);
 }
 
 /* Routine io_connect_set_notification_port */
@@ -3566,11 +3576,15 @@ kern_return_t is_io_connect_set_notification_port_64(
        mach_port_t port,
        io_user_reference_t reference)
 {
+    kern_return_t ret;
     CHECK( IOUserClient, connection, client );
 
     IOStatisticsClientCall();
-    return( client->registerNotificationPort( port, notification_type,
-                                               reference ));
+    IOLockLock(client->lock);
+    ret = client->registerNotificationPort( port, notification_type,
+                                               reference );
+    IOLockUnlock(client->lock);
+    return (ret);
 }
 
 /* Routine io_connect_map_memory_into_task */
index 1334f4c3d91f828c2a29df6bd3eed0f1e7f7ffa9..3a149790c8d0f9c72ee9f2bc24369a3f28cb9e02 100644 (file)
@@ -1730,7 +1730,7 @@ posix_spawnattr_set_persona_groups_np(const posix_spawnattr_t * __restrict attr,
        if (gidarray == NULL)
                return EINVAL;
 
-       if (ngroups > NGROUPS)
+       if (ngroups > NGROUPS || ngroups < 0)
                return EINVAL;
 
        psattr = *(_posix_spawnattr_t *)attr;
index d601291b6fd0f1f8650e51c15c380cc3eb3007a1..9bd9f3b0e8249889767ff787b4c489306b4123dd 100644 (file)
@@ -400,7 +400,7 @@ mach_timebase_info_trap(
        struct mach_timebase_info_trap_args *args)
 {
        mach_vm_address_t                       out_info_addr = args->info;
-       mach_timebase_info_data_t       info;
+       mach_timebase_info_data_t       info = {};
 
        clock_timebase_info(&info);
 
index 28da75b50e92a137b34b43dc41f5b03dd9c9b6de..bc7357560dd03fdb0e2975dbe774201940e705dc 100644 (file)
@@ -499,7 +499,7 @@ clock_sleep_trap(
        int                                     sleep_nsec = args->sleep_nsec;
        mach_vm_address_t       wakeup_time_addr = args->wakeup_time;  
        clock_t                         clock;
-       mach_timespec_t         swtime;
+       mach_timespec_t         swtime = {};
        kern_return_t           rvalue;
 
        /*
index d58d29cdbc186852040e2a3fdc7f9973f67b9e10..cb3a359b552d78ab099a7815e8c1cf66dc81ffc8 100644 (file)
@@ -500,6 +500,25 @@ task_wait_to_return(void)
        thread_bootstrap_return();
 }
 
+#ifdef CONFIG_32BIT_TELEMETRY
+boolean_t
+task_consume_32bit_log_flag(task_t task)
+{
+       if ((task->t_procflags & TPF_LOG_32BIT_TELEMETRY) != 0) {
+               task->t_procflags &= ~TPF_LOG_32BIT_TELEMETRY;
+               return TRUE;
+       } else {
+               return FALSE;
+       }
+}
+
+void
+task_set_32bit_log_flag(task_t task)
+{
+       task->t_procflags |= TPF_LOG_32BIT_TELEMETRY;
+}
+#endif /* CONFIG_32BIT_TELEMETRY */
+
 boolean_t
 task_is_exec_copy(task_t task)
 {
index 847120f95aa8d4e0bf886b09d14f225ee82e0ef8..352c50450402de7d42f869d1ca489d91b4861822 100644 (file)
@@ -288,6 +288,9 @@ struct task {
 #define TPF_NONE                 0
 #define TPF_DID_EXEC             0x00000001                              /* task has been execed to a new task */
 #define TPF_EXEC_COPY            0x00000002                              /* task is the new copy of an exec */
+#ifdef CONFIG_32BIT_TELEMETRY
+#define TPF_LOG_32BIT_TELEMETRY  0x00000004                              /* task should log identifying information */
+#endif
 
 #define task_did_exec_internal(task)           \
        (((task)->t_procflags & TPF_DID_EXEC) != 0)
@@ -742,6 +745,10 @@ extern void task_set_did_exec_flag(task_t task);
 extern void task_clear_exec_copy_flag(task_t task);
 extern boolean_t task_is_exec_copy(task_t);
 extern boolean_t task_did_exec(task_t task);
+#ifdef CONFIG_32BIT_TELEMETRY
+extern boolean_t task_consume_32bit_log_flag(task_t task);
+extern void task_set_32bit_log_flag(task_t task);
+#endif /* CONFIG_32BIT_TELEMETRY */
 extern boolean_t task_is_active(task_t task);
 extern boolean_t task_is_halting(task_t task);
 extern void task_clear_return_wait(task_t task);
index ec5955df86f81ebe191337679a92bbd57eb94495..2bd03b8eb1cd155aabc3813cd83243ba9a234961 100644 (file)
@@ -2026,4 +2026,10 @@ int mac_iokit_check_nvram_set(kauth_cred_t cred __unused, const char *name __unu
        return 0;
 }
 
+int mac_vnode_check_trigger_resolve(vfs_context_t ctx __unused, struct vnode *dvp __unused, struct componentname *cnp __unused);
+int mac_vnode_check_trigger_resolve(vfs_context_t ctx __unused, struct vnode *dvp __unused, struct componentname *cnp __unused)
+{
+       return 0;
+}
+
 #endif /* !MAC */
index b5560a3200b4a11f9f91c09a8c5f091390340f3c..81a4839c81132dac436e31ae09b0a4779015e2ac 100644 (file)
@@ -534,11 +534,13 @@ int       mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp,
 int    mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
            struct timespec atime, struct timespec mtime);
 int    mac_vnode_check_signature(struct vnode *vp,
-               struct cs_blob *cs_blob, struct image_params *imgp,
-               unsigned int *cs_flags, unsigned int *signer_type,
-               int flags);
+           struct cs_blob *cs_blob, struct image_params *imgp,
+           unsigned int *cs_flags, unsigned int *signer_type,
+           int flags);
 int    mac_vnode_check_stat(vfs_context_t ctx,
            kauth_cred_t file_cred, struct vnode *vp);
+int    mac_vnode_check_trigger_resolve(vfs_context_t ctx, struct vnode *dvp,
+           struct componentname *cnp);
 int    mac_vnode_check_truncate(vfs_context_t ctx,
            kauth_cred_t file_cred, struct vnode *vp);
 int    mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
index eedfeab13ee057ba24e4734dcc62bbbfefdce7bf..e656f8393d70006474f19af2b681464654342493 100644 (file)
@@ -5431,6 +5431,27 @@ typedef int mpo_vnode_check_stat_t(
        struct vnode *vp,
        struct label *label
 );
+/**
+  @brief Access control check for vnode trigger resolution
+  @param cred Subject credential
+  @param dvp Object vnode
+  @param dlabel Policy label for dvp
+  @param cnp Component name that triggered resolution
+
+  Determine whether the subject identified by the credential can trigger
+  resolution of the passed name (cnp) in the passed directory vnode
+  via an external trigger resolver.
+
+  @return Return 0 if access is granted, otherwise an appropriate value for
+  errno should be returned. Suggested failure: EACCES for label mismatch or
+  EPERM for lack of privilege.
+*/
+typedef int mpo_vnode_check_trigger_resolve_t(
+       kauth_cred_t cred,
+       struct vnode *dvp,
+       struct label *dlabel,
+       struct componentname *cnp
+);
 /**
   @brief Access control check for truncate/ftruncate
   @param active_cred Subject credential
@@ -6301,7 +6322,7 @@ typedef void mpo_reserved_hook_t(void);
  * Please note that this should be kept in sync with the check assumptions
  * policy in bsd/kern/policy_check.c (policy_ops struct).
  */
-#define MAC_POLICY_OPS_VERSION 52 /* inc when new reserved slots are taken */
+#define MAC_POLICY_OPS_VERSION 53 /* inc when new reserved slots are taken */
 struct mac_policy_ops {
        mpo_audit_check_postselect_t            *mpo_audit_check_postselect;
        mpo_audit_check_preselect_t             *mpo_audit_check_preselect;
@@ -6453,10 +6474,10 @@ struct mac_policy_ops {
        mpo_exc_action_label_init_t             *mpo_exc_action_label_init;
        mpo_exc_action_label_update_t           *mpo_exc_action_label_update;
 
+       mpo_vnode_check_trigger_resolve_t       *mpo_vnode_check_trigger_resolve;
        mpo_reserved_hook_t                     *mpo_reserved1;
        mpo_reserved_hook_t                     *mpo_reserved2;
        mpo_reserved_hook_t                     *mpo_reserved3;
-       mpo_reserved_hook_t                     *mpo_reserved4;
        mpo_skywalk_flow_check_connect_t        *mpo_skywalk_flow_check_connect;
        mpo_skywalk_flow_check_listen_t         *mpo_skywalk_flow_check_listen;
 
index 0d55a1c271958766db570f420adbe41226ccfe96..9c9b36c66279e1cfa23e6a54e7ef6b024c8ce4e9 100644 (file)
@@ -1699,6 +1699,25 @@ mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
        return (error);
 }
 
+int
+mac_vnode_check_trigger_resolve(vfs_context_t ctx, struct vnode *dvp,
+    struct componentname *cnp)
+{
+       kauth_cred_t cred;
+       int error;
+
+#if SECURITY_MAC_CHECK_ENFORCE
+       /* 21167099 - only check if we allow write */
+       if (!mac_vnode_enforce)
+               return 0;
+#endif
+       cred = vfs_context_ucred(ctx);
+       if (!mac_cred_check_enforce(cred))
+               return (0);
+       MAC_CHECK(vnode_check_trigger_resolve, cred, dvp, dvp->v_label, cnp);
+       return (error);
+}
+
 int
 mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
     struct vnode *vp)
diff --git a/tools/tests/darwintests/socket_bind_35243417.c b/tools/tests/darwintests/socket_bind_35243417.c
new file mode 100644 (file)
index 0000000..de5eed5
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+
+#include <darwintest.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <TargetConditionals.h>
+
+static int
+sockv6_open(void)
+{
+       int     s;
+
+       s = socket(AF_INET6, SOCK_DGRAM, 0);
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(s, "socket(AF_INET6, SOCK_DGRAM, 0)");
+       return (s);
+}
+
+static int
+sockv6_bind(int s, in_port_t port)
+{
+       struct sockaddr_in6     sin6;
+
+       bzero(&sin6, sizeof(sin6));
+       sin6.sin6_len = sizeof(sin6);
+       sin6.sin6_family = AF_INET6;
+       sin6.sin6_port = port;
+       return (bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)));
+}
+
+static void
+sockv6_set_v6only(int s)
+{
+       int             on = 1;
+       int             ret;
+
+       ret = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(ret, "setsockopt(%d, IPV6_ONLY)", s);
+}
+
+static bool
+alloc_and_bind_ports(in_port_t port_start, in_port_t port_end,
+                    int bind_attempts)
+{
+       int     bound_count = 0;
+       bool    success = true;
+
+       for (in_port_t i = port_start; success && i <= port_end; i++) {
+               int     s6 = -1;
+               int     s6_other = -1;
+               int     ret;
+
+               s6 = sockv6_open();
+               sockv6_set_v6only(s6);
+               if (sockv6_bind(s6, i) != 0) {
+                       /* find the next available port */
+                       goto loop_done;
+               }
+               s6_other = sockv6_open();
+               ret = sockv6_bind(s6_other, i);
+               T_WITH_ERRNO;
+               T_QUIET;
+               T_ASSERT_TRUE(ret != 0, "socket %d bind %d", s6_other, i);
+               /*
+                * After bind fails, try binding to a different port.
+                * For non-root user, this will panic without the fix for
+                * <rdar://problem/35243417>.
+                */
+               if (sockv6_bind(s6_other, i + 1) == 0) {
+                       bound_count++;
+                       if (bound_count >= bind_attempts) {
+                               break;
+                       }
+               }
+       loop_done:
+               if (s6 >= 0) {
+                       close(s6);
+               }
+               if (s6_other >= 0) {
+                       close(s6_other);
+               }
+       }
+       T_ASSERT_TRUE(bound_count == bind_attempts,
+                     "number of successful binds %d (out of %d)",
+                     bound_count, bind_attempts);
+       return (success);
+}
+
+
+T_DECL(socket_bind_35243417,
+       "bind IPv6 only UDP socket, then bind IPv6 socket.",
+       T_META_ASROOT(false),
+       T_META_CHECK_LEAKS(false))
+{
+#if TARGET_OS_WATCH
+       T_SKIP("socket_bind_35243417 can't run on watch.");
+#else
+       alloc_and_bind_ports(1, 65534, 10);
+#endif
+}
+
+T_DECL(socket_bind_35243417_root,
+       "bind IPv6 only UDP socket, then bind IPv6 socket.",
+       T_META_ASROOT(true))
+{
+#if TARGET_OS_WATCH
+       T_SKIP("socket_bind_35243417_root can't run on watch.");
+#else
+       alloc_and_bind_ports(1, 65534, 10);
+#endif
+}
index f6776c873f0d33343e99f69e2c4f4ab2641a8a2a..5da9f5bff6a0714c1d9dbc09bb372cd8e9ee80a1 100644 (file)
@@ -219,8 +219,10 @@ int main(int argc, char **argv)
                        break;
                case 'u':
                        ret = atoi(optarg);
-                       if (ret <= 0)
-                               err("Invalid UID: %s", optarg);
+                       /* allow invalid / -1 as a wildcard for lookup */
+                       if (ret < 0 && persona_op != PERSONA_OP_LOOKUP) {
+                               err("Invalid UID:%s (%d)", optarg, ret);
+                       }
                        uid = (uid_t)ret;
                        break;
                case 'g':
@@ -255,7 +257,7 @@ int main(int argc, char **argv)
                }
        }
 
-       if (uid == (uid_t)-1)
+       if (uid == (uid_t)-1 && persona_op != PERSONA_OP_LOOKUP)
                uid = kinfo.persona_id;
 
        if (kinfo.persona_gmuid && kinfo.persona_ngroups == 0) {