]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_cs.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / bsd / kern / kern_cs.c
index c6ab1e5bf086fef758f2c295acde1b4007112f3f..5da291b6a1310f99a7650def588f00273902be10 100644 (file)
 #include <mach/mach_vm.h>
 
 #include <kern/kern_types.h>
+#include <kern/startup.h>
 #include <kern/task.h>
 
 #include <vm/vm_map.h>
+#include <vm/pmap.h>
 #include <vm/vm_kern.h>
 
 
@@ -72,6 +74,8 @@
 #include <mach/shared_region.h>
 
 #include <libkern/section_keywords.h>
+#include <libkern/ptrauth_utils.h>
+
 
 unsigned long cs_procs_killed = 0;
 unsigned long cs_procs_invalidated = 0;
@@ -85,7 +89,22 @@ int cs_debug_fail_on_unsigned_code = 0;
 unsigned int cs_debug_unsigned_exec_failures = 0;
 unsigned int cs_debug_unsigned_mmap_failures = 0;
 
+#if CONFIG_ENFORCE_SIGNED_CODE
+#define DEFAULT_CS_SYSTEM_ENFORCEMENT_ENABLE 1
+#define DEFAULT_CS_PROCESS_ENFORCEMENT_ENABLE 1
+#else
+#define DEFAULT_CS_SYSTEM_ENFORCEMENT_ENABLE 1
+#define DEFAULT_CS_PROCESS_ENFORCEMENT_ENABLE 0
+#endif
+
+#if CONFIG_ENFORCE_LIBRARY_VALIDATION
+#define DEFAULT_CS_LIBRARY_VA_ENABLE 1
+#else
+#define DEFAULT_CS_LIBRARY_VA_ENABLE 0
+#endif
+
 #if SECURE_KERNEL
+
 /*
  *  Here we split cs_enforcement_enable into cs_system_enforcement_enable and cs_process_enforcement_enable
  *
@@ -99,35 +118,22 @@ unsigned int cs_debug_unsigned_mmap_failures = 0;
  *  (On iOS and related, both of these are set by default. On macOS, only cs_system_enforcement_enable
  *  is set by default. Processes can then be opted into code signing enforcement on a case by case basis.)
  */
-const int cs_system_enforcement_enable = 1;
-const int cs_process_enforcement_enable = 1;
-const int cs_library_val_enable = 1;
+SECURITY_READ_ONLY_EARLY(int) cs_system_enforcement_enable = DEFAULT_CS_SYSTEM_ENFORCEMENT_ENABLE;
+SECURITY_READ_ONLY_EARLY(int) cs_process_enforcement_enable = DEFAULT_CS_PROCESS_ENFORCEMENT_ENABLE;
+SECURITY_READ_ONLY_EARLY(int) cs_library_val_enable = DEFAULT_CS_LIBRARY_VA_ENABLE;
+
 #else /* !SECURE_KERNEL */
 int cs_enforcement_panic = 0;
 int cs_relax_platform_task_ports = 0;
 
-#if CONFIG_ENFORCE_SIGNED_CODE
-#define DEFAULT_CS_SYSTEM_ENFORCEMENT_ENABLE 1
-#define DEFAULT_CS_PROCESS_ENFORCEMENT_ENABLE 1
-#else
-#define DEFAULT_CS_SYSTEM_ENFORCEMENT_ENABLE 1
-#define DEFAULT_CS_PROCESS_ENFORCEMENT_ENABLE 0
-#endif
 SECURITY_READ_ONLY_LATE(int) cs_system_enforcement_enable = DEFAULT_CS_SYSTEM_ENFORCEMENT_ENABLE;
 SECURITY_READ_ONLY_LATE(int) cs_process_enforcement_enable = DEFAULT_CS_PROCESS_ENFORCEMENT_ENABLE;
 
-#if CONFIG_ENFORCE_LIBRARY_VALIDATION
-#define DEFAULT_CS_LIBRARY_VA_ENABLE 1
-#else
-#define DEFAULT_CS_LIBRARY_VA_ENABLE 0
-#endif
 SECURITY_READ_ONLY_LATE(int) cs_library_val_enable = DEFAULT_CS_LIBRARY_VA_ENABLE;
 
 #endif /* !SECURE_KERNEL */
 int cs_all_vnodes = 0;
 
