X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/39236c6e673c41db228275375ab7fdb0f837b292..eee3565979933af707c711411001ba11fe406a3c:/libsyscall/wrappers/spawn/posix_spawn.c diff --git a/libsyscall/wrappers/spawn/posix_spawn.c b/libsyscall/wrappers/spawn/posix_spawn.c index 3d8369be0..be3e94cea 100644 --- a/libsyscall/wrappers/spawn/posix_spawn.c +++ b/libsyscall/wrappers/spawn/posix_spawn.c @@ -38,10 +38,8 @@ #include #include #include - -#if TARGET_OS_EMBEDDED +#include /* for COALITION_TYPE_MAX */ #include -#endif /* * posix_spawnattr_init @@ -115,19 +113,15 @@ posix_spawnattr_init(posix_spawnattr_t *attr) (*psattrp)->short_padding = 0; (*psattrp)->flags_padding = 0; - (*psattrp)->int_padding = 0; - - /* - * The default value of this attribute shall be an no - * process control on resource starvation - */ - (*psattrp)->psa_apptype = 0; + /* Default is no new apptype requested */ + (*psattrp)->psa_apptype = POSIX_SPAWN_PROCESS_TYPE_DEFAULT; /* Jetsam related */ (*psattrp)->psa_jetsam_flags = 0; (*psattrp)->psa_priority = -1; - (*psattrp)->psa_high_water_mark = -1; + (*psattrp)->psa_memlimit_active = -1; + (*psattrp)->psa_memlimit_inactive = -1; /* Default is no CPU usage monitor active. */ (*psattrp)->psa_cpumonitor_percent = 0; @@ -135,6 +129,27 @@ posix_spawnattr_init(posix_spawnattr_t *attr) /* Default is no MAC policy extensions. */ (*psattrp)->psa_mac_extensions = NULL; + + /* Default is to inherit parent's coalition(s) */ + (*psattrp)->psa_coalition_info = NULL; + + (*psattrp)->psa_persona_info = NULL; + + /* + * old coalition field + * For backwards compatibility reasons, we set this to 1 + * which is the first valid coalition id. This will allow + * newer user space code to properly spawn processes on + * older kernels + * (they will just all end up in the same coalition). + */ + (*psattrp)->psa_reserved = 1; + + /* Default is no new clamp */ + (*psattrp)->psa_qos_clamp = POSIX_SPAWN_PROC_CLAMP_NONE; + + /* Default is no change to role */ + (*psattrp)->psa_darwin_role = POSIX_SPAWN_DARWIN_ROLE_NONE; } return (err); @@ -162,6 +177,8 @@ posix_spawnattr_init(posix_spawnattr_t *attr) * EINVAL The value specified by attr is invalid. */ static int posix_spawn_destroyportactions_np(posix_spawnattr_t *); +static int posix_spawn_destroycoalition_info_np(posix_spawnattr_t *); +static int posix_spawn_destroypersona_info_np(posix_spawnattr_t *); int posix_spawnattr_destroy(posix_spawnattr_t *attr) @@ -173,6 +190,8 @@ posix_spawnattr_destroy(posix_spawnattr_t *attr) psattr = *(_posix_spawnattr_t *)attr; posix_spawn_destroyportactions_np(attr); + posix_spawn_destroycoalition_info_np(attr); + posix_spawn_destroypersona_info_np(attr); free(psattr); *attr = NULL; @@ -737,6 +756,52 @@ posix_spawn_destroyportactions_np(posix_spawnattr_t *attr) return 0; } +/* + * posix_spawn_destroycoalition_info_np + * Description: clean up coalition_info struct in posix_spawnattr_t attr + */ +static int +posix_spawn_destroycoalition_info_np(posix_spawnattr_t *attr) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_coalition_info *coal_info; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + coal_info = psattr->psa_coalition_info; + if (coal_info == NULL) + return EINVAL; + + psattr->psa_coalition_info = NULL; + free(coal_info); + return 0; +} + +/* + * posix_spawn_destroypersona_info_np + * Description: clean up persona_info struct in posix_spawnattr_t attr + */ +static int +posix_spawn_destroypersona_info_np(posix_spawnattr_t *attr) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + persona = psattr->psa_persona_info; + if (persona == NULL) + return EINVAL; + + psattr->psa_persona_info = NULL; + free(persona); + return 0; +} + /* * posix_spawn_appendportaction_np * Description: append a port action, grow the array if necessary @@ -1266,24 +1331,27 @@ posix_spawnattr_getcpumonitor(posix_spawnattr_t * __restrict attr, return (0); } -#if TARGET_OS_EMBEDDED + /* - * posix_spawnattr_setjetsam + * 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 - * high_water_mark Value in pages; resident page - * counts above this level can - * result in termination + * 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(posix_spawnattr_t * __restrict attr, - short flags, int priority, int high_water_mark) +posix_spawnattr_setjetsam_ext(posix_spawnattr_t * __restrict attr, + short flags, int priority, int memlimit_active, int memlimit_inactive) { _posix_spawnattr_t psattr; @@ -1291,15 +1359,15 @@ posix_spawnattr_setjetsam(posix_spawnattr_t * __restrict attr, 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_high_water_mark = high_water_mark; + psattr->psa_memlimit_active = memlimit_active; + psattr->psa_memlimit_inactive = memlimit_inactive; return (0); } -#endif /* @@ -1379,8 +1447,9 @@ posix_spawnattr_getmacpolicyinfo_np(const posix_spawnattr_t * __restrict attr, if (extension == NULL) return ESRCH; *datap = (void *)(uintptr_t)extension->data; - if (datalenp != NULL) - *datalenp = extension->datalen; + if (datalenp != NULL) { + *datalenp = (size_t)extension->datalen; + } return 0; } @@ -1424,6 +1493,215 @@ posix_spawnattr_setmacpolicyinfo_np(posix_spawnattr_t * __restrict attr, return 0; } +int posix_spawnattr_setcoalition_np(const posix_spawnattr_t * __restrict attr, + uint64_t coalitionid, int type, int role) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_coalition_info *coal_info; + + if (attr == NULL || *attr == NULL) { + return EINVAL; + } + if (type < 0 || type > COALITION_TYPE_MAX) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + + coal_info = psattr->psa_coalition_info; + if (!coal_info) { + coal_info = (struct _posix_spawn_coalition_info *)malloc(sizeof(*coal_info)); + if (!coal_info) + return ENOMEM; + memset(coal_info, 0, sizeof(*coal_info)); + psattr->psa_coalition_info = coal_info; + } + + coal_info->psci_info[type].psci_id = coalitionid; + coal_info->psci_info[type].psci_role = role; + + return 0; +} + + +int posix_spawnattr_set_qos_clamp_np(const posix_spawnattr_t * __restrict attr, uint64_t qos_clamp) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) { + return EINVAL; + } + + if (qos_clamp >= POSIX_SPAWN_PROC_CLAMP_LAST) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + psattr->psa_qos_clamp = qos_clamp; + + return 0; +} + +int +posix_spawnattr_get_qos_clamp_np(const posix_spawnattr_t * __restrict attr, uint64_t * __restrict qos_clampp) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) { + return EINVAL; + } + + psattr = *(_posix_spawnattr_t *)attr; + *qos_clampp = psattr->psa_qos_clamp; + + return (0); +} + +int posix_spawnattr_set_darwin_role_np(const posix_spawnattr_t * __restrict attr, uint64_t darwin_role) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) { + return EINVAL; + } + + psattr = *(_posix_spawnattr_t *)attr; + psattr->psa_darwin_role = darwin_role; + + return 0; +} + +int +posix_spawnattr_get_darwin_role_np(const posix_spawnattr_t * __restrict attr, uint64_t * __restrict darwin_rolep) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) { + return EINVAL; + } + + psattr = *(_posix_spawnattr_t *)attr; + *darwin_rolep = psattr->psa_darwin_role; + + return (0); +} + + +int +posix_spawnattr_set_persona_np(const posix_spawnattr_t * __restrict attr, uid_t persona_id, uint32_t flags) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + if (flags & ~POSIX_SPAWN_PERSONA_ALL_FLAGS) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + + persona = psattr->psa_persona_info; + if (!persona) { + persona = (struct _posix_spawn_persona_info *)malloc(sizeof(*persona)); + if (!persona) + return ENOMEM; + persona->pspi_uid = 0; + persona->pspi_gid = 0; + persona->pspi_ngroups = 0; + persona->pspi_groups[0] = 0; + + psattr->psa_persona_info = persona; + } + + persona->pspi_id = persona_id; + persona->pspi_flags = flags; + + return 0; +} + +int +posix_spawnattr_set_persona_uid_np(const posix_spawnattr_t * __restrict attr, uid_t uid) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + persona = psattr->psa_persona_info; + if (!persona) + return EINVAL; + + if (!(persona->pspi_flags & (POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE | POSIX_SPAWN_PERSONA_FLAGS_VERIFY))) + return EINVAL; + + persona->pspi_uid = uid; + + persona->pspi_flags |= POSIX_SPAWN_PERSONA_UID; + + return 0; +} + +int +posix_spawnattr_set_persona_gid_np(const posix_spawnattr_t * __restrict attr, gid_t gid) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + persona = psattr->psa_persona_info; + if (!persona) + return EINVAL; + + if (!(persona->pspi_flags & (POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE | POSIX_SPAWN_PERSONA_FLAGS_VERIFY))) + return EINVAL; + + persona->pspi_gid = gid; + + persona->pspi_flags |= POSIX_SPAWN_PERSONA_GID; + + return 0; +} + +int +posix_spawnattr_set_persona_groups_np(const posix_spawnattr_t * __restrict attr, int ngroups, gid_t *gidarray, uid_t gmuid) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + if (gidarray == NULL) + return EINVAL; + + if (ngroups > NGROUPS) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + persona = psattr->psa_persona_info; + if (!persona) + return EINVAL; + + if (!(persona->pspi_flags & (POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE | POSIX_SPAWN_PERSONA_FLAGS_VERIFY))) + return EINVAL; + + persona->pspi_ngroups = ngroups; + for (int i = 0; i < ngroups; i++) + persona->pspi_groups[i] = gidarray[i]; + + persona->pspi_gmuid = gmuid; + + persona->pspi_flags |= POSIX_SPAWN_PERSONA_GROUPS; + + return 0; +} + + + /* * posix_spawn * @@ -1497,6 +1775,14 @@ posix_spawn(pid_t * __restrict pid, const char * __restrict path, ad.mac_extensions_size = PS_MAC_EXTENSIONS_SIZE( ad.mac_extensions->psmx_count); } + if (psattr->psa_coalition_info != NULL) { + ad.coal_info_size = sizeof(struct _posix_spawn_coalition_info); + ad.coal_info = psattr->psa_coalition_info; + } + if (psattr->psa_persona_info != NULL) { + ad.persona_info_size = sizeof(struct _posix_spawn_persona_info); + ad.persona_info = psattr->psa_persona_info; + } } if (file_actions != NULL && *file_actions != NULL) { _posix_spawn_file_actions_t psactsp =