+#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;
+}
+#endif // CONFIG_BASESYSTEMROOT
+