X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/490019cf9519204c5fb36b2fba54ceb983bb6b72..b226f5e54a60dc81db17b1260381d7dbfea3cdf1:/libsyscall/wrappers/spawn/posix_spawn.c?ds=sidebyside diff --git a/libsyscall/wrappers/spawn/posix_spawn.c b/libsyscall/wrappers/spawn/posix_spawn.c index 4c36d0e90..20083809a 100644 --- a/libsyscall/wrappers/spawn/posix_spawn.c +++ b/libsyscall/wrappers/spawn/posix_spawn.c @@ -39,7 +39,7 @@ #include #include #include /* for COALITION_TYPE_MAX */ - +#include /* * posix_spawnattr_init @@ -123,6 +123,9 @@ posix_spawnattr_init(posix_spawnattr_t *attr) (*psattrp)->psa_memlimit_active = -1; (*psattrp)->psa_memlimit_inactive = -1; + /* Default is no thread limit */ + (*psattrp)->psa_thread_limit = 0; + /* Default is no CPU usage monitor active. */ (*psattrp)->psa_cpumonitor_percent = 0; (*psattrp)->psa_cpumonitor_interval = 0; @@ -150,6 +153,8 @@ posix_spawnattr_init(posix_spawnattr_t *attr) /* Default is no change to role */ (*psattrp)->psa_darwin_role = POSIX_SPAWN_DARWIN_ROLE_NONE; + + (*psattrp)->psa_max_addr = 0; } return (err); @@ -713,7 +718,6 @@ posix_spawn_growportactions_np(posix_spawnattr_t *attr) { _posix_spawnattr_t psattr; _posix_spawn_port_actions_t acts; - int newnum; if (attr == NULL || *attr == NULL) return EINVAL; @@ -724,8 +728,14 @@ posix_spawn_growportactions_np(posix_spawnattr_t *attr) return EINVAL; /* Double number of port actions allocated for */ - newnum = 2 * acts->pspa_alloc; - acts = realloc(acts, PS_PORT_ACTIONS_SIZE(newnum)); + int newnum = 0; + if (os_mul_overflow(acts->pspa_alloc, 2, &newnum)) + return ENOMEM; + size_t newsize = PS_PORT_ACTIONS_SIZE(newnum); + if (newsize == 0) + return ENOMEM; + + acts = realloc(acts, newsize); if (acts == NULL) return ENOMEM; @@ -1031,8 +1041,13 @@ posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions) static int _posix_spawn_file_actions_grow(_posix_spawn_file_actions_t *psactsp) { - int new_alloc = (*psactsp)->psfa_act_alloc * 2; - _posix_spawn_file_actions_t new_psacts; + int newnum = 0; + if (os_mul_overflow((*psactsp)->psfa_act_alloc, 2, &newnum)) + return ENOMEM; + + size_t newsize = PSF_ACTIONS_SIZE(newnum); + if (newsize == 0) + return ENOMEM; /* * XXX may want to impose an administrative limit here; POSIX does @@ -1040,13 +1055,14 @@ _posix_spawn_file_actions_grow(_posix_spawn_file_actions_t *psactsp) * XXX so it's probably acceptable to just fail catastrophically * XXX instead of implementing one. */ - if ((new_psacts = (_posix_spawn_file_actions_t)realloc((*psactsp), PSF_ACTIONS_SIZE(new_alloc))) == NULL) { - return (ENOMEM); + _posix_spawn_file_actions_t new_psacts; + if ((new_psacts = (_posix_spawn_file_actions_t)realloc((*psactsp), newsize)) == NULL) { + return ENOMEM; } - new_psacts->psfa_act_alloc = new_alloc; + new_psacts->psfa_act_alloc = newnum; *psactsp = new_psacts; - return (0); + return 0; } @@ -1331,6 +1347,95 @@ posix_spawnattr_getcpumonitor(posix_spawnattr_t * __restrict attr, return (0); } +#if TARGET_OS_EMBEDDED +/* + * posix_spawnattr_setjetsam + * + * Description: Set jetsam attributes for the spawn attribute object + * referred to by 'attr'. + * + * Parameters: flags The flags value to set + * priority Relative jetsam priority + * memlimit Value in megabytes; a memory footprint + * above this level may result in termination. + * Implies both active and inactive limits. + * + * Returns: 0 Success + * + * Note: to be deprecated (not available on desktop) + * + */ +int +posix_spawnattr_setjetsam(posix_spawnattr_t * __restrict attr, + short flags, int priority, int memlimit) +{ + short flags_ext = flags; + + if (flags & POSIX_SPAWN_JETSAM_MEMLIMIT_FATAL) { + flags_ext |= POSIX_SPAWN_JETSAM_MEMLIMIT_ACTIVE_FATAL; + flags_ext |= POSIX_SPAWN_JETSAM_MEMLIMIT_INACTIVE_FATAL; + } else { + flags_ext &= ~POSIX_SPAWN_JETSAM_MEMLIMIT_ACTIVE_FATAL; + flags_ext &= ~POSIX_SPAWN_JETSAM_MEMLIMIT_INACTIVE_FATAL; + } + + return (posix_spawnattr_setjetsam_ext(attr, flags_ext, priority, memlimit, memlimit)); +} +#endif /* TARGET_OS_EMBEDDED */ + +/* + * posix_spawnattr_setjetsam_ext + * + * Description: Set jetsam attributes for the spawn attribute object + * referred to by 'attr'. + * + * Parameters: flags The flags value to set + * priority Relative jetsam priority + * memlimit_active Value in megabytes; memory footprint + * above this level while process is + * active may result in termination. + * memlimit_inactive Value in megabytes; memory footprint + * above this level while process is + * inactive may result in termination. + * + * Returns: 0 Success + */ +int +posix_spawnattr_setjetsam_ext(posix_spawnattr_t * __restrict attr, + short flags, int priority, int memlimit_active, int memlimit_inactive) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + + psattr->psa_jetsam_flags = flags; + psattr->psa_jetsam_flags |= POSIX_SPAWN_JETSAM_SET; + psattr->psa_priority = priority; + psattr->psa_memlimit_active = memlimit_active; + psattr->psa_memlimit_inactive = memlimit_inactive; + + return (0); +} + +int +posix_spawnattr_set_threadlimit_ext(posix_spawnattr_t * __restrict attr, + int thread_limit) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + + psattr->psa_thread_limit = thread_limit; + + return (0); + +} /* @@ -1443,10 +1548,16 @@ posix_spawnattr_setmacpolicyinfo_np(posix_spawnattr_t * __restrict attr, psmx->psmx_count = 0; } else if (psmx->psmx_count == psmx->psmx_alloc) { - psmx = psattr->psa_mac_extensions = reallocf(psmx, PS_MAC_EXTENSIONS_SIZE(psmx->psmx_alloc * 2)); + int newnum = 0; + if (os_mul_overflow(psmx->psmx_alloc, 2, &newnum)) + return ENOMEM; + size_t extsize = PS_MAC_EXTENSIONS_SIZE(newnum); + if (extsize == 0) + return ENOMEM; + psmx = psattr->psa_mac_extensions = reallocf(psmx, extsize); if (psmx == NULL) return ENOMEM; - psmx->psmx_alloc *= 2; + psmx->psmx_alloc = newnum; } extension = &psmx->psmx_extensions[psmx->psmx_count]; strlcpy(extension->policyname, policyname, sizeof(extension->policyname)); @@ -1641,7 +1752,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; @@ -1663,7 +1774,20 @@ posix_spawnattr_set_persona_groups_np(const posix_spawnattr_t * __restrict attr, return 0; } +int +posix_spawnattr_set_max_addr_np(const posix_spawnattr_t * __restrict attr, uint64_t max_addr) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) { + return EINVAL; + } + psattr = *(_posix_spawnattr_t *)attr; + psattr->psa_max_addr = max_addr; + + return 0; +} /* * posix_spawn @@ -1729,14 +1853,24 @@ posix_spawn(pid_t * __restrict pid, const char * __restrict path, ad.attrp = psattr; if (psattr->psa_ports != NULL) { + size_t psact_size = PS_PORT_ACTIONS_SIZE(psattr->psa_ports->pspa_count); + if (psact_size == 0 && psattr->psa_ports->pspa_count != 0) { + errno = EINVAL; + ret = -1; + goto out; + } ad.port_actions = psattr->psa_ports; - ad.port_actions_size = PS_PORT_ACTIONS_SIZE( - ad.port_actions->pspa_count); + ad.port_actions_size = psact_size; } if (psattr->psa_mac_extensions != NULL) { + size_t macext_size = PS_MAC_EXTENSIONS_SIZE(psattr->psa_mac_extensions->psmx_count); + if (macext_size == 0 && psattr->psa_mac_extensions->psmx_count != 0) { + errno = EINVAL; + ret = -1; + goto out; + } ad.mac_extensions = psattr->psa_mac_extensions; - ad.mac_extensions_size = PS_MAC_EXTENSIONS_SIZE( - ad.mac_extensions->psmx_count); + ad.mac_extensions_size = macext_size; } if (psattr->psa_coalition_info != NULL) { ad.coal_info_size = sizeof(struct _posix_spawn_coalition_info); @@ -1752,7 +1886,13 @@ posix_spawn(pid_t * __restrict pid, const char * __restrict path, *(_posix_spawn_file_actions_t *)file_actions; if (psactsp->psfa_act_count > 0) { - ad.file_actions_size = PSF_ACTIONS_SIZE(psactsp->psfa_act_count); + size_t fa_size = PSF_ACTIONS_SIZE(psactsp->psfa_act_count); + if (fa_size == 0 && psactsp->psfa_act_count != 0) { + errno = EINVAL; + ret = -1; + goto out; + } + ad.file_actions_size = fa_size; ad.file_actions = psactsp; } } @@ -1761,6 +1901,7 @@ posix_spawn(pid_t * __restrict pid, const char * __restrict path, } else ret = __posix_spawn(pid, path, NULL, argv, envp); +out: if (ret < 0) ret = errno; errno = saveerrno;