+#if CONFIG_MACF
+#if defined (__i386__) || defined (__x86_64__)
+ PE_parse_boot_argn("policy_check", &policy_check_flags, sizeof(policy_check_flags));
+#endif
+#endif /* CONFIG_MACF */
+
+ if (PE_parse_boot_argn("msgbuf", &msgbuf, sizeof(msgbuf))) {
+ log_setsize(msgbuf);
+ oslog_setsize(msgbuf);
+ }
+
+ if (PE_parse_boot_argn("-novfscache", namep, sizeof(namep))) {
+ nc_disabled = 1;
+ }
+
+#if CONFIG_JETSAM && (DEVELOPMENT || DEBUG)
+ if (PE_parse_boot_argn("-no_vnode_jetsam", namep, sizeof(namep))) {
+ bootarg_no_vnode_jetsam = 1;
+ }
+#endif /* CONFIG_JETSAM && (DEVELOPMENT || DEBUG) */
+
+ if (PE_parse_boot_argn("-no_vnode_drain", namep, sizeof(namep))) {
+ bootarg_no_vnode_drain = 1;
+ }
+
+#if CONFIG_DARKBOOT
+ /*
+ * The darkboot flag is specified by the bootloader and is stored in
+ * boot_args->bootFlags. This flag is available starting revision 2.
+ */
+ boot_args *args = (boot_args *) PE_state.bootArgs;
+ if ((args != NULL) && (args->Revision >= kBootArgsRevision2)) {
+ darkboot = (args->bootFlags & kBootFlagsDarkBoot) ? 1 : 0;
+ } else {
+ darkboot = 0;
+ }
+#endif
+
+#if PROC_REF_DEBUG
+ if (PE_parse_boot_argn("-disable_procref_tracking", namep, sizeof(namep))) {
+ proc_ref_tracking_disabled = 1;
+ }
+#endif
+
+ PE_parse_boot_argn("sigrestrict", &sigrestrict_arg, sizeof(sigrestrict_arg));
+
+#if DEVELOPMENT || DEBUG
+ if (PE_parse_boot_argn("-no_sigsys", namep, sizeof(namep))) {
+ send_sigsys = false;
+ }
+
+ if (PE_parse_boot_argn("alt-dyld", dyld_alt_path, sizeof(dyld_alt_path))) {
+ if (strlen(dyld_alt_path) > 0) {
+ use_alt_dyld = 1;
+ }
+ }
+ PE_parse_boot_argn("dyld_flags", &dyld_flags, sizeof(dyld_flags));
+
+ if (PE_parse_boot_argn("-disable_syscallfilter", &namep, sizeof(namep))) {
+ syscallfilter_disable = 1;
+ }
+
+#if __arm64__
+ if (PE_parse_boot_argn("legacy_footprint_entitlement_mode", &legacy_footprint_entitlement_mode, sizeof(legacy_footprint_entitlement_mode))) {
+ /*
+ * legacy_footprint_entitlement_mode specifies the behavior we want associated
+ * with the entitlement. The supported modes are:
+ *
+ * LEGACY_FOOTPRINT_ENTITLEMENT_IGNORE:
+ * Indicates that we want every process to have the memory accounting
+ * that is available in iOS 12.0 and beyond.
+ *
+ * LEGACY_FOOTPRINT_ENTITLEMENT_IOS11_ACCT:
+ * Indicates that for every process that has the 'legacy footprint entitlement',
+ * we want to give it the old iOS 11.0 accounting behavior which accounted some
+ * of the process's memory to the kernel.
+ *
+ * LEGACY_FOOTPRINT_ENTITLEMENT_LIMIT_INCREASE:
+ * Indicates that for every process that has the 'legacy footprint entitlement',
+ * we want it to have a higher memory limit which will help them acclimate to the
+ * iOS 12.0 (& beyond) accounting behavior that does the right accounting.
+ * The bonus added to the system-wide task limit to calculate this higher memory limit
+ * is available in legacy_footprint_bonus_mb.
+ */
+
+ if (legacy_footprint_entitlement_mode < LEGACY_FOOTPRINT_ENTITLEMENT_IGNORE ||
+ legacy_footprint_entitlement_mode > LEGACY_FOOTPRINT_ENTITLEMENT_LIMIT_INCREASE) {
+ legacy_footprint_entitlement_mode = LEGACY_FOOTPRINT_ENTITLEMENT_LIMIT_INCREASE;
+ }
+ }
+#endif /* __arm64__ */
+#endif /* DEVELOPMENT || DEBUG */
+}
+
+#if CONFIG_BASESYSTEMROOT
+
+extern const char* IOGetBootUUID(void);
+extern const char* IOGetApfsPrebootUUID(void);
+
+// Get the UUID of the Preboot (and Recovery) folder associated with the
+// current boot volume, if applicable. The meaning of the UUID can be
+// filesystem-dependent and not all kinds of boots will have a UUID.
+// If available, the string will be returned. It does not need to be
+// deallocate. (Future: if we need to return the string as a copy that the
+// caller must free, we'll introduce a new functcion for that.)
+// NULL will be returned if the current boot has no applicable Preboot UUID.
+static
+const char *
+get_preboot_uuid(void)
+{
+ const char *maybe_uuid_string;
+
+ // try IOGetApfsPrebootUUID
+ maybe_uuid_string = IOGetApfsPrebootUUID();
+ if (maybe_uuid_string) {
+ uuid_t maybe_uuid;
+ int error = uuid_parse(maybe_uuid_string, maybe_uuid);
+ if (error == 0) {
+ return maybe_uuid_string;
+ }
+ }
+
+ // try IOGetBootUUID
+ maybe_uuid_string = IOGetBootUUID();
+ if (maybe_uuid_string) {
+ uuid_t maybe_uuid;
+ int error = uuid_parse(maybe_uuid_string, maybe_uuid);
+ if (error == 0) {
+ return maybe_uuid_string;
+ }
+ }
+
+ // didn't find it
+ return NULL;
+}
+
+#if defined(__arm64__)
+extern const char *IOGetBootObjectsPath(void);
+#endif
+
+// Find the BaseSystem.dmg to be used as the initial root volume during certain
+// kinds of boots.
+// This may mount volumes and lookup vnodes.
+// The DEVELOPMENT kernel will look for BaseSystem.rooted.dmg first.
+// If it returns 0 (no error), then it also writes the absolute path to the
+// BaseSystem.dmg into its argument (which must be a char[MAXPATHLEN]).
+static
+int
+bsd_find_basesystem_dmg(char *bsdmgpath_out, bool *rooted_dmg, bool *skip_signature_check)
+{
+ int error;
+ size_t len;
+ char *dmgbasepath;
+ char *dmgpath;
+ bool allow_rooted_dmg = false;
+
+ dmgbasepath = zalloc_flags(ZV_NAMEI, Z_ZERO | Z_WAITOK);
+ dmgpath = zalloc_flags(ZV_NAMEI, Z_ZERO | Z_WAITOK);
+ vnode_t imagevp = NULLVP;
+
+#if DEVELOPMENT || DEBUG
+ allow_rooted_dmg = true;
+#endif
+
+ //must provide output bool
+ if (rooted_dmg && skip_signature_check) {
+ *rooted_dmg = false;
+ *skip_signature_check = false;
+ } else {
+ error = EINVAL;
+ goto done;
+ }
+
+ error = vfs_mount_recovery();
+ if (error) {
+ goto done;
+ }
+
+ len = strlcpy(dmgbasepath, "/System/Volumes/Recovery/", MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ if (csr_check(CSR_ALLOW_ANY_RECOVERY_OS) == 0) {
+ *skip_signature_check = true;
+ allow_rooted_dmg = true;
+ }
+
+#if defined(__arm64__)
+ const char *boot_obj_path = IOGetBootObjectsPath();
+ if (boot_obj_path) {
+ if (boot_obj_path[0] == '/') {
+ dmgbasepath[len - 1] = '\0';
+ }
+
+ len = strlcat(dmgbasepath, boot_obj_path, MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ len = strlcat(dmgbasepath, "/usr/standalone/firmware/", MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ if (allow_rooted_dmg) {
+ len = strlcpy(dmgpath, dmgbasepath, MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ len = strlcat(dmgpath, "arm64eBaseSystem.rooted.dmg", MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ error = vnode_lookup(dmgpath, 0, &imagevp, vfs_context_kernel());
+ if (error == 0) {
+ *rooted_dmg = true;
+ *skip_signature_check = true;
+ goto done;
+ }
+ memset(dmgpath, 0, MAXPATHLEN);
+ }
+
+ len = strlcpy(dmgpath, dmgbasepath, MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ len = strlcat(dmgpath, "arm64eBaseSystem.dmg", MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ error = vnode_lookup(dmgpath, 0, &imagevp, vfs_context_kernel());
+ if (error == 0) {
+ goto done;
+ }
+ memset(dmgpath, 0, MAXPATHLEN);
+ dmgbasepath[strlen("/System/Volumes/Recovery/")] = '\0';
+ }
+#endif // __arm64__
+
+ const char *preboot_uuid = get_preboot_uuid();
+ if (preboot_uuid == NULL) {
+ // no preboot? bail out
+ return EINVAL;
+ }
+
+ len = strlcat(dmgbasepath, preboot_uuid, MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ if (allow_rooted_dmg) {
+ // Try BaseSystem.rooted.dmg
+ len = strlcpy(dmgpath, dmgbasepath, MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ len = strlcat(dmgpath, "/BaseSystem.rooted.dmg", MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ error = vnode_lookup(dmgpath, 0, &imagevp, vfs_context_kernel());
+ if (error == 0) {
+ // we found it! success!
+ *rooted_dmg = true;
+ *skip_signature_check = true;
+ goto done;
+ }
+ }
+
+ // Try BaseSystem.dmg
+ len = strlcpy(dmgpath, dmgbasepath, MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ len = strlcat(dmgpath, "/BaseSystem.dmg", MAXPATHLEN);
+ if (len > MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto done;
+ }
+
+ error = vnode_lookup(dmgpath, 0, &imagevp, vfs_context_kernel());
+ if (error == 0) {
+ // success!
+ goto done;
+ }
+
+done:
+ if (error == 0) {
+ strlcpy(bsdmgpath_out, dmgpath, MAXPATHLEN);
+ } else {
+ bsd_init_kprintf("%s: error %d\n", __func__, error);
+ }
+ if (imagevp != NULLVP) {
+ vnode_put(imagevp);
+ }
+ zfree(ZV_NAMEI, dmgpath);
+ zfree(ZV_NAMEI, dmgbasepath);
+ return error;
+}
+
+static boolean_t
+bsdmgroot_bootable(void)
+{
+#if defined(__arm64__)
+#define BSDMGROOT_DEFAULT true
+#else
+#define BSDMGROOT_DEFAULT false
+#endif
+
+ boolean_t resolved = BSDMGROOT_DEFAULT;
+
+ boolean_t boot_arg_bsdmgroot = false;
+ boolean_t boot_arg_nobsdmgroot = false;
+ int error;
+ mount_t mp;
+ boolean_t root_part_of_volume_group = false;
+ struct vfs_attr vfsattr;
+
+ mp = rootvnode->v_mount;
+ VFSATTR_INIT(&vfsattr);
+ VFSATTR_WANTED(&vfsattr, f_capabilities);
+
+ boot_arg_bsdmgroot = PE_parse_boot_argn("-bsdmgroot", NULL, 0);
+ boot_arg_nobsdmgroot = PE_parse_boot_argn("-nobsdmgroot", NULL, 0);
+
+ error = vfs_getattr(mp, &vfsattr, vfs_context_kernel());
+ if (!error && VFSATTR_IS_SUPPORTED(&vfsattr, f_capabilities)) {
+ if ((vfsattr.f_capabilities.capabilities[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_VOL_GROUPS) &&
+ (vfsattr.f_capabilities.valid[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_VOL_GROUPS)) {
+ root_part_of_volume_group = true;
+ }
+ }
+
+ boolean_t singleuser = (boothowto & RB_SINGLE) != 0;
+
+ // Start with the #defined default above.
+ // If booting to single-user mode, default to false, because single-
+ // user mode inside the BaseSystem is probably not what's wanted.
+ // If the 'yes' boot-arg is set, we'll allow that even in single-user
+ // mode, we'll assume you know what you're doing.
+ // The 'no' boot-arg overpowers the 'yes' boot-arg.
+ // In any case, we will not attempt to root from BaseSystem if the
+ // original (booter-chosen) root volume isn't in a volume group.
+ // This is just out of an abundance of caution: if the boot environment
+ // seems to be "something other than a standard install",
+ // we'll be conservative in messing with the root volume.
+
+ if (singleuser) {
+ resolved = false;
+ }
+
+ if (boot_arg_bsdmgroot) {
+ resolved = true;
+ }
+
+ if (boot_arg_nobsdmgroot) {
+ resolved = false;
+ }
+
+ if (!root_part_of_volume_group) {
+ resolved = false;
+ }
+
+ return resolved;