-static lck_grp_t *cs_lockgrp;
-
 SYSCTL_INT(_vm, OID_AUTO, cs_force_kill, CTLFLAG_RW | CTLFLAG_LOCKED, &cs_force_kill, 0, "");
 SYSCTL_INT(_vm, OID_AUTO, cs_force_hard, CTLFLAG_RW | CTLFLAG_LOCKED, &cs_force_hard, 0, "");
 SYSCTL_INT(_vm, OID_AUTO, cs_debug, CTLFLAG_RW | CTLFLAG_LOCKED, &cs_debug, 0, "");
@@ -152,7 +158,8 @@ SYSCTL_INT(_vm, OID_AUTO, cs_library_validation, CTLFLAG_RD | CTLFLAG_LOCKED, &c
 
 int panic_on_cs_killed = 0;
 
-void
+__startup_func
+static void
 cs_init(void)
 {
 #if MACH_ASSERT
@@ -186,11 +193,8 @@ cs_init(void)
            sizeof(cs_library_val_enable));
 #endif
 #endif /* !SECURE_KERNEL */
-
-       lck_grp_attr_t *attr = lck_grp_attr_alloc_init();
-       cs_lockgrp = lck_grp_alloc_init("KERNCS", attr);
-       lck_grp_attr_free(attr);
 }
+STARTUP(CODESIGNING, STARTUP_RANK_FIRST, cs_init);
 
 int
 cs_allow_invalid(struct proc *p)
@@ -222,8 +226,23 @@ cs_allow_invalid(struct proc *p)
        if (p->p_csflags & CS_VALID) {
                p->p_csflags |= CS_DEBUGGED;
        }
+#if PMAP_CS
+       task_t procTask = proc_task(p);
+       if (procTask) {
+               vm_map_t proc_map = get_task_map_reference(procTask);
+               if (proc_map) {
+                       if (vm_map_cs_wx_enable(proc_map) != KERN_SUCCESS) {
+                               printf("CODE SIGNING: cs_allow_invalid() not allowed by pmap: pid %d\n", p->p_pid);
+                       }
+                       vm_map_deallocate(proc_map);
+               }
+       }
+#endif // MAP_CS
        proc_unlock(p);
 
+       /* allow a debugged process to hide some (debug-only!) memory */
+       task_set_memory_ownership_transfer(p->task, TRUE);
+
        vm_map_switch_protect(get_task_map(p->task), FALSE);
 #endif
        return (p->p_csflags & (CS_KILL | CS_HARD)) == 0;
@@ -234,7 +253,6 @@ cs_invalid_page(addr64_t vaddr, boolean_t *cs_killed)
 {
        struct proc     *p;
        int             send_kill = 0, retval = 0, verbose = cs_debug;
-       uint32_t        csflags;
 
        p = current_proc();
 
@@ -269,9 +287,9 @@ cs_invalid_page(addr64_t vaddr, boolean_t *cs_killed)
                        p->p_csflags &= ~CS_VALID;
                        cs_procs_invalidated++;
                        verbose = 1;
+                       cs_process_invalidated(NULL);
                }
        }
-       csflags = p->p_csflags;
        proc_unlock(p);
 
        if (verbose) {
@@ -292,10 +310,29 @@ cs_invalid_page(addr64_t vaddr, boolean_t *cs_killed)
                *cs_killed = FALSE;
        }
 
-
        return retval;
 }
 
+/*
+ * Called after a process got its CS_VALID bit removed, either by
+ * a previous call to cs_invalid_page, or through other means.
+ * Called from fault handler with vm object lock held.
+ * Called with proc lock held for current_proc or, if passed in, p,
+ * to ensure MACF hook can suspend the task before other threads
+ * can access the memory that is paged in after cs_invalid_page
+ * returns 0 due to missing CS_HARD|CS_KILL.
+ */
+void
+cs_process_invalidated(struct proc * __unused p)
+{
+#if CONFIG_MACF
+       if (p == NULL) {
+               p = current_proc();
+       }
+       mac_proc_notify_cs_invalidated(p);
+#endif
+}
+
 /*
  * Assumes p (if passed in) is locked with proc_lock().
  */
@@ -330,6 +367,13 @@ cs_system_enforcement(void)
        return cs_system_enforcement_enable ? 1 : 0;
 }
 
