]> git.saurik.com Git - apple/libdispatch.git/commitdiff
libdispatch-501.40.12.tar.gz os-x-10114 os-x-10115 os-x-10116 v501.40.12
authorApple <opensource@apple.com>
Wed, 13 Jul 2016 22:45:36 +0000 (22:45 +0000)
committerApple <opensource@apple.com>
Wed, 13 Jul 2016 22:45:36 +0000 (22:45 +0000)
config/config.h
configure.ac
libdispatch.xcodeproj/project.pbxproj
private/source_private.h
private/voucher_private.h
src/init.c
src/source.c
src/voucher.c

index 894428199c6f542c4ac72cadf852df54566ae0a1..cac6ac91d0e786dd36ccef446324ebc8c232dc24 100644 (file)
    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 <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
 
index 223084c615b4157e39c72ffb66fb22df8f50eacd..d0b626d68b1f8620b76a764c42eef62e03fd5694 100644 (file)
@@ -212,7 +212,7 @@ AC_CHECK_DECLS([NOTE_NONE, NOTE_REAP, NOTE_SIGNAL], [], [],
   [[#include <sys/event.h>]])
 AC_CHECK_DECLS([FD_COPY], [], [], [[#include <sys/select.h>]])
 AC_CHECK_DECLS([SIGEMT], [], [], [[#include <signal.h>]])
-AC_CHECK_DECLS([VQ_UPDATE, VQ_VERYLOWDISK], [], [], [[#include <sys/mount.h>]])
+AC_CHECK_DECLS([VQ_UPDATE, VQ_VERYLOWDISK, VQ_QUOTA], [], [], [[#include <sys/mount.h>]])
 AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
 AC_CHECK_FUNCS([pthread_key_init_np pthread_main_np mach_absolute_time malloc_create_zone sysconf getprogname])
 
index 898ffcaf9f17350ab255298778fd57cb87289f0c..230d5a0a6ea19e3564039a758dde35397380b4a7 100644 (file)
                5AAB45BF10D30B79004407EA /* data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = data.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
                5AAB45C310D30CC7004407EA /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = "<group>"; tabWidth = 8; };
                5AAB45C510D30D0C004407EA /* data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = data.h; sourceTree = "<group>"; tabWidth = 8; };
+               6E4130C91B431697001A152D /* backward-compat.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "backward-compat.xcconfig"; sourceTree = "<group>"; };
                721F5C5C0F15520500FF03A6 /* semaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = semaphore.h; sourceTree = "<group>"; };
                721F5CCE0F15553500FF03A6 /* semaphore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = semaphore.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
                72B54F690EB169EB00DBECBA /* dispatch_source_create.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dispatch_source_create.3; sourceTree = "<group>"; };
                E40041E4125E71150022B135 /* xcodeconfig */ = {
                        isa = PBXGroup;
                        children = (
+                               6E4130C91B431697001A152D /* backward-compat.xcconfig */,
                                E43D93F11097917E004F6A62 /* libdispatch.xcconfig */,
                                E40041AA125D705F0022B135 /* libdispatch-resolver.xcconfig */,
                                E40041A9125D70590022B135 /* libdispatch-resolved.xcconfig */,
index e8373ba26cb0d3cc8e4f9351d1ea340be886916c..2c768242bfa1b1b7d8204b8a73f95d623c325293 100644 (file)
@@ -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,
 };
 
 /*!
index e4c31a6967f11a967a1ae51c7efa17ccb6c49528..26403445d1c71c8c000bac450eb3b78a1730bf34 100644 (file)
@@ -24,7 +24,7 @@
 #include <os/base.h>
 #include <os/object.h>
 
-#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(<bank/bank_types.h>)
+#include <bank/bank_types.h>
+#endif
+#if __has_include(<sys/persona.h>)
+#include <sys/persona.h>
+#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__
index 0aff191f0e6fc31e3128e3095c50c02677c2b1b8..7cfa8dc88738be6d627b1ccffe58ce46e82342a9 100644 (file)
@@ -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
                        ,
 };
index dde7db9afff84600c8c5104529e2bd2555d720c0..430c7af0df7252177d7f857d9852ecf1a409b2ef 100644 (file)
@@ -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);
index 6967f19c1a561700c69bb9cf21d192dd1e7f2f6a..7489e7761eddf02aa31714d02eb68511c0fff7e2 100644 (file)
 
 #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 <mach/mach_voucher.h>
+#include <sys/kauth.h>
 
 // <rdar://16363550>
 #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)
 {