]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/kext_alloc.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / osfmk / kern / kext_alloc.c
index 5a689341faccbe2e18ea5999cf32706b71a0a551..2abe7d4d9b276d5740370903e56b211e9f1392e1 100644 (file)
@@ -39,6 +39,7 @@
 #include <mach-o/loader.h>
 #include <libkern/kernel_mach_header.h>
 #include <libkern/prelink.h>
+#include <libkern/OSKextLibPrivate.h>
 #include <san/kasan.h>
 
 #define KASLR_IOREG_DEBUG 0
@@ -246,23 +247,57 @@ kext_free(vm_offset_t addr, vm_size_t size)
 kern_return_t
 kext_receipt(void **addrp, size_t *sizep)
 {
+       kern_return_t ret = KERN_FAILURE;
        if (addrp == NULL || sizep == NULL) {
-               return KERN_FAILURE;
+               goto finish;
        }
 
        kernel_mach_header_t *kc = PE_get_kc_header(KCKindAuxiliary);
        if (kc == NULL) {
-               return KERN_FAILURE;
+               ret = KERN_MISSING_KC;
+               goto finish;
+       }
+
+       /*
+        * This will be set in early boot once we've successfully checked that
+        * the AuxKC is properly linked against the BootKC. If this isn't set,
+        * and we have a valid AuxKC mach header, then the booter gave us a
+        * bad KC.
+        */
+       if (auxkc_uuid_valid == FALSE) {
+               ret = KERN_INVALID_KC;
+               goto finish;
        }
 
        size_t size;
        void *addr = getsectdatafromheader(kc,
            kReceiptInfoSegment, kAuxKCReceiptSection, &size);
        if (addr == NULL) {
-               return KERN_FAILURE;
+               ret = KERN_INVALID_KC;
+               goto finish;
        }
 
        *addrp = addr;
        *sizep = size;
-       return KERN_SUCCESS;
+       ret = KERN_SUCCESS;
+
+finish:
+       /*
+        * If we do return success, we'll want to wait for the other side to
+        * call kext_receipt_set_queried themselves, so we can confirm that
+        * it made the roundtrip before allowing third party kexts to load.
+        */
+       if (ret != KERN_SUCCESS) {
+               kext_receipt_set_queried();
+       }
+       return ret;
+}
+
+/*
+ * Returns KERN_FAILURE if the variable was already set.
+ */
+kern_return_t
+kext_receipt_set_queried()
+{
+       return OSKextSetReceiptQueried();
 }