+int
+cs_vm_supports_4k_translations(void)
+{
+       return 0;
+}
+
+
 /*
  * Returns whether a given process is still valid.
  */
@@ -424,7 +468,7 @@ csblob_get_size(struct cs_blob *blob)
 vm_address_t
 csblob_get_addr(struct cs_blob *blob)
 {
-       return blob->csb_mem_kaddr;
+       return (vm_address_t)blob->csb_mem_kaddr;
 }
 
 /*
@@ -488,7 +532,7 @@ csproc_get_blob(struct proc *p)
                return NULL;
        }
 
-       return ubc_cs_blob_get(p->p_textvp, -1, p->p_textoff);
+       return ubc_cs_blob_get(p->p_textvp, -1, -1, p->p_textoff);
 }
 
 /*
@@ -500,7 +544,7 @@ csproc_get_blob(struct proc *p)
 struct cs_blob *
 csvnode_get_blob(struct vnode *vp, off_t offset)
 {
-       return ubc_cs_blob_get(vp, -1, offset);
+       return ubc_cs_blob_get(vp, -1, -1, offset);
 }
 
 /*
@@ -547,6 +591,11 @@ csblob_get_identity(struct cs_blob *csblob)
 const uint8_t *
 csblob_get_cdhash(struct cs_blob *csblob)
 {
+       ptrauth_utils_auth_blob_generic(csblob->csb_cdhash,
+           sizeof(csblob->csb_cdhash),
+           OS_PTRAUTH_DISCRIMINATOR("cs_blob.csb_cd_signature"),
+           PTRAUTH_ADDR_DIVERSIFY,
+           csblob->csb_cdhash_signature);
        return csblob->csb_cdhash;
 }
 
@@ -601,6 +650,19 @@ csproc_get_teamid(struct proc *p)
        return csblob_get_teamid(csblob);
 }
 
+const char *
+csproc_get_identity(struct proc *p)
+{
+       struct cs_blob *csblob = NULL;
+
+       csblob = csproc_get_blob(p);
+       if (csblob == NULL) {
+               return NULL;
+       }
+
+       return csblob_get_identity(csblob);
+}
+
 /*
  * Function: csproc_get_signer_type
  *
@@ -635,7 +697,7 @@ csvnode_get_teamid(struct vnode *vp, off_t offset)
                return NULL;
        }
 
-       csblob = ubc_cs_blob_get(vp, -1, offset);
+       csblob = ubc_cs_blob_get(vp, -1, -1, offset);
        if (csblob == NULL) {
                return NULL;
        }
@@ -698,6 +760,7 @@ csproc_disable_enforcement(struct proc* __unused p)
        if (p != NULL) {
                proc_lock(p);
                p->p_csflags &= (~CS_ENFORCEMENT);
+               vm_map_cs_enforcement_set(get_task_map(p->task), FALSE);
                proc_unlock(p);
        }
 #endif
@@ -802,6 +865,49 @@ out:
        return platform_binary;
 }
 
+int
+csfg_get_supplement_platform_binary(struct fileglob *fg __unused)
+{
+#if CONFIG_SUPPLEMENTAL_SIGNATURES
+       int platform_binary = 0;
+       struct ubc_info *uip;
+       vnode_t vp;
+
+       if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE) {
+               return 0;
+       }
+
+       vp = (struct vnode *)fg->fg_data;
+       if (vp == NULL) {
+               return 0;
+       }
+
+       vnode_lock(vp);
+       if (!UBCINFOEXISTS(vp)) {
+               goto out;
+       }
+
+       uip = vp->v_ubcinfo;
+       if (uip == NULL) {
+               goto out;
+       }
+
+       if (uip->cs_blob_supplement == NULL) {
+               goto out;
+       }
+
+       platform_binary = uip->cs_blob_supplement->csb_platform_binary;
+out:
+       vnode_unlock(vp);
+
+       return platform_binary;
+#else
+       // Supplemental signatures are only allowed in CONFIG_SUPPLEMENTAL_SIGNATURES
+       // Return false if anyone asks about them
+       return 0;
+#endif
+}
+
 uint8_t *
 csfg_get_cdhash(struct fileglob *fg, uint64_t offset, size_t *cdhash_size)
 {
@@ -817,15 +923,87 @@ csfg_get_cdhash(struct fileglob *fg, uint64_t offset, size_t *cdhash_size)
        }
 
        struct cs_blob *csblob = NULL;
-       if ((csblob = ubc_cs_blob_get(vp, -1, offset)) == NULL) {
+       if ((csblob = ubc_cs_blob_get(vp, -1, -1, offset)) == NULL) {
                return NULL;
        }
 
        if (cdhash_size) {
                *cdhash_size = CS_CDHASH_LEN;
        }
+       ptrauth_utils_auth_blob_generic(csblob->csb_cdhash,
+           sizeof(csblob->csb_cdhash),
+           OS_PTRAUTH_DISCRIMINATOR("cs_blob.csb_cd_signature"),
+           PTRAUTH_ADDR_DIVERSIFY,
+           csblob->csb_cdhash_signature);
+       return csblob->csb_cdhash;
+}
 
+uint8_t *
+csfg_get_supplement_cdhash(struct fileglob *fg __unused, uint64_t offset __unused, size_t *cdhash_size __unused)
+{
+#if CONFIG_SUPPLEMENTAL_SIGNATURES
+       vnode_t vp;
+
+       if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE) {
+               return NULL;
+       }
+
+       vp = (struct vnode *)fg->fg_data;
+       if (vp == NULL) {
+               return NULL;
+       }
+
+       struct cs_blob *csblob = NULL;
+       if ((csblob = ubc_cs_blob_get_supplement(vp, offset)) == NULL) {
+               return NULL;
+       }
+
+       if (cdhash_size) {
+               *cdhash_size = CS_CDHASH_LEN;
+       }
+       ptrauth_utils_auth_blob_generic(csblob->csb_cdhash,
+           sizeof(csblob->csb_cdhash),
+           OS_PTRAUTH_DISCRIMINATOR("cs_blob.csb_cd_signature"),
+           PTRAUTH_ADDR_DIVERSIFY,
+           csblob->csb_cdhash_signature);
        return csblob->csb_cdhash;
+#else
+       // Supplemental signatures are only available in CONFIG_SUPPLEMENTAL_SIGNATURES
+       // return NULL if anyone asks about them
+       return NULL;
+#endif
+}
+
+const uint8_t *
+csfg_get_supplement_linkage_cdhash(struct fileglob *fg __unused, uint64_t offset __unused, size_t *cdhash_size __unused)
+{
+#if CONFIG_SUPPLEMENTAL_SIGNATURES
+       vnode_t vp;
+
+       if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE) {
+               return NULL;
+       }
+
+       vp = (struct vnode *)fg->fg_data;
+       if (vp == NULL) {
+               return NULL;
+       }
+
+       struct cs_blob *csblob = NULL;
+       if ((csblob = ubc_cs_blob_get_supplement(vp, offset)) == NULL) {
+               return NULL;
+       }
+
+       if (cdhash_size) {
+               *cdhash_size = CS_CDHASH_LEN;
+       }
+
+       return csblob->csb_linkage;
+#else
+       // Supplemental signatures are only available in CONFIG_SUPPLEMENTAL_SIGNATURES
+       // return NULL if anyone asks about them
+       return NULL;
+#endif
 }
 
 /*
@@ -873,6 +1051,49 @@ out:
        return signer_type;
 }
 
+unsigned int
+csfg_get_supplement_signer_type(struct fileglob *fg __unused)
+{
+#if CONFIG_SUPPLEMENTAL_SIGNATURES
+       struct ubc_info *uip;
+       unsigned int signer_type = CS_SIGNER_TYPE_UNKNOWN;
+       vnode_t vp;
+
+       if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE) {
+               return CS_SIGNER_TYPE_UNKNOWN;
+       }
+
+       vp = (struct vnode *)fg->fg_data;
+       if (vp == NULL) {
+               return CS_SIGNER_TYPE_UNKNOWN;
+       }
+
+       vnode_lock(vp);
+       if (!UBCINFOEXISTS(vp)) {
+               goto out;
+       }
+
+       uip = vp->v_ubcinfo;
+       if (uip == NULL) {
+               goto out;
+       }
+
+       if (uip->cs_blob_supplement == NULL) {
+               goto out;
+       }
+
+       signer_type = uip->cs_blob_supplement->csb_signer_type;
+out:
+       vnode_unlock(vp);
+
+       return signer_type;
+#else
+       // Supplemental signatures are only available in CONFIG_SUPPLEMENTAL_SIGNATURES
+       // Return unknown if anyone asks
+       return CS_SIGNER_TYPE_UNKNOWN;
+#endif
+}
+
 /*
  * Function: csfg_get_teamid
  *
@@ -918,6 +1139,49 @@ out:
        return str;
 }
 
+const char *
+csfg_get_supplement_teamid(struct fileglob *fg __unused)
+{
+#if CONFIG_SUPPLEMENTAL_SIGNATURES
+       struct ubc_info *uip;
+       const char *str = NULL;
+       vnode_t vp;
+
+       if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE) {
+               return NULL;
+       }
+
+       vp = (struct vnode *)fg->fg_data;
+       if (vp == NULL) {
+               return NULL;
+       }
+
+       vnode_lock(vp);
+       if (!UBCINFOEXISTS(vp)) {
+               goto out;
+       }
+
+       uip = vp->v_ubcinfo;
+       if (uip == NULL) {
+               goto out;
+       }
+
+       if (uip->cs_blob_supplement == NULL) {
+               goto out;
+       }
+
+       str = uip->cs_blob_supplement->csb_supplement_teamid;
+out:
+       vnode_unlock(vp);
+
+       return str;
+#else
+       // Supplemental Signatures are only available in CONFIG_SUPPLEMENTAL_SIGNATURES
+       // Return NULL if anyone asks
+       return NULL;
+#endif
+}
+
 /*
  * Function: csfg_get_prod_signed
  *
@@ -964,6 +1228,51 @@ out:
        return prod_signed;
 }
 
+int
+csfg_get_supplement_prod_signed(struct fileglob *fg __unused)
+{
+#if CONFIG_SUPPLEMENTAL_SIGNATURES
+       struct ubc_info *uip;
+       vnode_t vp;
+       int prod_signed = 0;
+
+       if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE) {
+               return 0;
+       }
+
+       vp = (struct vnode *)fg->fg_data;
+       if (vp == NULL) {
+               return 0;
+       }
+
+       vnode_lock(vp);
+       if (!UBCINFOEXISTS(vp)) {
+               goto out;
+       }
+
+       uip = vp->v_ubcinfo;
+       if (uip == NULL) {
+               goto out;
+       }
+
+       if (uip->cs_blob_supplement == NULL) {
+               goto out;
+       }
+
+       /* It is OK to extract the flag from the first blob
+        *  because all blobs of a vnode must have the same cs_flags */
+       prod_signed = (uip->cs_blob_supplement->csb_flags & CS_DEV_CODE) == 0;
+out:
+       vnode_unlock(vp);
+
+       return prod_signed;
+#else
+       // Supplemental signatures are only available in CONFIG_SUPPLEMENTAL_SIGNATURES
+       // Indicate development signed if anyone tries to ask about one.
+       return 0;
+#endif
+}
+
 /*
  * Function: csfg_get_identity
  *
@@ -985,7 +1294,7 @@ csfg_get_identity(struct fileglob *fg, off_t offset)
                return NULL;
        }
 
-       csblob = ubc_cs_blob_get(vp, -1, offset);
+       csblob = ubc_cs_blob_get(vp, -1, -1, offset);
        if (csblob == NULL) {
                return NULL;
        }
@@ -1030,7 +1339,7 @@ csvnode_get_platform_identifier(struct vnode *vp, off_t offset)
        struct cs_blob *csblob;
        const CS_CodeDirectory *code_dir;
 
-       csblob = ubc_cs_blob_get(vp, -1, offset);
+       csblob = ubc_cs_blob_get(vp, -1, -1, offset);
        if (csblob == NULL) {
                return 0;
        }
@@ -1103,7 +1412,8 @@ csfg_get_path(struct fileglob *fg, char *path, int *len)
        return vn_getpath(vp, path, len);
 }
 
-/* Retrieve the entitlements blob for a process.
+/*
+ * Retrieve the entitlements blob for a vnode
  * Returns:
  *   EINVAL    no text vnode associated with the process
  *   EBADEXEC   invalid code signing data
@@ -1113,15 +1423,63 @@ csfg_get_path(struct fileglob *fg, char *path, int *len)
  * entitlements blob if found; or will be set to NULL/zero
  * if there were no entitlements.
  */
