From 7a22f034ba38e9f517788a2d562f7e68de3e0bb0 Mon Sep 17 00:00:00 2001 From: Apple Date: Wed, 13 Jul 2016 22:45:36 +0000 Subject: [PATCH] libdispatch-501.40.12.tar.gz --- config/config.h | 4 + configure.ac | 2 +- libdispatch.xcodeproj/project.pbxproj | 2 + private/source_private.h | 4 + private/voucher_private.h | 92 ++++++++++++- src/init.c | 3 + src/source.c | 3 + src/voucher.c | 184 +++++++++++++++++++++----- 8 files changed, 258 insertions(+), 36 deletions(-) diff --git a/config/config.h b/config/config.h index 8944281..cac6ac9 100644 --- a/config/config.h +++ b/config/config.h @@ -45,6 +45,10 @@ you don't. */ #define HAVE_DECL_VQ_VERYLOWDISK 1 +/* Define to 1 if you have the declaration of `VQ_QUOTA', and to 0 if + you don't. */ +#define HAVE_DECL_VQ_QUOTA 1 + /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 diff --git a/configure.ac b/configure.ac index 223084c..d0b626d 100644 --- a/configure.ac +++ b/configure.ac @@ -212,7 +212,7 @@ AC_CHECK_DECLS([NOTE_NONE, NOTE_REAP, NOTE_SIGNAL], [], [], [[#include ]]) AC_CHECK_DECLS([FD_COPY], [], [], [[#include ]]) AC_CHECK_DECLS([SIGEMT], [], [], [[#include ]]) -AC_CHECK_DECLS([VQ_UPDATE, VQ_VERYLOWDISK], [], [], [[#include ]]) +AC_CHECK_DECLS([VQ_UPDATE, VQ_VERYLOWDISK, VQ_QUOTA], [], [], [[#include ]]) AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include ]]) AC_CHECK_FUNCS([pthread_key_init_np pthread_main_np mach_absolute_time malloc_create_zone sysconf getprogname]) diff --git a/libdispatch.xcodeproj/project.pbxproj b/libdispatch.xcodeproj/project.pbxproj index 898ffca..230d5a0 100644 --- a/libdispatch.xcodeproj/project.pbxproj +++ b/libdispatch.xcodeproj/project.pbxproj @@ -696,6 +696,7 @@ 5AAB45BF10D30B79004407EA /* data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = data.c; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.c; }; 5AAB45C310D30CC7004407EA /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = ""; tabWidth = 8; }; 5AAB45C510D30D0C004407EA /* data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = data.h; sourceTree = ""; tabWidth = 8; }; + 6E4130C91B431697001A152D /* backward-compat.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "backward-compat.xcconfig"; sourceTree = ""; }; 721F5C5C0F15520500FF03A6 /* semaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = semaphore.h; sourceTree = ""; }; 721F5CCE0F15553500FF03A6 /* semaphore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = semaphore.c; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.c; }; 72B54F690EB169EB00DBECBA /* dispatch_source_create.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dispatch_source_create.3; sourceTree = ""; }; @@ -974,6 +975,7 @@ E40041E4125E71150022B135 /* xcodeconfig */ = { isa = PBXGroup; children = ( + 6E4130C91B431697001A152D /* backward-compat.xcconfig */, E43D93F11097917E004F6A62 /* libdispatch.xcconfig */, E40041AA125D705F0022B135 /* libdispatch-resolver.xcconfig */, E40041A9125D70590022B135 /* libdispatch-resolved.xcconfig */, diff --git a/private/source_private.h b/private/source_private.h index e8373ba..2c76824 100644 --- a/private/source_private.h +++ b/private/source_private.h @@ -200,6 +200,9 @@ enum { * * @constant DISPATCH_VFS_VERYLOWDISK * File system has *very* little disk space left. + * + * @constant DISPATCH_VFS_QUOTA + * We hit a user quota (quotactl) for this filesystem. */ enum { DISPATCH_VFS_NOTRESP = 0x0001, @@ -212,6 +215,7 @@ enum { DISPATCH_VFS_NOTRESPLOCK = 0x0080, DISPATCH_VFS_UPDATE = 0x0100, DISPATCH_VFS_VERYLOWDISK = 0x0200, + DISPATCH_VFS_QUOTA = 0x1000, }; /*! diff --git a/private/voucher_private.h b/private/voucher_private.h index e4c31a6..2640344 100644 --- a/private/voucher_private.h +++ b/private/voucher_private.h @@ -24,7 +24,7 @@ #include #include -#define OS_VOUCHER_SPI_VERSION 20141203 +#define OS_VOUCHER_SPI_VERSION 20150630 #if OS_VOUCHER_WEAK_IMPORT #define OS_VOUCHER_EXPORT OS_EXPORT OS_WEAK_IMPORT @@ -424,6 +424,96 @@ OS_VOUCHER_EXPORT OS_OBJECT_RETURNS_RETAINED OS_WARN_RESULT OS_NOTHROW voucher_t voucher_create_with_mach_msg(mach_msg_header_t *msg); +/*! + * @group Voucher Persona SPI + * SPI intended for clients that need to interact with personas. + */ + +#if __has_include() +#include +#endif +#if __has_include() +#include +#endif + +struct proc_persona_info; + +/*! + * @function voucher_get_current_persona + * + * @abstract + * Retrieve the persona identifier of the 'originator' process for the current + * voucher. + * + * @discussion + * Retrieve the persona identifier of the ’originator’ process possibly stored + * in the PERSONA_TOKEN attribute of the currently adopted voucher. + * + * If the thread has not adopted a voucher, or the current voucher does not + * contain a PERSONA_TOKEN attribute, this function returns the persona + * identifier of the current process. + * + * If the process is not running under a persona, then this returns + * PERSONA_ID_NONE. + * + * @result + * The persona identifier of the 'originator' process for the current voucher, + * or the persona identifier of the current process + * or PERSONA_ID_NONE + */ +__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_9_2) +OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW +uid_t +voucher_get_current_persona(void); + +/*! + * @function voucher_get_current_persona_originator_info + * + * @abstract + * Retrieve the ’originator’ process persona info for the currently adopted + * voucher. + * + * @discussion + * If there is no currently adopted voucher, or no PERSONA_TOKEN attribute + * in that voucher, this function fails. + * + * @param persona_info + * The proc_persona_info structure to fill in case of success + * + * @result + * 0 on success: currently adopted voucher has a PERSONA_TOKEN + * -1 on failure: persona_info is untouched/uninitialized + */ +__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_9_2) +OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL1 +int +voucher_get_current_persona_originator_info( + struct proc_persona_info *persona_info); + +/*! + * @function voucher_get_current_persona_proximate_info + * + * @abstract + * Retrieve the ’proximate’ process persona info for the currently adopted + * voucher. + * + * @discussion + * If there is no currently adopted voucher, or no PERSONA_TOKEN attribute + * in that voucher, this function fails. + * + * @param persona_info + * The proc_persona_info structure to fill in case of success + * + * @result + * 0 on success: currently adopted voucher has a PERSONA_TOKEN + * -1 on failure: persona_info is untouched/uninitialized + */ +__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_9_2) +OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL1 +int +voucher_get_current_persona_proximate_info( + struct proc_persona_info *persona_info); + __END_DECLS #endif // __OS_VOUCHER_PRIVATE__ diff --git a/src/init.c b/src/init.c index 0aff191..7cfa8dc 100644 --- a/src/init.c +++ b/src/init.c @@ -1176,6 +1176,9 @@ const struct dispatch_source_type_s _dispatch_source_type_vfs = { #endif #if HAVE_DECL_VQ_VERYLOWDISK |VQ_VERYLOWDISK +#endif +#if HAVE_DECL_VQ_QUOTA + |VQ_QUOTA #endif , }; diff --git a/src/source.c b/src/source.c index dde7db9..430c7af 100644 --- a/src/source.c +++ b/src/source.c @@ -4559,11 +4559,14 @@ dispatch_mig_server(dispatch_source_t ds, size_t maxmsgsz, bufReply = bufTemp; #if DISPATCH_USE_IMPORTANCE_ASSERTION +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" int r = proc_importance_assertion_begin_with_msg(&bufRequest->Head, NULL, &assertion_token); if (r && slowpath(r != EIO)) { (void)dispatch_assume_zero(r); } +#pragma clang diagnostic pop #endif _voucher_replace(voucher_create_with_mach_msg(&bufRequest->Head)); demux_success = callback(&bufRequest->Head, &bufReply->Head); diff --git a/src/voucher.c b/src/voucher.c index 6967f19..7489e77 100644 --- a/src/voucher.c +++ b/src/voucher.c @@ -20,9 +20,22 @@ #include "internal.h" +#if !defined(VOUCHER_EXPORT_PERSONA_SPI) +#if TARGET_OS_IPHONE +#define VOUCHER_EXPORT_PERSONA_SPI 1 +#else +#define VOUCHER_EXPORT_PERSONA_SPI 0 +#endif +#endif + +#ifndef PERSONA_ID_NONE +#define PERSONA_ID_NONE ((uid_t)-1) +#endif + #if VOUCHER_USE_MACH_VOUCHER #include +#include // #ifndef VM_MEMORY_GENEALOGY @@ -273,6 +286,15 @@ _voucher_create_mach_voucher(const mach_voucher_attr_recipe_data_t *recipes, mach_voucher_t _voucher_default_task_mach_voucher; #endif +#if !defined(VOUCHER_USE_PERSONA) +#if VOUCHER_USE_ATTR_BANK && defined(BANK_PERSONA_TOKEN) && \ + !TARGET_IPHONE_SIMULATOR +#define VOUCHER_USE_PERSONA 1 +#else +#define VOUCHER_USE_PERSONA 0 +#endif +#endif + void _voucher_task_mach_voucher_init(void* ctxt DISPATCH_UNUSED) { @@ -355,9 +377,10 @@ _voucher_get_mach_voucher(voucher_t voucher) _voucher_base_recipe(voucher).previous_voucher = kvb; _voucher_atm_recipe(voucher).previous_voucher = _voucher_get_atm_mach_voucher(voucher); - kr = _voucher_create_mach_voucher(voucher->v_recipes, - _voucher_recipes_size() + _voucher_extra_size(voucher) + - _voucher_bits_recipe(voucher).content_size, &kv); + size_t recipes_size = _voucher_recipes_size() + + _voucher_extra_size(voucher) + + _voucher_bits_recipe(voucher).content_size; + kr = _voucher_create_mach_voucher(voucher->v_recipes, recipes_size, &kv); if (dispatch_assume_zero(kr) || !kv){ return MACH_VOUCHER_NULL; } @@ -418,42 +441,20 @@ _voucher_create_with_mach_voucher(mach_voucher_t kv) { if (!kv) return NULL; kern_return_t kr; - mach_voucher_t rkv; mach_voucher_attr_recipe_t vr; size_t vr_size; mach_voucher_attr_recipe_size_t kvr_size = 0; - const mach_voucher_attr_recipe_data_t redeem_recipe[] = { - [0] = { - .key = MACH_VOUCHER_ATTR_KEY_ALL, - .command = MACH_VOUCHER_ATTR_COPY, - .previous_voucher = kv, - }, -#if VOUCHER_USE_ATTR_BANK - [1] = { - .key = MACH_VOUCHER_ATTR_KEY_BANK, - .command = MACH_VOUCHER_ATTR_REDEEM, - }, -#endif - }; - kr = _voucher_create_mach_voucher(redeem_recipe, sizeof(redeem_recipe), - &rkv); - if (!dispatch_assume_zero(kr)) { - _voucher_dealloc_mach_voucher(kv); - } else { - _dispatch_voucher_debug_machport(kv); - rkv = kv; - } - voucher_t v = _voucher_find_and_retain(rkv); + voucher_t v = _voucher_find_and_retain(kv); if (v) { - _dispatch_voucher_debug("kvoucher[0x%08x] find with 0x%08x", v, rkv,kv); - _voucher_dealloc_mach_voucher(rkv); + _dispatch_voucher_debug("kvoucher[0x%08x] found", v, kv); + _voucher_dealloc_mach_voucher(kv); return v; } vr_size = sizeof(*vr) + _voucher_bits_size(_voucher_max_activities); vr = alloca(vr_size); - if (rkv) { + if (kv) { kvr_size = (mach_voucher_attr_recipe_size_t)vr_size; - kr = mach_voucher_extract_attr_recipe(rkv, + kr = mach_voucher_extract_attr_recipe(kv, MACH_VOUCHER_ATTR_KEY_USER_DATA, (void*)vr, &kvr_size); DISPATCH_VERIFY_MIG(kr); if (dispatch_assume_zero(kr)) kvr_size = 0; @@ -483,7 +484,7 @@ _voucher_create_with_mach_voucher(mach_voucher_t kv) _voucher_atm_t vatm = NULL; if (activities) { va_id = *(voucher_activity_id_t*)content; - act = _voucher_activity_copy_from_mach_voucher(rkv, va_id); + act = _voucher_activity_copy_from_mach_voucher(kv, va_id); if (!act && _voucher_activity_default) { activities++; // default to _voucher_activity_default base activity @@ -507,9 +508,9 @@ _voucher_create_with_mach_voucher(mach_voucher_t kv) if (activities) { memcpy(activity_ids, content, content_size); } - v->v_ipc_kvoucher = v->v_kvoucher = rkv; + v->v_ipc_kvoucher = v->v_kvoucher = kv; _voucher_insert(v); - _dispatch_voucher_debug("kvoucher[0x%08x] create with 0x%08x", v, rkv, kv); + _dispatch_voucher_debug("kvoucher[0x%08x] create", v, kv); return v; } @@ -780,6 +781,92 @@ _voucher_atfork_child(void) // TODO: voucher/activity inheritance on fork ? } +#if VOUCHER_EXPORT_PERSONA_SPI +#if VOUCHER_USE_PERSONA +static kern_return_t +_voucher_get_current_persona_token(struct persona_token *token) +{ + kern_return_t kr = KERN_FAILURE; + voucher_t v = _voucher_get(); + + if (v && v->v_kvoucher) { + mach_voucher_t kv = v->v_ipc_kvoucher ?: v->v_kvoucher; + mach_voucher_attr_content_t kvc_in = NULL; + mach_voucher_attr_content_size_t kvc_in_size = 0; + mach_voucher_attr_content_t kvc_out = + (mach_voucher_attr_content_t)token; + mach_voucher_attr_content_size_t kvc_out_size = sizeof(*token); + + kr = mach_voucher_attr_command(kv, MACH_VOUCHER_ATTR_KEY_BANK, + BANK_PERSONA_TOKEN, kvc_in, kvc_in_size, + kvc_out, &kvc_out_size); + if (kr != KERN_NOT_SUPPORTED + // Voucher doesn't have a PERSONA_TOKEN + && kr != KERN_INVALID_VALUE + // Kernel doesn't understand BANK_PERSONA_TOKEN + && kr != KERN_INVALID_ARGUMENT) { + (void)dispatch_assume_zero(kr); + } + } + return kr; +} +#endif + +uid_t +voucher_get_current_persona(void) +{ + uid_t persona_id = PERSONA_ID_NONE; + +#if VOUCHER_USE_PERSONA + struct persona_token token; + int err; + + if (_voucher_get_current_persona_token(&token) == KERN_SUCCESS) { + return token.originator.persona_id; + } + + // falling back to the process persona if there is no adopted voucher + if (kpersona_get(&persona_id) < 0) { + err = errno; + if (err != ESRCH) { + (void)dispatch_assume_zero(err); + } + } +#endif + return persona_id; +} + +int +voucher_get_current_persona_originator_info(struct proc_persona_info *persona_info) +{ +#if VOUCHER_USE_PERSONA + struct persona_token token; + if (_voucher_get_current_persona_token(&token) == KERN_SUCCESS) { + *persona_info = token.originator; + return 0; + } +#else + (void)persona_info; +#endif + return -1; +} + +int +voucher_get_current_persona_proximate_info(struct proc_persona_info *persona_info) +{ +#if VOUCHER_USE_PERSONA + struct persona_token token; + if (_voucher_get_current_persona_token(&token) == KERN_SUCCESS) { + *persona_info = token.proximate; + return 0; + } +#else + (void)persona_info; +#endif + return -1; +} +#endif + #pragma mark - #pragma mark _voucher_init @@ -991,7 +1078,7 @@ _voucher_heap_buffer_limit() return _voucher_activity_buffers_per_heap; } #if TARGET_OS_EMBEDDED - // Low-profile modes: 3 activities, each of which can use 2 buffers; + // Low-profile modes: 3 activities, each of which can use 2 buffers; // plus the default activity, which can use 3; plus 3 buffers of overhead. return 12; #else @@ -2416,6 +2503,13 @@ _voucher_dealloc_mach_voucher(mach_voucher_t kv) (void)kv; } +mach_voucher_t +_voucher_get_mach_voucher(voucher_t voucher) +{ + (void)voucher; + return MACH_VOUCHER_NULL; +} + mach_voucher_t _voucher_create_mach_voucher_with_priority(voucher_t voucher, pthread_priority_t priority) @@ -2467,6 +2561,28 @@ _voucher_dispose(voucher_t voucher) (void)voucher; } +#if VOUCHER_EXPORT_PERSONA_SPI +uid_t +voucher_get_current_persona(void) +{ + return PERSONA_ID_NONE; +} + +int +voucher_get_current_persona_originator_info(struct proc_persona_info *persona_info) +{ + (void)persona_info; + return -1; +} + +int +voucher_get_current_persona_proximate_info(struct proc_persona_info *persona_info) +{ + (void)persona_info; + return -1; +} +#endif + void _voucher_atfork_child(void) { -- 2.45.2