-
 int
-cs_entitlements_blob_get(proc_t p, void **out_start, size_t *out_length)
+cs_entitlements_blob_get_vnode(vnode_t vnode, off_t offset, void **out_start, size_t *out_length)
 {
        struct cs_blob *csblob;
 
        *out_start = NULL;
        *out_length = 0;
 
+       if (vnode == NULL) {
+               return EINVAL;
+       }
+
+       if ((csblob = ubc_cs_blob_get(vnode, -1, -1, offset)) == NULL) {
+               return 0;
+       }
+
+       return csblob_get_entitlements(csblob, out_start, out_length);
+}
+
+/*
+ * Retrieve the entitlements blob for a process.
+ * Returns:
+ *   EINVAL    no text vnode associated with the process
+ *   EBADEXEC   invalid code signing data
+ *   0         no error occurred
+ *
+ * On success, out_start and out_length will point to the
+ * entitlements blob if found; or will be set to NULL/zero
+ * if there were no entitlements.
+ */
+int
+cs_entitlements_blob_get(proc_t p, void **out_start, size_t *out_length)
+{
+       if ((p->p_csflags & CS_SIGNED) == 0) {
+               return 0;
+       }
+
+       return cs_entitlements_blob_get_vnode(p->p_textvp, p->p_textoff, out_start, out_length);
+}
+
+
+/* Retrieve the cached entitlements for a process
+ * Returns:
+ *   EINVAL    no text vnode associated with the process
+ *   EBADEXEC   invalid code signing data
+ *   0         no error occurred
+ *
+ * Note: the entitlements may be NULL if there is nothing cached.
+ */
+
+int
+cs_entitlements_dictionary_copy(proc_t p, void **entitlements)
+{
+       struct cs_blob *csblob;
+
+       *entitlements = NULL;
+
        if ((p->p_csflags & CS_SIGNED) == 0) {
                return 0;
        }
@@ -1130,11 +1488,12 @@ cs_entitlements_blob_get(proc_t p, void **out_start, size_t *out_length)
                return EINVAL;
        }
 
-       if ((csblob = ubc_cs_blob_get(p->p_textvp, -1, p->p_textoff)) == NULL) {
+       if ((csblob = ubc_cs_blob_get(p->p_textvp, -1, -1, p->p_textoff)) == NULL) {
                return 0;
        }
 
-       return csblob_get_entitlements(csblob, out_start, out_length);
+       *entitlements = csblob_entitlements_dictionary_copy(csblob);
+       return 0;
 }
 
 /* Retrieve the codesign identity for a process.
@@ -1156,7 +1515,7 @@ cs_identity_get(proc_t p)
                return NULL;
        }
 
-       if ((csblob = ubc_cs_blob_get(p->p_textvp, -1, p->p_textoff)) == NULL) {
+       if ((csblob = ubc_cs_blob_get(p->p_textvp, -1, -1, p->p_textoff)) == NULL) {
                return NULL;
        }
 
@@ -1184,11 +1543,11 @@ cs_blob_get(proc_t p, void **out_start, size_t *out_length)
                return EINVAL;
        }
 
-       if ((csblob = ubc_cs_blob_get(p->p_textvp, -1, p->p_textoff)) == NULL) {
+       if ((csblob = ubc_cs_blob_get(p->p_textvp, -1, -1, p->p_textoff)) == NULL) {
                return 0;
        }
 
-       *out_start = (void *)csblob->csb_mem_kaddr;
+       *out_start = csblob->csb_mem_kaddr;
        *out_length = csblob->csb_mem_size;
 
        return 0;
@@ -1211,9 +1570,14 @@ cs_get_cdhash(struct proc *p)
                return NULL;
        }
 
-       if ((csblob = ubc_cs_blob_get(p->p_textvp, -1, p->p_textoff)) == NULL) {
+       if ((csblob = ubc_cs_blob_get(p->p_textvp, -1, -1, p->p_textoff)) == NULL) {
                return NULL;
        }
 
+       ptrauth_utils_auth_blob_generic(csblob->csb_cdhash,
+           sizeof(csblob->csb_cdhash),
+           OS_PTRAUTH_DISCRIMINATOR("cs_blob.csb_cd_signature"),
+           PTRAUTH_ADDR_DIVERSIFY,
+           csblob->csb_cdhash_signature);
        return csblob->csb_cdhash;
 }