├── .cirrus.yml ├── .github ├── dependabot.yml └── workflows │ └── c-cpp.yml ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── Makefile ├── README.md ├── build.sh ├── codeql.sh ├── patches ├── 14.4 │ ├── TrustCache.patch │ ├── entitlements.patch │ ├── iokit.patch │ ├── machine_routines.patch │ ├── python.patch │ └── skywalk.patch ├── 15.0 │ ├── entitlements.patch │ ├── iokit.patch │ ├── link_kdk.patch │ ├── link_kdk146.patch │ ├── remove_tightbeam.patch │ ├── restore_files.sh │ └── skywalk.patch ├── TrustCache.patch ├── iobuffermemd_monterey.patch ├── kas_info.patch ├── machine_routines.patch ├── skywalk_sonoma.patch ├── skywalk_ventura.patch ├── syntax_checker_sonoma.patch └── syntax_checker_ventura.patch └── templates └── codeql.pkr.hcl /.cirrus.yml: -------------------------------------------------------------------------------- 1 | task: 2 | name: Build 3 | macos_instance: 4 | image: sequoia-codeql 5 | build_script: MACOS_VERSION='15.0' MACHINE_CONFIG=VMAPPLE bash -x build.sh 6 | codeql_script: MACOS_VERSION='15.0' MACHINE_CONFIG=VMAPPLE bash -x codeql.sh 7 | binary_artifacts: 8 | path: xnu-codeql.zip 9 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | time: "08:00" 8 | labels: 9 | - "dependencies" 10 | commit-message: 11 | prefix: "chore" 12 | include: "scope" 13 | -------------------------------------------------------------------------------- /.github/workflows/c-cpp.yml: -------------------------------------------------------------------------------- 1 | name: XNU CodeQL 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths-ignore: 7 | - "*.md" 8 | - Makefile 9 | - .cirrus.yml 10 | pull_request: 11 | branches: [ main ] 12 | 13 | concurrency: 14 | group: ${{ github.ref }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | build: 19 | runs-on: macos-latest 20 | strategy: 21 | matrix: 22 | macos-version: [ '15.5' ] 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v4 26 | with: 27 | fetch-depth: 0 28 | 29 | - name: Deps 30 | run: | 31 | # brew update 32 | brew install bash blacktop/tap/ipsw 33 | # sudo ipsw dl kdk --host --install 34 | sudo xcode-select -s /Applications/Xcode_16.2.app 35 | 36 | - name: kmutil help # This is to check for what flags are available 37 | run: | 38 | sysctl -n kern.bootobjectspath || true 39 | sw_vers 40 | kmutil inspect 41 | 42 | # - name: Cache JSONDB 43 | # id: cache-jsondb 44 | # uses: actions/cache@v4 45 | # with: 46 | # path: .cache/${{ matrix.macos-version }}/compile_commands.json 47 | # key: ${{ matrix.macos-version }}-jsondb 48 | 49 | - name: Build XNU JSON compilation database 50 | if: steps.cache-jsondb.outputs.cache-hit != 'true' 51 | run: | 52 | MACOS_VERSION='${{ matrix.macos-version }}' MACHINE_CONFIG=VMAPPLE JSONDB=1 bash -x build.sh 53 | zip -j xnu-${{ matrix.macos-version }}-jsondb.zip .cache/${{ matrix.macos-version }}/compile_commands.json 54 | 55 | - name: Build XNU 56 | run: | 57 | MACOS_VERSION='${{ matrix.macos-version }}' MACHINE_CONFIG=VMAPPLE KC_FILTER='com.apple.driver.SEPHibernation|com.apple.iokit.IOACPIFamily' bash -x build.sh 58 | # ipsw macho info fakeroot/oss-xnu.macOS.${{ matrix.macos-version }}.kc.vmapple 59 | ls -lah fakeroot/System/Library/Kernels/ 60 | cp fakeroot/System/Library/Kernels/kernel.release.vmapple . 61 | echo "$(shasum -a 256 kernel.release.vmapple)" 62 | shasum -a 256 kernel.release.vmapple > kernel.release.vmapple.sha256 63 | 64 | - uses: actions/upload-artifact@v4 65 | with: 66 | name: xnu-build-${{ matrix.macos-version }} 67 | path: | 68 | fakeroot/System/Library/Kernels/ 69 | # fakeroot/oss-xnu.macOS.${{ matrix.macos-version }}.kc.vmapple 70 | 71 | - name: Build XNU CodeQL Database 72 | run: | 73 | MACOS_VERSION='${{ matrix.macos-version }}' MACHINE_CONFIG=VMAPPLE bash -x codeql.sh 74 | echo "$(shasum -a 256 xnu-codeql.zip)" 75 | shasum -a 256 xnu-codeql.zip > xnu-codeql.zip.sha256 76 | 77 | - uses: actions/upload-artifact@v4 78 | with: 79 | name: xnu-codeql-${{ matrix.macos-version }} 80 | path: xnu-codeql.zip 81 | 82 | - name: Release 83 | env: 84 | GH_TOKEN: ${{ github.token }} 85 | run: | 86 | ls -lah 87 | gh release upload v${{ matrix.macos-version }} --clobber kernel.release.vmapple 88 | gh release upload v${{ matrix.macos-version }} --clobber kernel.release.vmapple.sha256 89 | gh release upload v${{ matrix.macos-version }} --clobber xnu-codeql.zip 90 | gh release upload v${{ matrix.macos-version }} --clobber xnu-codeql.zip.sha256 91 | gh release upload v${{ matrix.macos-version }} --clobber xnu-${{ matrix.macos-version }}-jsondb.zip -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # build files 46 | .DS_Store 47 | venv 48 | compile_commands.json 49 | build 50 | fakeroot 51 | release.json 52 | # build repos 53 | xnu 54 | AvailabilityVersions 55 | dtrace 56 | bootstrap_cmds 57 | libdispatch 58 | libplatform 59 | Libsystem 60 | # patches 61 | bsd/sys/make_symbol_aliasing.sh 62 | libsyscall/Libsyscall.xcconfig 63 | makedefs/MakeInc.def 64 | osfmk/arm64/machine_routines.c 65 | # CodeQL 66 | xnu-codeql 67 | xnu-codeql.zip 68 | xnu-queries 69 | codeql_queries 70 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "codeQL.githubDatabase.update": "never", 3 | "C_Cpp.intelliSenseEngine": "disabled", 4 | "clangd.path": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clangd", 5 | "clangd.arguments": [ 6 | "-log=verbose", 7 | "-pretty", 8 | "--background-index", 9 | //"--query-driver=/bin/arm-buildroot-linux-gnueabihf-g++", //for cross compile usage 10 | "--compile-commands-dir=${workspaceFolder}/build/xnu-compiledb.obj/RELEASE_ARM64_VMAPPLE", 11 | ], 12 | "editor.formatOnSave": false 13 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-2025 blacktop 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MACOS_VERSION=sequoia-xcode 2 | MACOS_VM_NAME=sequoia-codeql 3 | 4 | .PHONY: deps 5 | deps: 6 | @echo " > Installing dependencies" 7 | brew install hashicorp/tap/packer 8 | brew install cirruslabs/cli/tart 9 | brew install cirruslabs/cli/cirrus 10 | 11 | .PHONY: build-vm 12 | build-vm: 13 | @echo " > Building macOS VM" 14 | @packer init -upgrade ./templates/codeql.pkr.hcl 15 | @packer build -var "macos_version=$(MACOS_VERSION)" -var "macos_vm_name=$(MACOS_VM_NAME)" ./templates/codeql.pkr.hcl 16 | @echo " 🎉 Done! 🎉" 17 | 18 | .PHONY: export-vm 19 | export-vm: 20 | @echo " > EXPORTING macOS VM: $(MACOS_VM_NAME)" 21 | @tart export $(MACOS_VM_NAME) 22 | @echo " 🎉 Done! 🎉" 23 | 24 | .PHONY: codeql-db 25 | codeql-db: 26 | @echo " > Building CodeQL Database" 27 | @cirrus run 28 | @echo " 🎉 Done! 🎉" 29 | @cirrus run --artifacts-dir artifacts 30 | 31 | clean: 32 | @echo " > Cleaning up" 33 | @rm -rf ./artifacts 34 | @rm -rf ./venv 35 | @rm -rf ./xnu-codeql 36 | @rm xnu-codeql.zip 37 | @echo " 🎉 Done! 🎉" 38 | 39 | .DEFAULT_GOAL := build-vm -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # darwin-xnu-build 2 | 3 | [![XNU CodeQL](https://github.com/blacktop/darwin-xnu-build/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/blacktop/darwin-xnu-build/actions/workflows/c-cpp.yml) ![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/blacktop/darwin-xnu-build/total) 4 | [![LICENSE](https://img.shields.io/:license-mit-blue.svg)](https://doge.mit-license.org) 5 | 6 | 7 | 8 | 9 | > This repository contains scripts to build [xnu](https://github.com/apple-oss-distributions/xnu) as well as generate a kernel collection and [CodeQL](https://codeql.github.com) databases. 10 | 11 | --- 12 | 13 | ## Supported OS Versions 14 | 15 | | Version | Compiles | CodeQL | Boots *(arm64/x86_64)* | 16 | | ---------- | :------: | :---------------------------------------------------------------------------------------: | :--------------------: | 17 | | macOS 12.5 | ✅ | ❔ | ❔ / ✅ | 18 | | macOS 13.0 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v13.0/xnu-codeql.zip) | ❔ / ❔ | 19 | | macOS 13.1 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v13.1/xnu-codeql.zip) | ❔ / ❔ | 20 | | macOS 13.2 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v13.2/xnu-codeql.zip) | ❔ / ❔ | 21 | | macOS 13.3 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v13.3/xnu-codeql.zip) | ❔ / ❔ | 22 | | macOS 13.4 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v13.4/xnu-codeql.zip) | ❔ / ❔ | 23 | | macOS 13.5 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v13.5/xnu-codeql.zip) | ❔ / ❔ | 24 | | macOS 14.0 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v14.0/xnu-codeql.zip) | ❔ / ❔ | 25 | | macOS 14.1 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v14.1/xnu-codeql.zip) | ❔ / ❔ | 26 | | macOS 14.2 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v14.2/xnu-codeql.zip) | ❔ / ❔ | 27 | | macOS 14.3 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v14.3/xnu-codeql.zip) | ✅ / ✅ | 28 | | macOS 14.4 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v14.4/xnu-codeql.zip) | ✅ / ✅ | 29 | | macOS 14.5 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v14.5/xnu-codeql.zip) | ✅ / ✅ | 30 | | macOS 14.6 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v14.6/xnu-codeql.zip) | ❔ / ❔ | 31 | | macOS 15.0 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v15.0/xnu-codeql.zip) | ✅ / ✅ | 32 | | macOS 15.1 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v15.1/xnu-codeql.zip) | ❔ / ❔ | 33 | | macOS 15.2 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v15.2/xnu-codeql.zip) | ❔ / ❔ | 34 | | macOS 15.3 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v15.3/xnu-codeql.zip) | ❔ / ❔ | 35 | | macOS 15.4 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v15.4/xnu-codeql.zip) | ❔ / ❔ | 36 | | macOS 15.5 | ✅ | [DB](https://github.com/blacktop/darwin-xnu-build/releases/download/v15.5/xnu-codeql.zip) | ❔ / ❔ | 37 | 38 | > [!NOTE] 39 | > CodeQL DBs built with `MACHINE_CONFIG=VMAPPLE` 40 | > MacOS `14.3` booted: 41 | > - via Virtualization.framework with `MACHINE_CONFIG=VMAPPLE` 42 | > - via qemu with `ARCH_CONFIG=x86_64` 43 | > - via ASi tested with `MACHINE_CONFIG=T8101` and `MACHINE_CONFIG=T6000` 44 | 45 | ### Known Issue ⚠️ 46 | 47 | Currently `MACHINE_CONFIG=T8103` is not correctly building for at least `14.3` 48 | 49 | > [!NOTE] 50 | > When attempting to boot try adding the boot-arg: `sudo nvram boot-args="-unsafe_kernel_text"` 51 | 52 | > [!WARNING] 53 | > Booting VMAPPLE kernels in VMs only works on Apple M1s [see issue](https://github.com/blacktop/darwin-xnu-build/issues/22) 54 | 55 | ## Why? 🤔 56 | 57 | I'm hoping to patch and build the xnu source in interesting ways to aid in research and development of macOS/iOS security research tools as well as generate [CodeQL](https://securitylab.github.com/tools/codeql) databases for the community to use. 58 | 59 | ## Getting Started 60 | 61 | ### Dependencies 62 | 63 | - [homebrew](https://brew.sh) 64 | - [jq](https://stedolan.github.io/jq/) 65 | - [gum](https://github.com/charmbracelet/gum) 66 | - [xcodes](https://github.com/RobotsAndPencils/xcodes) 67 | - [ipsw](https://github.com/blacktop/ipsw) 68 | - [cmake](https://cmake.org) 69 | - [ninja](https://ninja-build.org) 70 | - XCode 71 | - python3 72 | - [codeql CLI](https://codeql.github.com/docs/codeql-cli/) 73 | 74 | > [!NOTE] 75 | > The `build.sh` script will install all these for you if you are connected to the internet. 76 | 77 | ### Clone the repo 78 | 79 | ```bash 80 | git clone https://github.com/blacktop/darwin-xnu-build.git 81 | cd darwin-xnu-build 82 | ``` 83 | 84 | ```bash 85 | ❯ ./build.sh --help 86 | 87 | Usage: build.sh [-h] [--clean] [--kc] 88 | 89 | This script builds the macOS XNU kernel 90 | 91 | Where: 92 | -h|--help show this help text 93 | -c|--clean cleans build artifacts and cloned repos 94 | -k|--kc create kernel collection (via kmutil create) 95 | ``` 96 | 97 | ### Build the kernel and kernel Collection 98 | 99 | ```bash 100 | KERNEL_CONFIG=RELEASE ARCH_CONFIG=ARM64 MACHINE_CONFIG=VMAPPLE ./build.sh --kc 101 | ``` 102 | 103 | > [!NOTE] 104 | > Supported `KERNEL_CONFIG` include: 105 | > - `RELEASE` 106 | > - `DEVELOPMENT` 107 | > 108 | > Supported `MACHINE_CONFIG` include: 109 | > - `T8101` 110 | > - `T8103` 111 | > - `T6000` 112 | > - `VMAPPLE` 113 | 114 | ```bash 115 | 116 | ⇒ 📦 Building kernel collection for 'kernel.release.t6000' 117 | • Decompressing KernelManagement kernelcache 118 | Merged LINKEDIT: 119 | weak bindings size: 0KB 120 | exports info size: 0KB 121 | bindings size: 0KB 122 | lazy bindings size: 0KB 123 | function starts size: 41KB 124 | data in code size: 0KB 125 | symbol table size: 3702KB (85348 exports, 87979 imports) 126 | symbol string pool size: 6465KB 127 | LINKEDITS optimized from 30MB to 10MB 128 | time to layout cache: 0ms 129 | time to copy cached dylibs into buffer: 1ms 130 | time to adjust segments for new split locations: 2ms 131 | time to bind all images: 8ms 132 | time to optimize Objective-C: 0ms 133 | time to do stub elimination: 0ms 134 | time to optimize LINKEDITs: 2ms 135 | time to compute slide info: 1ms 136 | time to compute UUID and codesign cache file: 1ms 137 | 🎉 XNU Build Done! 138 | ``` 139 | 140 | Check that the output contains all the KEXTs 141 | 142 | ```bash 143 | ❯ ipsw macho info build/oss-xnu.kc | head 144 | Magic = 64-bit MachO 145 | Type = FILESET 146 | CPU = AARCH64, ARM64e 147 | Commands = 241 (Size: 17160) 148 | Flags = None 149 | 000: LC_UUID 67DF7148-8EEC-B1A6-5F51-7502DADF2264 150 | 001: LC_BUILD_VERSION Platform: unknown, SDK: 0.0 151 | 002: LC_UNIXTHREAD Threads: 1, ARM64 EntryPoint: 0xfffffe0007ad1488 152 | 003: LC_DYLD_CHAINED_FIXUPS offset=0x003690000 size=0x444 153 | 004: LC_SEGMENT_64 sz=0x00008000 off=0x00000000-0x00008000 addr=0xfffffe0007004000-0xfffffe000700c000 r--/r-- __TEXT 154 | 155 | ``` 156 | 157 | ### Clean rebuild the kernel and kernel collection 158 | 159 | ```bash 160 | MACOS_VERSION='15.0' KERNEL_CONFIG=RELEASE ARCH_CONFIG=ARM64 MACHINE_CONFIG=VMAPPLE ./build.sh --clean --kc 161 | ``` 162 | 163 | ### Generate a CodeQL database 164 | 165 | ```bash 166 | MACOS_VERSION='15.0' KERNEL_CONFIG=RELEASE ARCH_CONFIG=ARM64 MACHINE_CONFIG=VMAPPLE ./codeql.sh 167 | ``` 168 | ```bash 169 | 170 | [2023-03-03 22:33:20] [build-stdout] 🎉 XNU Build Done! 171 | Finalizing database at darwin-xnu-build/xnu-codeql. 172 | Running TRAP import for CodeQL database at darwin-xnu-build/xnu-codeql... 173 | TRAP import complete (1m46s). 174 | Successfully created database at darwin-xnu-build/xnu-codeql. 175 | [info] Deleting log files... 176 | [info] Zipping the CodeQL database... 177 | 🎉 CodeQL Database Create Done! 178 | ``` 179 | 180 | Script builds and zips up the CodeQL database 181 | 182 | ```bash 183 | ❯ ll xnu-codeql.zip 184 | -rw-r--r--@ 1 blacktop staff 219M Mar 3 22:35 xnu-codeql.zip 185 | ``` 186 | 187 | ### Generate a CodeQL database *(in a `local` **Tart** VM)* 188 | 189 | Install deps: *[packer](https://developer.hashicorp.com/packer), [tart](https://tart.ru) and [cirrus](https://github.com/cirruslabs/cirrus-cli)* 190 | 191 | ```bash 192 | make deps 193 | ``` 194 | 195 | Build VM image 196 | 197 | ```bash 198 | make build-vm 199 | ``` 200 | 201 | Create CodeQL DB 202 | 203 | ```bash 204 | make codeql-db 205 | ``` 206 | 207 | ```bash 208 | > Building CodeQL Database 209 | 🕓 'Build' Task 08:22 210 | ✅ pull virtual machine 0.0s 211 | ✅ 'Build' Task 47:59 212 | 🎉 Done! 🎉 213 | 🕒 'Build' Task 46:28 214 | ✅ 'Build' Task 48:15 215 | ``` 216 | 217 | ```bash 218 | ❯ tree artifacts/ 219 | 220 | artifacts/ 221 | └── Build 222 | └── binary 223 | └── xnu-codeql.zip 224 | 225 | 3 directories, 1 file 226 | ``` 227 | 228 | ## TODO 229 | 230 | - [x] ~~Auto build xnu with Github Actions~~ 231 | - [x] ~~Auto generate CodeQL database with Github Actions~~ 232 | 233 | ## NOTES 234 | 235 | To see kernel logs 236 | 237 | ```bash 238 | log show --debug --last boot --predicate 'process == "kernel"' 239 | ``` 240 | 241 | ## Credit 242 | 243 | - 244 | - 245 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # CREDIT: https://github.com/pwn0rz/xnu-build 4 | 5 | set -o errexit 6 | set -o nounset 7 | set -o pipefail 8 | if [[ "${TRACE-0}" == "1" ]]; then 9 | set -o xtrace 10 | fi 11 | 12 | # Colors 13 | export ESC_SEQ="\x1b[" 14 | export COL_RESET=$ESC_SEQ"39;49;00m" 15 | export COL_RED=$ESC_SEQ"31;01m" 16 | export COL_GREEN=$ESC_SEQ"32;01m" 17 | export COL_YELLOW=$ESC_SEQ"33;01m" 18 | export COL_BLUE=$ESC_SEQ"34;01m" 19 | export COL_MAGENTA=$ESC_SEQ"35;01m" 20 | export COL_CYAN=$ESC_SEQ"36;01m" 21 | 22 | function running() { 23 | echo -e "$COL_MAGENTA ⇒ $COL_RESET""$1" 24 | } 25 | 26 | function info() { 27 | echo -e "$COL_BLUE[info] $COL_RESET""$1" 28 | } 29 | 30 | function error() { 31 | echo -e "$COL_RED[error] $COL_RESET""$1" 32 | } 33 | 34 | # Config 35 | : ${KERNEL_CONFIG:=RELEASE} 36 | : ${ARCH_CONFIG:=ARM64} 37 | : ${MACHINE_CONFIG:=VMAPPLE} 38 | : ${MACOS_VERSION:=""} 39 | : ${JSONDB:=0} 40 | : ${BUILDKC:=0} 41 | : ${CODEQL:=0} 42 | : ${KC_FILTER:='com.apple.driver.SEPHibernation|com.apple.driver.ExclavesAudioKext|com.apple.driver.AppleH11ANEInterface|com.apple.driver.AppleFirmwareKit|com.apple.driver.AppleARMWatchdogTimer'} 43 | 44 | WORK_DIR="$PWD" 45 | CACHE_DIR="${WORK_DIR}/.cache" 46 | BUILD_DIR="${WORK_DIR}/build" 47 | FAKEROOT_DIR="${WORK_DIR}/fakeroot" 48 | DSTROOT="${FAKEROOT_DIR}" 49 | 50 | HAVE_WE_INSTALLED_HEADERS_YET="${FAKEROOT_DIR}/.xnu_headers_installed" 51 | 52 | KERNEL_FRAMEWORK_ROOT='/System/Library/Frameworks/Kernel.framework/Versions/A' 53 | KC_VARIANT=$(echo "$KERNEL_CONFIG" | tr '[:upper:]' '[:lower:]') 54 | KERNEL_TYPE="${KC_VARIANT}.$(echo "$MACHINE_CONFIG" | tr '[:upper:]' '[:lower:]')" 55 | 56 | help() { 57 | echo 'Usage: build.sh [-h] [--clean] [--kc] 58 | 59 | This script builds the macOS XNU kernel 60 | 61 | Where: 62 | -h|--help show this help text 63 | -c|--clean cleans build artifacts and cloned repos 64 | -k|--kc create kernel collection (via kmutil create) 65 | ' 66 | exit 0 67 | } 68 | 69 | clean() { 70 | running "Cleaning build directories and extra repos..." 71 | declare -a paths_to_delete=( 72 | "${BUILD_DIR}" 73 | "${FAKEROOT_DIR}" 74 | "${WORK_DIR}/xnu" 75 | "${WORK_DIR}/bootstrap_cmds" 76 | "${WORK_DIR}/dtrace" 77 | "${WORK_DIR}/AvailabilityVersions" 78 | "${WORK_DIR}/Libsystem" 79 | "${WORK_DIR}/libplatform" 80 | "${WORK_DIR}/libdispatch" 81 | ) 82 | 83 | for path in "${paths_to_delete[@]}"; do 84 | info "Will delete ${path}" 85 | done 86 | 87 | read -p "Are you sure? " -n 1 -r 88 | echo # (optional) move to a new line 89 | if [[ $REPLY =~ ^[Yy]$ ]]; then 90 | for path in "${paths_to_delete[@]}"; do 91 | info "Deleting ${path}" 92 | rm -rf "${path}" 93 | done 94 | fi 95 | } 96 | 97 | install_deps() { 98 | if [ ! -x "$(command -v jq)" ] || [ ! -x "$(command -v gum)" ] || [ ! -x "$(command -v xcodes)" ] || [ ! -x "$(command -v cmake)" ] || [ ! -x "$(command -v ninja)" ]; then 99 | running "Installing dependencies" 100 | if [ ! -x "$(command -v brew)" ]; then 101 | error "Please install homebrew - https://brew.sh (or install 'jq', 'gum' and 'xcodes' manually)" 102 | read -p "Install homebrew now? " -n 1 -r 103 | echo # (optional) move to a new line 104 | if [[ $REPLY =~ ^[Yy]$ ]]; then 105 | running "Installing homebrew" 106 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 107 | else 108 | exit 1 109 | fi 110 | fi 111 | brew install jq gum xcodes bash cmake ninja 112 | fi 113 | if compgen -G "/Applications/Xcode*.app" >/dev/null; then 114 | info "Xcode is already installed: $(xcode-select -p)" 115 | else 116 | running "Installing XCode" 117 | ipsw download dev --more --output /tmp 118 | XCODE_VERSION=$(ls /tmp/Xcode_*.xip | sed -E 's/.*Xcode_(.*).xip/\1/') 119 | xcodes install "${XCODE_VERSION}" --experimental-unxip --color --select --path "/tmp/Xcode_${XCODE_VERSION}.xip" 120 | # xcodebuild -downloadAllPlatforms 121 | xcodebuild -runFirstLaunch 122 | fi 123 | } 124 | 125 | install_ipsw() { 126 | if [ ! -x "$(command -v ipsw)" ]; then 127 | running "Installing ipsw..." 128 | brew install blacktop/tap/ipsw 129 | fi 130 | } 131 | 132 | choose_xnu() { 133 | if [ -z "$MACOS_VERSION" ]; then 134 | gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "Choose $(gum style --foreground 212 'macOS') version to build:" 135 | MACOS_VERSION=$(gum choose "12.5" "13.0" "13.1" "13.2" "13.3" "13.4" "13.5" "14.0" "14.1" "14.2" "14.3" "14.4" "14.5" "14.6" "15.0" "15.1" "15.2" "15.3" "15.4" "15.5") 136 | fi 137 | TIGHTBEAMC="tightbeamc-not-supported" 138 | case ${MACOS_VERSION} in 139 | '12.5') 140 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-125/release.json' 141 | KDK_NAME='Kernel Debug Kit 12.5 build 21G72' 142 | KDKROOT='/Library/Developer/KDKs/KDK_12.5_21G72.kdk' 143 | RC_DARWIN_KERNEL_VERSION='22.6.0' 144 | ;; 145 | '13.0') 146 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-130/release.json' 147 | KDK_NAME='Kernel Debug Kit 13.0 build 22A380' 148 | KDKROOT='/Library/Developer/KDKs/KDK_13.0_22A380.kdk' 149 | RC_DARWIN_KERNEL_VERSION='22.1.0' 150 | ;; 151 | '13.1') 152 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-131/release.json' 153 | KDK_NAME='Kernel Debug Kit 13.1 build 22C65' 154 | KDKROOT='/Library/Developer/KDKs/KDK_13.1_22C65.kdk' 155 | RC_DARWIN_KERNEL_VERSION='22.2.0' 156 | ;; 157 | '13.2') 158 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-132/release.json' 159 | KDK_NAME='Kernel Debug Kit 13.2 build 22D49' 160 | KDKROOT='/Library/Developer/KDKs/KDK_13.2_22D49.kdk' 161 | RC_DARWIN_KERNEL_VERSION='22.3.0' 162 | ;; 163 | '13.3') 164 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-133/release.json' 165 | KDK_NAME='Kernel Debug Kit 13.3 build 22E252' 166 | KDKROOT='/Library/Developer/KDKs/KDK_13.3_22E252.kdk' 167 | RC_DARWIN_KERNEL_VERSION='22.4.0' 168 | ;; 169 | '13.4') 170 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-134/release.json' 171 | KDK_NAME='Kernel Debug Kit 13.4 build 22F66' 172 | KDKROOT='/Library/Developer/KDKs/KDK_13.4_22F66.kdk' 173 | RC_DARWIN_KERNEL_VERSION='22.5.0' 174 | ;; 175 | '13.5') 176 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-135/release.json' 177 | KDK_NAME='Kernel Debug Kit 13.5 build 22G74' 178 | KDKROOT='/Library/Developer/KDKs/KDK_13.5_22G74.kdk' 179 | RC_DARWIN_KERNEL_VERSION='22.6.0' 180 | ;; 181 | '14.0') 182 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-140/release.json' 183 | KDK_NAME='Kernel Debug Kit 14.0 build 23A344' 184 | KDKROOT='/Library/Developer/KDKs/KDK_14.0_23A344.kdk' 185 | RC_DARWIN_KERNEL_VERSION='23.0.0' 186 | ;; 187 | '14.1') 188 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-141/release.json' 189 | KDK_NAME='Kernel Debug Kit 14.1 build 23B74' 190 | KDKROOT='/Library/Developer/KDKs/KDK_14.1_23B74.kdk' 191 | RC_DARWIN_KERNEL_VERSION='23.1.0' 192 | ;; 193 | '14.2') 194 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-142/release.json' 195 | KDK_NAME='Kernel Debug Kit 14.2 build 23C64' 196 | KDKROOT='/Library/Developer/KDKs/KDK_14.2_23C64.kdk' 197 | RC_DARWIN_KERNEL_VERSION='23.2.0' 198 | ;; 199 | '14.3') 200 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-143/release.json' 201 | KDK_NAME='Kernel Debug Kit 14.3 build 23D56' 202 | KDKROOT='/Library/Developer/KDKs/KDK_14.3_23D56.kdk' 203 | RC_DARWIN_KERNEL_VERSION='23.3.0' 204 | ;; 205 | '14.4') 206 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-144/release.json' 207 | KDK_NAME='Kernel Debug Kit 14.4 build 23E214' 208 | KDKROOT='/Library/Developer/KDKs/KDK_14.4_23E214.kdk' 209 | RC_DARWIN_KERNEL_VERSION='23.4.0' 210 | ;; 211 | '14.5') 212 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-145/release.json' 213 | KDK_NAME='Kernel Debug Kit 14.5 build 23F79' 214 | KDKROOT='/Library/Developer/KDKs/KDK_14.5_23F79.kdk' 215 | RC_DARWIN_KERNEL_VERSION='23.5.0' 216 | ;; 217 | '14.6') 218 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-146/release.json' 219 | KDK_NAME='Kernel Debug Kit 14.6 build 23G80' 220 | KDKROOT='/Library/Developer/KDKs/KDK_14.6_23G80.kdk' 221 | RC_DARWIN_KERNEL_VERSION='23.6.0' 222 | ;; 223 | '15.0') 224 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-150/release.json' 225 | KDK_NAME='Kernel Debug Kit 15.0 build 24A335' 226 | KDKROOT='/Library/Developer/KDKs/KDK_15.0_24A335.kdk' 227 | RC_DARWIN_KERNEL_VERSION='24.0.0' 228 | ;; 229 | '15.1') 230 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-151/release.json' 231 | KDK_NAME='Kernel Debug Kit 15.1 build 24B83' 232 | KDKROOT='/Library/Developer/KDKs/KDK_15.1_24B83.kdk' 233 | RC_DARWIN_KERNEL_VERSION='24.1.0' 234 | ;; 235 | '15.2') 236 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-152/release.json' 237 | KDK_NAME='Kernel Debug Kit 15.2 build 24C101' 238 | KDKROOT='/Library/Developer/KDKs/KDK_15.2_24C101.kdk' 239 | RC_DARWIN_KERNEL_VERSION='24.2.0' 240 | ;; 241 | '15.3') 242 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-153/release.json' 243 | KDK_NAME='Kernel Debug Kit 15.3 build 24D60' 244 | KDKROOT='/Library/Developer/KDKs/KDK_15.3_24D60.kdk' 245 | RC_DARWIN_KERNEL_VERSION='24.3.0' 246 | ;; 247 | '15.4') 248 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-154/release.json' 249 | KDK_NAME='Kernel Debug Kit 15.4 build 24E248' 250 | KDKROOT='/Library/Developer/KDKs/KDK_15.4_24E248.kdk' 251 | RC_DARWIN_KERNEL_VERSION='24.4.0' 252 | ;; 253 | '15.5') 254 | RELEASE_URL='https://raw.githubusercontent.com/apple-oss-distributions/distribution-macOS/macos-155/release.json' 255 | KDK_NAME='Kernel Debug Kit 15.5 build 24F74' 256 | KDKROOT='/Library/Developer/KDKs/KDK_15.5_24F74.kdk' 257 | RC_DARWIN_KERNEL_VERSION='24.5.0' 258 | ;; 259 | *) 260 | error "Invalid xnu version" 261 | exit 1 262 | ;; 263 | esac 264 | info "Building XNU for macOS ${MACOS_VERSION}" 265 | if [ ! -d "$KDKROOT" ]; then 266 | KDK_URL=$(curl -s "https://raw.githubusercontent.com/dortania/KdkSupportPkg/gh-pages/manifest.json" | jq -r --arg KDK_NAME "$KDK_NAME" '.[] | select(.name==$KDK_NAME) | .url') 267 | running "Downloading '$KDK_NAME' to /tmp" 268 | curl --progress-bar --max-time 900 --connect-timeout 60 -L -o /tmp/KDK.dmg "${KDK_URL}" 269 | running "Installing KDK" 270 | hdiutil attach /tmp/KDK.dmg 271 | if [ ! -d " /Library/Developer/KDKs" ]; then 272 | sudo mkdir -p /Library/Developer/KDKs 273 | sudo chmod 755 /Library/Developer/KDKs 274 | fi 275 | sudo installer -pkg '/Volumes/Kernel Debug Kit/KernelDebugKit.pkg' -target / 276 | hdiutil detach '/Volumes/Kernel Debug Kit' 277 | ls -lah /Library/Developer/KDKs 278 | fi 279 | } 280 | 281 | venv() { 282 | if [ ! -d "${WORK_DIR}/venv" ]; then 283 | running "Creating virtual environment" 284 | python3 -m venv "${WORK_DIR}/venv" 285 | fi 286 | info "Activating virtual environment" 287 | source "${WORK_DIR}/venv/bin/activate" 288 | } 289 | 290 | get_xnu() { 291 | if [ ! -d "${WORK_DIR}/xnu" ]; then 292 | running "⬇️ Cloning xnu" 293 | XNU_VERSION=$(curl -s $RELEASE_URL | jq -r '.projects[] | select(.project=="xnu") | .tag') 294 | git clone --branch "${XNU_VERSION}" https://github.com/apple-oss-distributions/xnu.git "${WORK_DIR}/xnu" 295 | fi 296 | if [ -f "${CACHE_DIR}/${MACOS_VERSION}/compile_commands.json" ]; then 297 | info "Restoring cached ${CACHE_DIR}/${MACOS_VERSION}/compile_commands.json" 298 | cp -f "${CACHE_DIR}/${MACOS_VERSION}/compile_commands.json" "${WORK_DIR}/xnu" 299 | fi 300 | } 301 | 302 | patches() { 303 | running "🩹 Patching xnu files" 304 | # xnu headers patch 305 | sed -i '' 's|^AVAILABILITY_PL="${SDKROOT}/${DRIVERKITROOT}|AVAILABILITY_PL="${FAKEROOT_DIR}|g' "${WORK_DIR}/xnu/bsd/sys/make_symbol_aliasing.sh" 306 | # libsyscall patch 307 | sed -i '' 's|^#include.*BSD.xcconfig.*||g' "${WORK_DIR}/xnu/libsyscall/Libsyscall.xcconfig" 308 | # xnu build patch 309 | sed -i '' 's|^LDFLAGS_KERNEL_SDK = -L$(SDKROOT).*|LDFLAGS_KERNEL_SDK = -L$(FAKEROOT_DIR)/usr/local/lib/kernel -lfirehose_kernel|g' "${WORK_DIR}/xnu/makedefs/MakeInc.def" 310 | sed -i '' 's|^INCFLAGS_SDK = -I$(SDKROOT)|INCFLAGS_SDK = -I$(FAKEROOT_DIR)|g' "${WORK_DIR}/xnu/makedefs/MakeInc.def" 311 | # specify location of mig (bootstrap_cmds) 312 | sed -i '' 's|export MIG := $(shell $(XCRUN) -sdk $(SDKROOT) -find mig)|export MIG := $(shell find $(FAKEROOT_DIR) -name "mig")|g' "${WORK_DIR}/xnu/makedefs/MakeInc.cmd" 313 | sed -i '' 's|export MIGCOM := $(shell $(XCRUN) -sdk $(SDKROOT) -find migcom)|export MIGCOM := $(shell find $(FAKEROOT_DIR) -name "migcom")|g' "${WORK_DIR}/xnu/makedefs/MakeInc.cmd" 314 | # Don't apply patches when building CodeQL database to keep code pure 315 | if [ "$CODEQL" -eq "0" ]; then 316 | PATCH_DIR="" 317 | case ${MACOS_VERSION} in 318 | '12.5' | '13.0' | '13.1' | '13.2' | '13.3' | '13.4' | '13.5' | '14.0' | '14.1' | '14.2' | '14.3') 319 | PATCH_DIR="${WORK_DIR}/patches" 320 | ;; 321 | '14.4' | '14.5') 322 | PATCH_DIR="${WORK_DIR}/patches/14.4" 323 | ;; 324 | '14.6' | '15.0' | '15.1' | '15.2' | '15.3' | '15.4' | '15.5') 325 | PATCH_DIR="${WORK_DIR}/patches/15.0" 326 | ;; 327 | *) 328 | error "Invalid xnu version" 329 | exit 1 330 | ;; 331 | esac 332 | cd "${WORK_DIR}/xnu" 333 | for SCRIPT in "${PATCH_DIR}"/*.sh; do 334 | running "Running script: ${SCRIPT}" 335 | bash "${SCRIPT}" 336 | done 337 | for PATCH in "${PATCH_DIR}"/*.patch; do 338 | if git apply --check "$PATCH" 2> /dev/null; then 339 | running "Applying patch: ${PATCH}" 340 | git apply "$PATCH" 341 | fi 342 | done 343 | cd "${WORK_DIR}" 344 | fi 345 | } 346 | 347 | build_bootstrap_cmds() { 348 | if [ ! "$(find "${FAKEROOT_DIR}" -name 'mig' | wc -l)" -gt 0 ]; then 349 | running "📦 Building bootstrap_cmds" 350 | 351 | if [ ! -d "${WORK_DIR}/bootstrap_cmds" ]; then 352 | BOOTSTRAP_VERSION=$(curl -s $RELEASE_URL | jq -r '.projects[] | select(.project=="bootstrap_cmds") | .tag') 353 | git clone --branch "${BOOTSTRAP_VERSION}" https://github.com/apple-oss-distributions/bootstrap_cmds.git "${WORK_DIR}/bootstrap_cmds" 354 | fi 355 | 356 | SRCROOT="${WORK_DIR}/bootstrap_cmds" 357 | OBJROOT="${BUILD_DIR}/bootstrap_cmds.obj" 358 | SYMROOT="${BUILD_DIR}/bootstrap_cmds.sym" 359 | 360 | sed -i '' 's|-o root -g wheel||g' "${WORK_DIR}/bootstrap_cmds/xcodescripts/install-mig.sh" 361 | 362 | CLONED_BOOTSTRAP_VERSION=$(cd "${WORK_DIR}/bootstrap_cmds"; git describe --always 2>/dev/null) 363 | 364 | cd "${SRCROOT}" 365 | xcodebuild install -sdk macosx -project mig.xcodeproj ARCHS="arm64 x86_64" CODE_SIGN_IDENTITY="-" OBJROOT="${OBJROOT}" SYMROOT="${SYMROOT}" DSTROOT="${DSTROOT}" RC_ProjectNameAndSourceVersion="${CLONED_BOOTSTRAP_VERSION}" 366 | cd "${WORK_DIR}" 367 | fi 368 | } 369 | 370 | build_dtrace() { 371 | if [ ! "$(find "${FAKEROOT_DIR}" -name 'ctfmerge' | wc -l)" -gt 0 ]; then 372 | running "📦 Building dtrace" 373 | if [ ! -d "${WORK_DIR}/dtrace" ]; then 374 | DTRACE_VERSION=$(curl -s $RELEASE_URL | jq -r '.projects[] | select(.project=="dtrace") | .tag') 375 | git clone --branch "${DTRACE_VERSION}" https://github.com/apple-oss-distributions/dtrace.git "${WORK_DIR}/dtrace" 376 | fi 377 | SRCROOT="${WORK_DIR}/dtrace" 378 | OBJROOT="${BUILD_DIR}/dtrace.obj" 379 | SYMROOT="${BUILD_DIR}/dtrace.sym" 380 | cd "${SRCROOT}" 381 | xcodebuild install -sdk macosx -target ctfconvert -target ctfdump -target ctfmerge ARCHS="arm64 x86_64" CODE_SIGN_IDENTITY="-" OBJROOT="${OBJROOT}" SYMROOT="${SYMROOT}" DSTROOT="${DSTROOT}" 382 | cd "${WORK_DIR}" 383 | fi 384 | } 385 | 386 | build_availabilityversions() { 387 | if [ ! "$(find "${FAKEROOT_DIR}" -name 'availability.pl' | wc -l)" -gt 0 ]; then 388 | running "📦 Building AvailabilityVersions" 389 | if [ ! -d "${WORK_DIR}/AvailabilityVersions" ]; then 390 | AVAILABILITYVERSIONS_VERSION=$(curl -s $RELEASE_URL | jq -r '.projects[] | select(.project=="AvailabilityVersions") | .tag') 391 | git clone --branch "${AVAILABILITYVERSIONS_VERSION}" https://github.com/apple-oss-distributions/AvailabilityVersions.git "${WORK_DIR}/AvailabilityVersions" 392 | fi 393 | SRCROOT="${WORK_DIR}/AvailabilityVersions" 394 | OBJROOT="${BUILD_DIR}/" 395 | SYMROOT="${BUILD_DIR}/" 396 | cd "${SRCROOT}" 397 | make install -j8 OBJROOT="${OBJROOT}" SYMROOT="${SYMROOT}" DSTROOT="${DSTROOT}" 398 | cd "${WORK_DIR}" 399 | fi 400 | } 401 | 402 | xnu_headers() { 403 | if [ ! -f "${HAVE_WE_INSTALLED_HEADERS_YET}" ]; then 404 | running "Installing xnu headers" 405 | SRCROOT="${WORK_DIR}/xnu" 406 | OBJROOT="${BUILD_DIR}/xnu-hdrs.obj" 407 | SYMROOT="${BUILD_DIR}/xnu-hdrs.sym" 408 | cd "${SRCROOT}" 409 | make installhdrs SDKROOT=macosx ARCH_CONFIGS="X86_64 ARM64" OBJROOT="${OBJROOT}" SYMROOT="${SYMROOT}" DSTROOT="${DSTROOT}" FAKEROOT_DIR="${FAKEROOT_DIR}" KDKROOT="${KDKROOT}" TIGHTBEAMC=${TIGHTBEAMC} RC_DARWIN_KERNEL_VERSION=${RC_DARWIN_KERNEL_VERSION} 410 | cd "${WORK_DIR}" 411 | touch "${HAVE_WE_INSTALLED_HEADERS_YET}" 412 | fi 413 | } 414 | 415 | libsystem_headers() { 416 | if [ ! -d "${FAKEROOT_DIR}/System/Library/Frameworks/System.framework" ]; then 417 | running "Installing Libsystem headers" 418 | if [ ! -d "${WORK_DIR}/Libsystem" ]; then 419 | LIBSYSTEM_VERSION=$(curl -s $RELEASE_URL | jq -r '.projects[] | select(.project=="Libsystem") | .tag') 420 | git clone --branch "${LIBSYSTEM_VERSION}" https://github.com/apple-oss-distributions/Libsystem.git "${WORK_DIR}/Libsystem" 421 | fi 422 | sed -i '' 's|^#include.*BSD.xcconfig.*||g' "${WORK_DIR}/Libsystem/Libsystem.xcconfig" 423 | SRCROOT="${WORK_DIR}/Libsystem" 424 | OBJROOT="${BUILD_DIR}/Libsystem.obj" 425 | SYMROOT="${BUILD_DIR}/Libsystem.sym" 426 | cd "${SRCROOT}" 427 | xcodebuild installhdrs -sdk macosx ARCHS="arm64 arm64e" VALID_ARCHS="arm64 arm64e" OBJROOT="${OBJROOT}" SYMROOT="${SYMROOT}" DSTROOT="${DSTROOT}" FAKEROOT_DIR="${FAKEROOT_DIR}" 428 | cd "${WORK_DIR}" 429 | fi 430 | } 431 | 432 | libsyscall_headers() { 433 | if [ ! -f "${FAKEROOT_DIR}/usr/include/os/proc.h" ]; then 434 | running "Installing libsyscall headers" 435 | SRCROOT="${WORK_DIR}/xnu/libsyscall" 436 | OBJROOT="${BUILD_DIR}/libsyscall.obj" 437 | SYMROOT="${BUILD_DIR}/libsyscall.sym" 438 | cd "${SRCROOT}" 439 | xcodebuild installhdrs -sdk macosx TARGET_CONFIGS="$KERNEL_CONFIG $ARCH_CONFIG $MACHINE_CONFIG" ARCHS="arm64 arm64e" VALID_ARCHS="arm64 arm64e" OBJROOT="${OBJROOT}" SYMROOT="${SYMROOT}" DSTROOT="${DSTROOT}" FAKEROOT_DIR="${FAKEROOT_DIR}" 440 | cd "${WORK_DIR}" 441 | fi 442 | } 443 | 444 | build_libplatform() { 445 | if [ ! -f "${FAKEROOT_DIR}/usr/local/include/_simple.h" ]; then 446 | running "📦 Building libplatform" 447 | if [ ! -d "${WORK_DIR}/libplatform" ]; then 448 | LIBPLATFORM_VERSION=$(curl -s $RELEASE_URL | jq -r '.projects[] | select(.project=="libplatform") | .tag') 449 | git clone --branch "${LIBPLATFORM_VERSION}" https://github.com/apple-oss-distributions/libplatform.git "${WORK_DIR}/libplatform" 450 | fi 451 | SRCROOT="${WORK_DIR}/libplatform" 452 | cd "${SRCROOT}" 453 | ditto "${SRCROOT}/include" "${DSTROOT}/usr/local/include" 454 | ditto "${SRCROOT}/private" "${DSTROOT}/usr/local/include" 455 | cd "${WORK_DIR}" 456 | fi 457 | } 458 | 459 | build_libdispatch() { 460 | if [ ! -f "${FAKEROOT_DIR}/usr/local/lib/kernel/libfirehose_kernel.a" ]; then 461 | running "📦 Building libdispatch" 462 | if [ ! -d "${WORK_DIR}/libdispatch" ]; then 463 | LIBDISPATCH_VERSION=$(curl -s $RELEASE_URL | jq -r '.projects[] | select(.project=="libdispatch") | .tag') 464 | git clone --branch "${LIBDISPATCH_VERSION}" https://github.com/apple-oss-distributions/libdispatch.git "${WORK_DIR}/libdispatch" 465 | fi 466 | SRCROOT="${WORK_DIR}/libdispatch" 467 | OBJROOT="${BUILD_DIR}/libfirehose_kernel.obj" 468 | SYMROOT="${BUILD_DIR}/libfirehose_kernel.sym" 469 | # libfirehose_kernel patch 470 | sed -i '' 's|$(SDKROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders|$(FAKEROOT_DIR)/System/Library/Frameworks/Kernel.framework/PrivateHeaders|g' "${SRCROOT}/xcodeconfig/libfirehose_kernel.xcconfig" 471 | sed -i '' 's|$(SDKROOT)/usr/local/include|$(FAKEROOT_DIR)/usr/local/include|g' "${SRCROOT}/xcodeconfig/libfirehose_kernel.xcconfig" 472 | cd "${SRCROOT}" 473 | xcodebuild install -target libfirehose_kernel -sdk macosx ARCHS="x86_64 arm64e" VALID_ARCHS="x86_64 arm64e" OBJROOT="${OBJROOT}" SYMROOT="${SYMROOT}" DSTROOT="${DSTROOT}" FAKEROOT_DIR="${FAKEROOT_DIR}" 474 | cd "${WORK_DIR}" 475 | mv "${FAKEROOT_DIR}/usr/local/lib/kernel/liblibfirehose_kernel.a" "${FAKEROOT_DIR}/usr/local/lib/kernel/libfirehose_kernel.a" 476 | fi 477 | } 478 | 479 | build_xnu() { 480 | if [ ! -f "${BUILD_DIR}/xnu.obj/kernel.${KERNEL_TYPE}" ]; then 481 | if [ "$JSONDB" -ne "0" ]; then 482 | running "📦 Building XNU kernel with JSON compilation database" 483 | if [ ! -d "${KDKROOT}" ]; then 484 | error "KDKROOT not found: ${KDKROOT} - please install from the Developer Portal" 485 | exit 1 486 | fi 487 | SRCROOT="${WORK_DIR}/xnu" 488 | OBJROOT="${BUILD_DIR}/xnu-compiledb.obj" 489 | SYMROOT="${BUILD_DIR}/xnu-compiledb.sym" 490 | rm -rf "${OBJROOT}" 491 | rm -rf "${SYMROOT}" 492 | cd "${SRCROOT}" 493 | make SDKROOT=macosx TARGET_CONFIGS="$KERNEL_CONFIG $ARCH_CONFIG $MACHINE_CONFIG" LOGCOLORS=y BUILD_WERROR=0 BUILD_LTO=0 BUILD_JSON_COMPILATION_DATABASE=1 SRCROOT="${SRCROOT}" OBJROOT="${OBJROOT}" SYMROOT="${SYMROOT}" DSTROOT="${DSTROOT}" FAKEROOT_DIR="${FAKEROOT_DIR}" KDKROOT="${KDKROOT}" TIGHTBEAMC=${TIGHTBEAMC} RC_DARWIN_KERNEL_VERSION=${RC_DARWIN_KERNEL_VERSION} || true 494 | JSON_COMPILE_DB="$(find "${OBJROOT}" -name compile_commands.json)" 495 | info "JSON compilation database: ${JSON_COMPILE_DB}" 496 | cp -f "${JSON_COMPILE_DB}" "${SRCROOT}" 497 | mkdir -p "${CACHE_DIR}/${MACOS_VERSION}" 498 | info "Caching JSON compilation database in: ${CACHE_DIR}/${MACOS_VERSION}" 499 | cp -f "${JSON_COMPILE_DB}" "${CACHE_DIR}/${MACOS_VERSION}" 500 | else 501 | running "📦 Building XNU kernel TARGET_CONFIGS=\"$KERNEL_CONFIG $ARCH_CONFIG $MACHINE_CONFIG\"" 502 | if [ ! -d "${KDKROOT}" ]; then 503 | error "KDKROOT not found: ${KDKROOT} - please install from the Developer Portal" 504 | exit 1 505 | fi 506 | SRCROOT="${WORK_DIR}/xnu" 507 | OBJROOT="${BUILD_DIR}/xnu.obj" 508 | SYMROOT="${BUILD_DIR}/xnu.sym" 509 | cd "${SRCROOT}" 510 | make install -j8 VERBOSE=YES SDKROOT=macosx TARGET_CONFIGS="$KERNEL_CONFIG $ARCH_CONFIG $MACHINE_CONFIG" CONCISE=0 LOGCOLORS=y BUILD_WERROR=0 BUILD_LTO=0 SRCROOT="${SRCROOT}" OBJROOT="${OBJROOT}" SYMROOT="${SYMROOT}" DSTROOT="${DSTROOT}" FAKEROOT_DIR="${FAKEROOT_DIR}" KDKROOT="${KDKROOT}" TIGHTBEAMC=${TIGHTBEAMC} RC_DARWIN_KERNEL_VERSION=${RC_DARWIN_KERNEL_VERSION} 511 | cd "${WORK_DIR}" 512 | fi 513 | else 514 | info "📦 XNU kernel.${KERNEL_TYPE} already built" 515 | fi 516 | } 517 | 518 | version_lte() { 519 | [ "$1" = "$(echo -e "$1\n$2" | sort -V | head -n1)" ] 520 | } 521 | 522 | version_lt() { 523 | [ "$1" = "$2" ] && return 1 || version_lte "$1" "$2" 524 | } 525 | 526 | build_kc() { 527 | if [ -f "${BUILD_DIR}/xnu.obj/kernel.${KERNEL_TYPE}" ]; then 528 | running "📦 Building kernel collection for kernel.${KERNEL_TYPE}" 529 | KDK_FLAG="" 530 | if version_lte 13.0 "$(sw_vers -productVersion | grep -Eo '[0-9]+\.[0-9]+')"; then 531 | KDK_FLAG="--kdk ${KDKROOT}" # Newer versions of kmutil support the --kdk option 532 | fi 533 | if [ "$ARCH_CONFIG" == "ARM64" ]; then 534 | kmutil create -v -V "${KC_VARIANT}" -a arm64e -n boot -s none \ 535 | ${KDK_FLAG} \ 536 | -B "${DSTROOT}/oss-xnu.macOS.${MACOS_VERSION}.kc.$(echo "$MACHINE_CONFIG" | tr '[:upper:]' '[:lower:]')" \ 537 | -k "${BUILD_DIR}/xnu.obj/kernel.${KERNEL_TYPE}" \ 538 | -x $(ipsw kernel kmutil inspect -x --filter "${KC_FILTER}") # this will skip KC_FILTER regex (and other KEXTs with them as dependencies) 539 | # -x $(kmutil inspect -V release --no-header | grep apple | grep -v "SEPHibernation" | awk '{print " -b "$1; }') 540 | else 541 | kmutil create -v -V "${KC_VARIANT}" -a x86_64 -n boot sys -s none \ 542 | ${KDK_FLAG} \ 543 | -B "${DSTROOT}/BootKernelExtensions.${MACOS_VERSION}.$(echo "$MACHINE_CONFIG" | tr '[:upper:]' '[:lower:]').kc" \ 544 | -S "${DSTROOT}/SystemKernelExtensions.${MACOS_VERSION}.$(echo "$MACHINE_CONFIG" | tr '[:upper:]' '[:lower:]').kc" \ 545 | -k "${BUILD_DIR}/xnu.obj/kernel.${KERNEL_TYPE}" \ 546 | --elide-identifier com.apple.ExclaveKextClient \ 547 | -x $(ipsw kernel kmutil inspect -x --filter "${KC_FILTER}") # this will skip KC_FILTER regex (and other KEXTs with them as dependencies) 548 | # -x $(kmutil inspect -V release --no-header | grep apple | grep -v "SEPHibernation" | awk '{print " -b "$1; }') 549 | fi 550 | echo " 🎉 KC Build Done!" 551 | fi 552 | } 553 | 554 | main() { 555 | # Parse arguments 556 | while test $# -gt 0; do 557 | case "$1" in 558 | -h | --help) 559 | help 560 | ;; 561 | -c | --clean) 562 | clean 563 | shift 564 | ;; 565 | -k | --kc) 566 | BUILDKC=1 567 | shift 568 | ;; 569 | *) 570 | break 571 | ;; 572 | esac 573 | done 574 | install_deps 575 | choose_xnu 576 | get_xnu 577 | patches 578 | venv 579 | build_bootstrap_cmds 580 | build_dtrace 581 | build_availabilityversions 582 | xnu_headers 583 | libsystem_headers 584 | libsyscall_headers 585 | build_libplatform 586 | build_libdispatch 587 | build_xnu 588 | echo " 🎉 XNU Build Done!" 589 | if [ "$BUILDKC" -ne "0" ]; then 590 | install_ipsw 591 | build_kc 592 | fi 593 | } 594 | 595 | main "$@" 596 | -------------------------------------------------------------------------------- /codeql.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # CREDIT: https://github.com/pwn0rz/xnu-build 4 | 5 | set -o errexit 6 | set -o nounset 7 | set -o pipefail 8 | if [[ "${TRACE-0}" == "1" ]]; then 9 | set -o xtrace 10 | fi 11 | 12 | # Help 13 | if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then 14 | echo 'Usage: codeql.sh 15 | 16 | This script creates the macOS xnu kernel codeql database 17 | 18 | ' 19 | exit 20 | fi 21 | 22 | # Colors 23 | export ESC_SEQ="\x1b[" 24 | export COL_RESET=$ESC_SEQ"39;49;00m" 25 | export COL_RED=$ESC_SEQ"31;01m" 26 | export COL_GREEN=$ESC_SEQ"32;01m" 27 | export COL_YELLOW=$ESC_SEQ"33;01m" 28 | export COL_BLUE=$ESC_SEQ"34;01m" 29 | export COL_MAGENTA=$ESC_SEQ"35;01m" 30 | export COL_CYAN=$ESC_SEQ"36;01m" 31 | 32 | function running() { 33 | echo -e "$COL_MAGENTA ⇒ $COL_RESET""$1" 34 | } 35 | 36 | function info() { 37 | echo -e "$COL_BLUE[info] $COL_RESET""$1" 38 | } 39 | 40 | : ${KERNEL_CONFIG:=RELEASE} 41 | : ${ARCH_CONFIG:=ARM64} 42 | : ${MACHINE_CONFIG:=VMAPPLE} 43 | : ${XNU_VERSION:=''} 44 | 45 | function install_codeql() { 46 | if ! [ -x "$(command -v codeql)" ]; then 47 | running "Installing CodeQL..." 48 | brew install codeql 49 | fi 50 | } 51 | 52 | function create_db() { 53 | WORK_DIR="$PWD" 54 | BUILD_DIR="${WORK_DIR}/build" 55 | FAKEROOT_DIR="${WORK_DIR}/fakeroot" 56 | DATABASE_DIR="${WORK_DIR}/xnu-codeql" 57 | rm -rf "${BUILD_DIR}" 58 | rm -rf "${FAKEROOT_DIR}" 59 | rm -rf "${DATABASE_DIR}" 60 | running "📦 Creating the CodeQL database..." 61 | XNU_VERSION=${XNU_VERSION} KERNEL_CONFIG=${KERNEL_CONFIG} ARCH_CONFIG=${ARCH_CONFIG} MACHINE_CONFIG=${MACHINE_CONFIG} CODEQL=1 codeql database create "${DATABASE_DIR}" --language=cpp -v --command="${WORK_DIR}"/build.sh --source-root="${WORK_DIR}" 62 | info "Deleting log files..." 63 | rm -rf "${DATABASE_DIR}"/log 64 | info "Zipping the CodeQL database..." 65 | zip -r -X xnu-codeql.zip xnu-codeql/* 66 | } 67 | 68 | main() { 69 | install_codeql 70 | create_db 71 | echo " 🎉 CodeQL Database Create Done!" 72 | } 73 | 74 | main "$@" -------------------------------------------------------------------------------- /patches/14.4/TrustCache.patch: -------------------------------------------------------------------------------- 1 | diff --git a/EXTERNAL_HEADERS/TrustCache/API.h b/EXTERNAL_HEADERS/TrustCache/API.h 2 | new file mode 100644 3 | index 00000000..d13cddf3 4 | --- /dev/null 5 | +++ b/EXTERNAL_HEADERS/TrustCache/API.h 6 | @@ -0,0 +1,188 @@ 7 | +#ifndef libTrustCache_API_h 8 | +#define libTrustCache_API_h 9 | + 10 | +#include 11 | +__BEGIN_DECLS 12 | + 13 | +#include 14 | +#include 15 | +#include 16 | +#include 17 | +#include 18 | +#include 19 | +#include 20 | + 21 | +/** 22 | + * NOTE: This library does not enforce any concurrency by itself. To be safe in a multi-threaded 23 | + * environment, the caller must manually enforce concurrency on the runtime data structure as 24 | + * otherwise the library is susceptible to memory corruption from race conditions. 25 | + */ 26 | + 27 | +/** 28 | + * Initialize a runtime to the default values. 29 | + * 30 | + * If the system supports read-only segments, and the runtime is allocated within the read-only 31 | + * segment, then this function needs to be called before the segment is enforced to be read-only. 32 | + * For more information, please look at . 33 | + */ 34 | +static inline void 35 | +trustCacheInitializeRuntime(TrustCacheRuntime_t *runtime, 36 | + TrustCacheMutableRuntime_t *mutableRT, 37 | + bool allowSecondStaticTC, 38 | + bool allowEngineeringTC, 39 | + bool allowLegacyTC, 40 | + const img4_runtime_t *image4RT) 41 | +{ 42 | + /* Zero out everything */ 43 | + memset(runtime, 0, sizeof(*runtime)); 44 | + memset(mutableRT, 0, sizeof(*mutableRT)); 45 | + 46 | + /* Set the mutable runtime pointer */ 47 | + runtime->mutableRT = mutableRT; 48 | + 49 | + /* Setup trust cache type permissions */ 50 | + runtime->allowSecondStaticTC = allowSecondStaticTC; 51 | + runtime->allowEngineeringTC = allowEngineeringTC; 52 | + runtime->allowLegacyTC = allowLegacyTC; 53 | + 54 | + /* Set the image4 runtime */ 55 | + runtime->image4RT = image4RT; 56 | +} 57 | + 58 | +/** 59 | + * Construct a trust cache object from some module bytes. The module is validated for 60 | + * correctness before being returned. 61 | + */ 62 | +TCReturn_t 63 | +trustCacheConstructInvalid(TrustCache_t *trustCache, 64 | + const uint8_t *moduleAddr, 65 | + size_t moduleSize); 66 | + 67 | +/** 68 | + * Check the runtime for a trust cache which matches a particular UUID. Since we do 69 | + * not allow trust caches with duplocate UUIDs, there can only ever be a single trust 70 | + * cache with a particular UUID within the runtime. 71 | + */ 72 | +TCReturn_t 73 | +trustCacheCheckRuntimeForUUID(const TrustCacheRuntime_t *runtime, 74 | + const uint8_t checkUUID[kUUIDSize], 75 | + const TrustCache_t **trustCacheRet); 76 | + 77 | +/** 78 | + * Add a trust cache module directly to the runtime. This function is used to add modules which 79 | + * don't need to be separately authenticated. Currently, the only trust cache types which can be 80 | + * used with this function are static and engineering trust caches. 81 | + * 82 | + * If the system supports read-only segments, and the runtime is allocated within the read-only 83 | + * segment, then this function needs to be called before the segment is enforced to be read-only. 84 | + * For more information, please look at . 85 | + */ 86 | +TCReturn_t 87 | +trustCacheLoadModule(TrustCacheRuntime_t *runtime, 88 | + const TCType_t type, 89 | + TrustCache_t *trustCache, 90 | + const uintptr_t dataAddr, 91 | + const size_t dataSize); 92 | + 93 | +/** 94 | + * Load a trust cache onto the system. This function validates the trust cache for a proper 95 | + * signature and adds it to the runtime. 96 | + * 97 | + * Both the payload and the manifest must be provided and they will be validated as image4 98 | + * objects. 99 | + */ 100 | +TCReturn_t 101 | +trustCacheLoad(TrustCacheRuntime_t *runtime, 102 | + TCType_t type, 103 | + TrustCache_t *trustCache, 104 | + const uintptr_t payloadAddr, 105 | + const size_t payloadSize, 106 | + const uintptr_t manifestAddr, 107 | + const size_t manifestSize); 108 | + 109 | +/** 110 | + * Extract an image4 artifact from an image4 file or an image4 payload and extract the 111 | + * trust cache module embedded within it. The module is validated for correctness 112 | + * before being returned, however the image4 signature is not verified. 113 | + * 114 | + * The returned trust cache object is marked with an invalid type. 115 | + */ 116 | +TCReturn_t 117 | +trustCacheExtractModule(TrustCache_t *trustCache, 118 | + const uint8_t *dataAddr, 119 | + size_t dataSize); 120 | + 121 | +/** 122 | + * Query a trust cache for a particular CDHash. The returned token can then be used to 123 | + * query further attributes from the matched entry. 124 | + */ 125 | +TCReturn_t 126 | +trustCacheQuery(const TrustCacheRuntime_t *runtime, 127 | + TCQueryType_t queryType, 128 | + const uint8_t CDHash[kTCEntryHashSize], 129 | + TrustCacheQueryToken_t *queryToken); 130 | + 131 | +/** 132 | + * Get the module bytes backng a trust cache object. The environment may have chosen 133 | + * to allocate the module bytes within read-only memory, so the bytes returned may 134 | + * not be mutable. 135 | + */ 136 | +TCReturn_t 137 | +trustCacheGetModule(const TrustCache_t *trustCache, 138 | + const uint8_t **moduleAddrRet, 139 | + size_t *moduleSizeRet); 140 | + 141 | +/** 142 | + * Get the UUID of the trust cache module represented by the wrapped trust cache object. 143 | + */ 144 | +TCReturn_t 145 | +trustCacheGetUUID(const TrustCache_t *trustCache, 146 | + uint8_t returnUUID[kUUIDSize]); 147 | + 148 | +/** 149 | + * Get the capabilities of a trust cache. This function can be used to query which fields a given 150 | + * trust cache supports. 151 | + * 152 | + * The fields which are supported are based on the version of the trust cache module. 153 | + */ 154 | +TCReturn_t 155 | +trustCacheGetCapabilities(const TrustCache_t *trustCache, 156 | + TCCapabilities_t *capabilities); 157 | + 158 | +/** 159 | + * Acquire the trust cache type for a query token. 160 | + */ 161 | +TCReturn_t 162 | +trustCacheQueryGetTCType(const TrustCacheQueryToken_t *queryToken, 163 | + TCType_t *typeRet); 164 | + 165 | +/** 166 | + * Acquire the capabilities of the trust cache through a query token. 167 | + */ 168 | +TCReturn_t 169 | +trustCacheQueryGetCapabilities(const TrustCacheQueryToken_t *queryToken, 170 | + TCCapabilities_t *capabilities); 171 | + 172 | +/** 173 | + * Acquire the hash type for the CDHash through a query token. 174 | + */ 175 | +TCReturn_t 176 | +trustCacheQueryGetHashType(const TrustCacheQueryToken_t *queryToken, 177 | + uint8_t *hashTypeRet); 178 | + 179 | +/** 180 | + * Acquire the flags for a trust cache entry through a query token. 181 | + */ 182 | +TCReturn_t 183 | +trustCacheQueryGetFlags(const TrustCacheQueryToken_t *queryToken, 184 | + uint64_t *flagsRet); 185 | + 186 | +/** 187 | + * Acquire the constraint category for a trust cache entry through a query token. 188 | + */ 189 | +TCReturn_t 190 | +trustCacheQueryGetConstraintCategory(const TrustCacheQueryToken_t *queryToken, 191 | + uint8_t *constraintCategoryRet); 192 | + 193 | +__END_DECLS 194 | +#endif /* libTrustCache_API_h */ 195 | diff --git a/EXTERNAL_HEADERS/TrustCache/RawTypes.h b/EXTERNAL_HEADERS/TrustCache/RawTypes.h 196 | new file mode 100644 197 | index 00000000..16b684e2 198 | --- /dev/null 199 | +++ b/EXTERNAL_HEADERS/TrustCache/RawTypes.h 200 | @@ -0,0 +1,103 @@ 201 | +#ifndef libTrustCache_RawTypes_h 202 | +#define libTrustCache_RawTypes_h 203 | + 204 | +#include 205 | +__BEGIN_DECLS 206 | + 207 | +#include 208 | +#include 209 | + 210 | +/* 211 | + * CDHashes in the trust cache are always truncated to the length of a SHA1 hash. 212 | + */ 213 | +#define kTCEntryHashSize CCSHA1_OUTPUT_SIZE 214 | + 215 | +/* UUIDs are always 16 bytes */ 216 | +#define kUUIDSize 16 217 | + 218 | +/* Versions supported by the library */ 219 | +enum { 220 | + kTCVersion0 = 0x0, 221 | + kTCVersion1 = 0x1, 222 | + kTCVersion2 = 0x2, 223 | + 224 | + kTCVersionTotal, 225 | +}; 226 | + 227 | +/* Flags for the trust cache look ups */ 228 | +enum { 229 | + kTCFlagAMFID = 0x01, 230 | + kTCFlagANEModel = 0x02, 231 | +}; 232 | + 233 | +typedef struct _TrustCacheModuleBase { 234 | + /* The version for this trust cache module */ 235 | + uint32_t version; 236 | +} __attribute__((packed)) TrustCacheModuleBase_t; 237 | + 238 | +#pragma mark Trust Cache Version 0 239 | + 240 | +typedef uint8_t TrustCacheEntry0_t[kTCEntryHashSize]; 241 | + 242 | +typedef struct _TrustCacheModule0 { 243 | + /* Must be 0 */ 244 | + uint32_t version; 245 | + 246 | + /* ID which uniquely identifies the trust cache */ 247 | + uint8_t uuid[kUUIDSize]; 248 | + 249 | + /* The number of entries present in the trust cache */ 250 | + uint32_t numEntries; 251 | + 252 | + /* Dynamic data containing all the entries */ 253 | + TrustCacheEntry0_t entries[0]; 254 | +} __attribute__((packed)) TrustCacheModule0_t; 255 | + 256 | +#pragma mark Trust Cache Version 1 257 | + 258 | +typedef struct _TrustCacheEntry1 { 259 | + uint8_t CDHash[kTCEntryHashSize]; 260 | + uint8_t hashType; 261 | + uint8_t flags; 262 | +} __attribute__((packed)) TrustCacheEntry1_t; 263 | + 264 | +typedef struct _TrustCacheModule1 { 265 | + /* Must be 1 */ 266 | + uint32_t version; 267 | + 268 | + /* ID which uniquely identifies the trust cache */ 269 | + uint8_t uuid[kUUIDSize]; 270 | + 271 | + /* The number of entries present in the trust cache */ 272 | + uint32_t numEntries; 273 | + 274 | + /* Dynamic data containing all the entries */ 275 | + TrustCacheEntry1_t entries[0]; 276 | +} __attribute__((packed)) TrustCacheModule1_t; 277 | + 278 | +#pragma mark Trust Cache Version 2 279 | + 280 | +typedef struct _TrustCacheEntry2 { 281 | + uint8_t CDHash[kTCEntryHashSize]; 282 | + uint8_t hashType; 283 | + uint8_t flags; 284 | + uint8_t constraintCategory; 285 | + uint8_t reserved0; 286 | +} __attribute__((packed)) TrustCacheEntry2_t; 287 | + 288 | +typedef struct _TrustCacheModule2 { 289 | + /* Must be 2 */ 290 | + uint32_t version; 291 | + 292 | + /* ID which uniquely identifies the trust cache */ 293 | + uint8_t uuid[kUUIDSize]; 294 | + 295 | + /* The number of entries present in the trust cache */ 296 | + uint32_t numEntries; 297 | + 298 | + /* Dynamic data containing all the entries */ 299 | + TrustCacheEntry2_t entries[0]; 300 | +} __attribute__((packed)) TrustCacheModule2_t; 301 | + 302 | +__END_DECLS 303 | +#endif /* libTrustCache_RawTypes_h */ 304 | diff --git a/EXTERNAL_HEADERS/TrustCache/Return.h b/EXTERNAL_HEADERS/TrustCache/Return.h 305 | new file mode 100644 306 | index 00000000..440a53c4 307 | --- /dev/null 308 | +++ b/EXTERNAL_HEADERS/TrustCache/Return.h 309 | @@ -0,0 +1,123 @@ 310 | +#ifndef libTrustCache_Return_h 311 | +#define libTrustCache_Return_h 312 | + 313 | +#include 314 | +__BEGIN_DECLS 315 | + 316 | +#include 317 | + 318 | +/* Components which can return information from the library */ 319 | +enum { 320 | + kTCComponentLoadModule = 0x00, 321 | + kTCComponentLoad = 0x01, 322 | + kTCComponentImage4Validate = 0x02, 323 | + kTCComponentImage4Callback = 0x03, 324 | + kTCComponentConstructInvalid = 0x04, 325 | + kTCComponentCheckRuntimeForUUID = 0x05, 326 | + kTCComponentExtractModule = 0x06, 327 | + kTCComponentGetUUID = 0x07, 328 | + kTCComponentGetModule = 0x08, 329 | + 330 | + /* Query Functions */ 331 | + kTCComponentQuery = 0x10, 332 | + kTCComponentQueryChain = 0x11, 333 | + kTCComponentQueryRuntime = 0x12, 334 | + kTCComponentQueryTCType = 0x13, 335 | + kTCComponentQueryHashType = 0x14, 336 | + kTCComponentQueryFlags = 0x15, 337 | + kTCComponentQueryConstraintCategory = 0x16, 338 | + 339 | + /* Module based */ 340 | + kTCComponentQueryModule = 0x40, 341 | + kTCComponentValidateModule = 0x41, 342 | + kTCComponentQueryModule0 = 0x42, 343 | + kTCComponentValidateModule0 = 0x43, 344 | + kTCComponentQueryModule1 = 0x44, 345 | + kTCComponentValidateModule1 = 0x45, 346 | + kTCComponentQueryModule2 = 0x46, 347 | + kTCComponentValidateModule2 = 0x47, 348 | + kTCComponentModuleCapabilities = 0x48, 349 | + 350 | + /* Other functions which can return a value */ 351 | + kTCComponentLinkedListAddHead = 0x80, 352 | + kTCComponentLinkedListRemove = 0x81, 353 | + kTCComponentExtractImage4Payload = 0x82, 354 | + 355 | + /* Cannot exceed this value */ 356 | + kTCComponentTotal = 0xFF, 357 | +}; 358 | + 359 | +/* Error types which can be returned from the library */ 360 | +enum { 361 | + kTCReturnSuccess = 0x00, 362 | + 363 | + /* Generic error condition - avoid using this */ 364 | + kTCReturnError = 0x01, 365 | + 366 | + /* Specific error conditions */ 367 | + kTCReturnOverflow = 0x20, 368 | + kTCReturnUnsupported = 0x21, 369 | + kTCReturnInvalidModule = 0x22, 370 | + kTCReturnDuplicate = 0x23, 371 | + kTCReturnNotFound = 0x24, 372 | + kTCReturnInvalidArguments = 0x25, 373 | + kTCReturnInsufficientLength = 0x26, 374 | + kTCReturnNotPermitted = 0x27, 375 | + kTCReturnLinkedListCorrupted = 0x28, 376 | + 377 | + /* Image 4 return errors */ 378 | + kTCReturnImage4Expired = 0xA0, 379 | + kTCReturnImage4UnknownFormat = 0xA1, 380 | + kTCReturnImage4WrongObject = 0xA2, 381 | + kTCReturnImage4WrongCrypto = 0xA3, 382 | + kTCReturnImage4ManifestViolation = 0xA4, 383 | + kTCReturnImage4PayloadViolation = 0xA5, 384 | + kTCReturnImage4PermissionDenied = 0xA6, 385 | + kTCReturnImage4NoChipAvailable = 0xA7, 386 | + kTCReturnImage4NoNonceAvailable = 0xA8, 387 | + kTCReturnImage4NoDeviceAvailable = 0xA9, 388 | + kTCReturnImage4DecodeError = 0xAA, 389 | + kTCReturnImage4UnknownError = 0xAF, 390 | + 391 | + /* Cannot exceed this value */ 392 | + kTCReturnTotal = 0xFF 393 | +}; 394 | + 395 | +typedef struct _TCReturn { 396 | + union { 397 | + /* Raw 32 bit representation of the return code */ 398 | + uint32_t rawValue; 399 | + 400 | + /* Formatted representation of the return code */ 401 | + struct { 402 | + /* Component of the library which is returning the code */ 403 | + uint8_t component; 404 | + 405 | + /* Error code which is being returned */ 406 | + uint8_t error; 407 | + 408 | + /* Unique error path within the component */ 409 | + uint16_t uniqueError; 410 | + } __attribute__((packed)); 411 | + } __attribute__((packed)); 412 | +} __attribute__((packed)) TCReturn_t; 413 | + 414 | +/* Ensure the size of the structure remains as expected */ 415 | +_Static_assert(sizeof(TCReturn_t) == sizeof(uint32_t), "TCReturn_t is not 32 bits large"); 416 | + 417 | +static inline TCReturn_t 418 | +buildTCRet(uint8_t component, 419 | + uint8_t error, 420 | + uint16_t uniqueError) 421 | +{ 422 | + TCReturn_t ret = { 423 | + .component = component, 424 | + .error = error, 425 | + .uniqueError = uniqueError 426 | + }; 427 | + 428 | + return ret; 429 | +} 430 | + 431 | +__END_DECLS 432 | +#endif /* libTrustCache_Return_h */ 433 | diff --git a/EXTERNAL_HEADERS/TrustCache/Types.h b/EXTERNAL_HEADERS/TrustCache/Types.h 434 | new file mode 100644 435 | index 00000000..f3412f38 436 | --- /dev/null 437 | +++ b/EXTERNAL_HEADERS/TrustCache/Types.h 438 | @@ -0,0 +1,320 @@ 439 | +#ifndef libTrustCache_Types_h 440 | +#define libTrustCache_Types_h 441 | + 442 | +#include 443 | +__BEGIN_DECLS 444 | + 445 | +#include 446 | +#include 447 | +#include 448 | + 449 | +typedef uint8_t TCType_t; 450 | +enum { 451 | + /* 452 | + * These types of trust caches are always loaded as modules. Their validation 453 | + * is done externally by upper-level software. 454 | + * 455 | + * Static trust caches are bundled with the operating system and are the primary 456 | + * method of denoting platform trust. Engineering trust caches are similar to 457 | + * static trust caches except that they can be created by engineers at their 458 | + * desk as a root for a static trust cache. Legacy trust caches are image3 signed 459 | + * modules. This library does not support validating image3 signatures, so it 460 | + * accepts the trust caches only as direct modules. These are still considered 461 | + * loadable trust caches. 462 | + */ 463 | + kTCTypeStatic = 0x00, 464 | + kTCTypeEngineering = 0x01, 465 | + kTCTypeLegacy = 0x02, 466 | + 467 | + /* 468 | + * Do NOT change the order of the types listed here. This header is shared across 469 | + * a variety of projects and they update at different cadences. Adding a new type 470 | + * requires appending to the end of the enumeration, instead of insertion in the 471 | + * middle somewhere. 472 | + */ 473 | + 474 | + /* 475 | + * Type: Personalized 476 | + * These are engineering roots which are only ever valid for development devices. 477 | + * These can be created by engineers at their desks for testing software. 478 | + */ 479 | + kTCTypeDTRS = 0x03, 480 | + 481 | + /* 482 | + * Type: Personalized 483 | + * These are loadable trust caches which are viable for all kinds of devices and 484 | + * can be used for testing, but also for shipping code in production devices. 485 | + */ 486 | + kTCTypeLTRS = 0x04, 487 | + 488 | + /* 489 | + * Type: Personalized 490 | + * Used by disk images which are used to supply platform code for a number of use 491 | + * cases, including the multidude of disk images supplied for engineering use-cases 492 | + * such as the factoey disk image. 493 | + */ 494 | + kTCTypePersonalizedDiskImage = 0x05, 495 | + 496 | + /* 497 | + * Type: Categorized 498 | + * Developer disk images which are personalized per device. These have a different 499 | + * tag than standard loadable trust caches and helps differentiate them. However, 500 | + * these were never productionized and are for all purposes, retired. 501 | + */ 502 | + kTCTypeDeveloperDiskImage = 0x06, 503 | + 504 | + /* 505 | + * Type: Personalized 506 | + * These trust caches are similar to a personalized LTRS trust cache type except 507 | + * they are personalized against a long lived nonce, allowing these to remain 508 | + * useable across reboots of the system. 509 | + */ 510 | + kTCTypeLTRSWithDDINonce = 0x07, 511 | + 512 | + /* 513 | + * Type: Personalized 514 | + * These trust cache types are used to authenticate code shipped in Cryptexes for 515 | + * security research devices. Outside of the SRD, these are also used in some data 516 | + * center use cases which deploy code through Cryptexes. 517 | + */ 518 | + kTCTypeCryptex = 0x08, 519 | + 520 | + /* 521 | + * Type: Personalized (against supplemental root) 522 | + * These are special trust caches which validate against a supplemental root beyond 523 | + * Tatsu. These are only meant for special deployments within some data centers. 524 | + * 525 | + * NOTE: This type is deprecated in favor of the newer Supplemental Persistent 526 | + * and Supplemental Ephemeral types. 527 | + */ 528 | + kTCTypeEphemeralCryptex = 0x09, 529 | + 530 | + /* 531 | + * Type: Global 532 | + * OTA updates ship an update brain to assist with the OS update. The brain is some 533 | + * code with platform privileges which can do whatever the current OS needs it to do 534 | + * in order to update the system. 535 | + */ 536 | + kTCTypeUpdateBrain = 0x0A, 537 | + 538 | + /* 539 | + * Type: Global 540 | + * Trust caches which are loaded by the Install Assistant on macOS in order to help 541 | + * with installing macOS. 542 | + */ 543 | + kTCTypeInstallAssistant = 0x0B, 544 | + 545 | + /* 546 | + * Type: Global 547 | + * These are used by macOS systems to ship a bootability brain. The bootability brain 548 | + * is a piece of code which helps determine if macOS systems of a different version 549 | + * are bootable or not. The brain is useful because the logic for determining that a 550 | + * system is bootable or not differs with each release. 551 | + */ 552 | + kTCTypeBootabilityBrain = 0x0C, 553 | + 554 | + /* 555 | + * Type: Personalized (against Cryptex 1 Boot/Preboot environments) 556 | + * These trust cache types are used by SPLAT at different stages of the boot pipeline 557 | + * for loading code responsible for system boot up, such as the shared cache. 558 | + * 559 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 560 | + * manifest itself. 561 | + */ 562 | + kTCTypeCryptex1BootOS = 0x0D, 563 | + kTCTypeCryptex1BootApp = 0x0E, 564 | + kTCTypeCryptex1PreBootApp = 0x0F, 565 | + 566 | + /* 567 | + * Type: Global 568 | + * These are disk images which are globally signed against the FF00 chip environment. 569 | + * They are used when disk images want to supply code for devices across the fleet 570 | + * without requiring individual personalization for each. 571 | + * 572 | + * The developer disk image is supplied through this mechanism as well, as of January 573 | + * 5th, 2022. 574 | + */ 575 | + kTCTypeGlobalDiskImage = 0x10, 576 | + 577 | + /* 578 | + * Type: Personalized (Cryptex1 mobile asset brain) 579 | + * The mobile asset brain contains the core logic for mobileassetd, which is a system 580 | + * daemon responsible for downloading and maintaining assets on the device. The brain 581 | + * is meant to be back-deployable, which is what the trust cache helps with. 582 | + * 583 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 584 | + * manifest itself. 585 | + */ 586 | + kTCTypeMobileAssetBrain = 0x11, 587 | + 588 | + /* 589 | + * Type: Personalized (Cryptex1 boot reduced) 590 | + * Safari is backported to older builds. Since Safari is now moving to a SPLAT based 591 | + * mount volume, we need to support loading a trust cache which is used to mount and 592 | + * run Safari from the future. 593 | + * 594 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 595 | + * manifest itself. 596 | + */ 597 | + kTCTypeSafariDownlevel = 0x12, 598 | + 599 | + /* 600 | + * Type: Personalized (Cryptex 1 Preboot) 601 | + * This trust cache type is used for the semi-SPLAT use-case for loading the new dyld 602 | + * shared cache onto the platform, along with some other system libraries. This is 603 | + * only required for macOS. 604 | + * 605 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 606 | + * manifest itself. 607 | + */ 608 | + kTCTypeCryptex1PreBootOS = 0x13, 609 | + 610 | + /* 611 | + * Type: Personalized (Supplemental Root) 612 | + * Persistent trust caches which are signed by an authority different from Tatsu. 613 | + * These are only required for deployment on darwinOS platforms. 614 | + */ 615 | + kTCTypeSupplementalPersistent = 0x14, 616 | + 617 | + /* 618 | + * Type: Personalized (Supplemental Root) 619 | + * Ephemeral trust caches which are signed by an authority different from Tatsu. 620 | + * These are only required for deployment on darwinOS platforms. 621 | + */ 622 | + kTCTypeSupplementalEphemeral = 0x15, 623 | + 624 | + /* 625 | + * Type: Personalized (Cryptex1 Generic) 626 | + * This type can be used by the assortment of PDIs we ship. Each PDI train can opt 627 | + * into allocating a Cryptex1 sub-type for itself, and then ship on the OS being 628 | + * signed by the Cryptex1 generic environment. This allows the PDI to adopt Cryptex1 629 | + * personalization without requiring a new bespoke trust cache type. 630 | + * 631 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 632 | + * manifest itself. 633 | + */ 634 | + kTCTypeCryptex1Generic = 0x16, 635 | + 636 | + /* 637 | + * Type: Personalized (Cryptex1 Generic Supplemental) 638 | + * Similar to the kTCTypeCryptex1Generic type except the manifest is signed by the 639 | + * supplemental root of trust. Only viable for some data center use-cases. 640 | + * 641 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 642 | + * manifest itself. 643 | + */ 644 | + kTCTypeCryptex1GenericSupplemental = 0x17, 645 | + 646 | + kTCTypeTotal, 647 | + 648 | + /* Invalid type */ 649 | + kTCTypeInvalid = 0xFF, 650 | +}; 651 | + 652 | +/* Availability macros for different trust cache types */ 653 | +#define kLibTrustCacheHasCryptex1BootOS 1 654 | +#define kLibTrustCacheHasCryptex1BootApp 1 655 | +#define kLibTrustCacheHasCryptex1PreBootApp 1 656 | +#define kLibTrustCacheHasMobileAssetBrain 1 657 | +#define kLibTrustCacheHasSafariDownlevel 1 658 | +#define kLibTrustCacheHasCryptex1PreBootOS 1 659 | +#define kLibTrustCacheHasSupplementalPersistent 1 660 | +#define kLibTrustCacheHasSupplementalEphemeral 1 661 | +#define kLibTrustCacheHasCryptex1Generic 1 662 | +#define kLibTrustCacheHasCryptex1GenericSupplemental 1 663 | + 664 | +typedef struct _TrustCache { 665 | + /* Linked list linkage for the trust cache */ 666 | + struct _TrustCache *next; 667 | + struct _TrustCache *prev; 668 | + 669 | + /* The type of this trust cache */ 670 | + TCType_t type; 671 | + 672 | + /* TODO: Add reference counts when we support unloading */ 673 | + 674 | + /* The trust cache module itself */ 675 | + size_t moduleSize; 676 | + const TrustCacheModuleBase_t *module; 677 | +} TrustCache_t; 678 | + 679 | +typedef uint8_t TCQueryType_t; 680 | +enum { 681 | + /* Query all types of trust caches in the runtime */ 682 | + kTCQueryTypeAll = 0x00, 683 | + 684 | + /* Static query type includes engineering trust caches */ 685 | + kTCQueryTypeStatic = 0x01, 686 | + 687 | + /* Most first party trust cache types are loadable ones */ 688 | + kTCQueryTypeLoadable = 0x02, 689 | + 690 | + kTCQueryTypeTotal, 691 | +}; 692 | + 693 | +typedef uint64_t TCCapabilities_t; 694 | +enum { 695 | + /* Supports no capabilities */ 696 | + kTCCapabilityNone = 0, 697 | + 698 | + /* Supports the hash type field */ 699 | + kTCCapabilityHashType = (1 << 0), 700 | + 701 | + /* Supports the flags field */ 702 | + kTCCapabilityFlags = (1 << 1), 703 | + 704 | + /* Supports the constraints category field */ 705 | + kTCCapabilityConstraintsCategory = (1 << 2), 706 | +}; 707 | + 708 | +typedef struct _TrustCacheQueryToken { 709 | + /* Trust cache where query was found */ 710 | + const TrustCache_t *trustCache; 711 | + 712 | + /* Entry within the trust cache where query was found */ 713 | + const void *trustCacheEntry; 714 | +} TrustCacheQueryToken_t; 715 | + 716 | +/* 717 | + * The runtime data structure is setup in a very special way. To make use of HW mitigations 718 | + * offered by the silicon, the runtime can be placed in a region which is locked down by the 719 | + * HW at some commit point. This theoretically allows the static and the engineering trust 720 | + * caches to be locked down and immutable if the storage for the trust cache data structure 721 | + * is also allocated within this same immutable memory segment. 722 | + * 723 | + * At the same time, we need to be able to support dynamically loaded trust caches on the 724 | + * system. We can't keep a list head within the runtime for these trust caches, since that 725 | + * head will be locked down when the runtime is locked, preventing us from adding a new link 726 | + * in the chain. To solve this, the runtime instead stores a pointer to a wrapped data structure. 727 | + * This pointer itself is locked down and can't be changed, but the contents of the wrapped 728 | + * structure are mutable, making it a good place to store the linked list head. 729 | + */ 730 | + 731 | +/* Data structure expected to be stored within mutable memory */ 732 | +typedef struct _TrustCacheMutableRuntime { 733 | + /* Loadable trust caches on the system */ 734 | + TrustCache_t *loadableTCHead; 735 | +} TrustCacheMutableRuntime_t; 736 | + 737 | +/* Data structure expected to be stored within immutable memory */ 738 | +typedef struct _TrustCacheRuntime { 739 | + /* Runtime to use for image 4 object verification */ 740 | + const img4_runtime_t *image4RT; 741 | + 742 | + /* Configuration for trust cache types */ 743 | + bool allowSecondStaticTC; 744 | + bool allowEngineeringTC; 745 | + bool allowLegacyTC; 746 | + 747 | + /* Static trust cache for the system */ 748 | + TrustCache_t *staticTCHead; 749 | + 750 | + /* Engineering trust caches for the system */ 751 | + TrustCache_t *engineeringTCHead; 752 | + 753 | + /* Mutable runtime instance */ 754 | + TrustCacheMutableRuntime_t *mutableRT; 755 | +} TrustCacheRuntime_t; 756 | + 757 | +__END_DECLS 758 | +#endif /* libTrustCache_Types_h */ 759 | diff --git a/EXTERNAL_HEADERS/TrustCache/TypesConfig.h b/EXTERNAL_HEADERS/TrustCache/TypesConfig.h 760 | new file mode 100644 761 | index 00000000..d93e8b09 762 | --- /dev/null 763 | +++ b/EXTERNAL_HEADERS/TrustCache/TypesConfig.h 764 | @@ -0,0 +1,389 @@ 765 | +#ifndef libTrustCache_TypesConfig_h 766 | +#define libTrustCache_TypesConfig_h 767 | + 768 | +#include 769 | +__BEGIN_DECLS 770 | + 771 | +#include 772 | + 773 | +#if XNU_KERNEL_PRIVATE 774 | +/* 775 | + * The AppleImage4 API definitions are accessed through the 'img4if' indirection 776 | + * layer within XNU itself. Kernel extensions can access them directly from the 777 | + * AppleImage4 headers. 778 | + */ 779 | +#include 780 | +#endif 781 | + 782 | +#if !XNU_KERNEL_PRIVATE 783 | +/* 784 | + * XNU does not make this header available and uses different availability macros 785 | + * than kernel extensions or base user-space applications. 786 | + */ 787 | +#include 788 | +#endif 789 | + 790 | +#pragma mark Chip Environments 791 | + 792 | +static const img4_chip_t* 793 | +chipEnvironmentPersonalized(void) { 794 | + return img4_chip_select_personalized_ap(); 795 | +} 796 | + 797 | +static const img4_chip_t* 798 | +chipEnvironmentCategorized(void) { 799 | + return img4_chip_select_categorized_ap(); 800 | +} 801 | + 802 | +static const img4_chip_t* 803 | +chipEnvironmentGlobalFF00(void) { 804 | + return IMG4_CHIP_AP_SOFTWARE_FF00; 805 | +} 806 | + 807 | +static const img4_chip_t* 808 | +chipEnvironmentGlobalFF01(void) { 809 | + return IMG4_CHIP_AP_SOFTWARE_FF01; 810 | +} 811 | + 812 | +static const img4_chip_t* 813 | +chipEnvironmentGlobalFF06(void) { 814 | + return IMG4_CHIP_AP_SOFTWARE_FF06; 815 | +} 816 | + 817 | +static const img4_chip_t* 818 | +chipEnvironmentEphemeralCryptex(void) { 819 | + return IMG4_CHIP_AP_SUPPLEMENTAL; 820 | +} 821 | + 822 | +static const img4_chip_t* 823 | +chipEnvironmentCryptex1Boot(void) { 824 | +#if IMG4_API_VERSION >= 20211126 825 | + return img4_chip_select_cryptex1_boot(); 826 | +#else 827 | + return NULL; 828 | +#endif 829 | +} 830 | + 831 | +static const img4_chip_t* 832 | +chipEnvironmentCryptex1PreBoot(void) { 833 | +#if IMG4_API_VERSION >= 20211126 834 | + return img4_chip_select_cryptex1_preboot(); 835 | +#else 836 | + return NULL; 837 | +#endif 838 | +} 839 | + 840 | +static const img4_chip_t* 841 | +chipEnvironmentCryptex1MobileAsset(void) { 842 | +#if IMG4_API_VERSION >= 20211126 843 | + return IMG4_CHIP_CRYPTEX1_ASSET; 844 | +#else 845 | + return NULL; 846 | +#endif 847 | +} 848 | + 849 | +static const img4_chip_t* 850 | +chipEnvironmentSafariDownlevel(void) { 851 | +#if IMG4_API_VERSION >= 20211126 852 | + return IMG4_CHIP_CRYPTEX1_BOOT_REDUCED; 853 | +#else 854 | + return NULL; 855 | +#endif 856 | +} 857 | + 858 | +static const img4_chip_t* 859 | +chipEnvironmentSupplemental(void) { 860 | + return IMG4_CHIP_AP_SUPPLEMENTAL; 861 | +} 862 | + 863 | +static const img4_chip_t* 864 | +chipEnvironmentCryptex1Generic(void) { 865 | +#if IMG4_API_VERSION >= 20221202 866 | + return IMG4_CHIP_CRYPTEX1_GENERIC; 867 | +#else 868 | + return NULL; 869 | +#endif 870 | +} 871 | + 872 | +static const img4_chip_t* 873 | +chipEnvironmentCryptex1GenericSupplemental(void) { 874 | +#if IMG4_API_VERSION >= 20221202 875 | + return IMG4_CHIP_CRYPTEX1_GENERIC_SUPPLEMENTAL; 876 | +#else 877 | + return NULL; 878 | +#endif 879 | +} 880 | + 881 | +#pragma mark Nonce Domains 882 | + 883 | +static const img4_nonce_domain_t* 884 | +nonceDomainTrustCache(void) { 885 | + return IMG4_NONCE_DOMAIN_TRUST_CACHE; 886 | +} 887 | + 888 | +static const img4_nonce_domain_t* 889 | +nonceDomainDDI(void) { 890 | + return IMG4_NONCE_DOMAIN_DDI; 891 | +} 892 | + 893 | +static const img4_nonce_domain_t* 894 | +nonceDomainCryptex(void) { 895 | + return IMG4_NONCE_DOMAIN_CRYPTEX; 896 | +} 897 | + 898 | +static const img4_nonce_domain_t* 899 | +nonceDomainEphemeralCryptex(void) { 900 | + return IMG4_NONCE_DOMAIN_EPHEMERAL_CRYPTEX; 901 | +} 902 | + 903 | +static const img4_nonce_domain_t* 904 | +nonceDomainPDI(void) { 905 | + return IMG4_NONCE_DOMAIN_PDI; 906 | +} 907 | + 908 | +#pragma mark Firmware Flags 909 | + 910 | +static img4_firmware_flags_t 911 | +firmwareFlagsDTRS(void) { 912 | + return IMG4_FIRMWARE_FLAG_RESPECT_AMNM; 913 | +} 914 | + 915 | +static img4_firmware_flags_t 916 | +firmwareFlagsSplat(void) { 917 | +#if XNU_TARGET_OS_OSX && (defined(__arm__) || defined(__arm64__)) 918 | + return IMG4_FIRMWARE_FLAG_SUBSEQUENT_STAGE; 919 | +#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX && (TARGET_CPU_ARM || TARGET_CPU_ARM64) 920 | + return IMG4_FIRMWARE_FLAG_SUBSEQUENT_STAGE; 921 | +#else 922 | + return IMG4_FIRMWARE_FLAG_INIT; 923 | +#endif 924 | +} 925 | + 926 | +#pragma mark Type Configuration 927 | + 928 | +typedef struct _TrustCacheTypeConfig { 929 | + /* Chip environment to use for validation */ 930 | + const img4_chip_t* (*chipEnvironment)(void); 931 | + 932 | + /* Nonce domain for anti-replay */ 933 | + const img4_nonce_domain_t* (*nonceDomain)(void); 934 | + 935 | + /* Four CC identifier for this type */ 936 | + img4_4cc_t fourCC; 937 | + 938 | + /* Firmware flags to add for this configuration */ 939 | + img4_firmware_flags_t (*firmwareFlags)(void); 940 | + 941 | + /* 942 | + * Higher level policy imposes restrictions on which process can load 943 | + * which trust cache. These restrictions are enforced through the use 944 | + * of the entitlement "com.apple.private.pmap.load-trust-cache". The 945 | + * value here is the required value of the above entitlement. 946 | + */ 947 | + const char *entitlementValue; 948 | +} TrustCacheTypeConfig_t; 949 | + 950 | +#pragma GCC diagnostic push 951 | +#pragma GCC diagnostic ignored "-Wfour-char-constants" 952 | + 953 | +static const TrustCacheTypeConfig_t TCTypeConfig[kTCTypeTotal] = { 954 | + /* Static trust caches are loaded as raw modules */ 955 | + [kTCTypeStatic] = { 956 | + .chipEnvironment = NULL, 957 | + .nonceDomain = NULL, 958 | + .fourCC = 0, 959 | + .firmwareFlags = NULL, 960 | + .entitlementValue = NULL 961 | + }, 962 | + 963 | + /* Engineering trust caches are loaded as raw modules */ 964 | + [kTCTypeEngineering] = { 965 | + .chipEnvironment = NULL, 966 | + .nonceDomain = NULL, 967 | + .fourCC = 0, 968 | + .firmwareFlags = NULL, 969 | + .entitlementValue = NULL 970 | + }, 971 | + 972 | + /* Legacy trust caches are loaded as raw modules */ 973 | + [kTCTypeLegacy] = { 974 | + .chipEnvironment = NULL, 975 | + .nonceDomain = NULL, 976 | + .fourCC = 0, 977 | + .firmwareFlags = NULL, 978 | + .entitlementValue = NULL 979 | + }, 980 | + 981 | + [kTCTypeDTRS] = { 982 | + .chipEnvironment = chipEnvironmentPersonalized, 983 | + .nonceDomain = NULL, 984 | + .fourCC = 'dtrs', 985 | + .firmwareFlags = firmwareFlagsDTRS, 986 | + .entitlementValue = "personalized.engineering-root" 987 | + }, 988 | + 989 | + [kTCTypeLTRS] = { 990 | + .chipEnvironment = chipEnvironmentPersonalized, 991 | + .nonceDomain = nonceDomainTrustCache, 992 | + .fourCC = 'ltrs', 993 | + .firmwareFlags = NULL, 994 | + .entitlementValue = "personalized.trust-cache" 995 | + }, 996 | + 997 | + [kTCTypePersonalizedDiskImage] = { 998 | + .chipEnvironment = chipEnvironmentPersonalized, 999 | + .nonceDomain = nonceDomainPDI, 1000 | + .fourCC = 'ltrs', 1001 | + .firmwareFlags = NULL, 1002 | + .entitlementValue = "personalized.pdi" 1003 | + }, 1004 | + 1005 | + [kTCTypeDeveloperDiskImage] = { 1006 | + .chipEnvironment = chipEnvironmentCategorized, 1007 | + .nonceDomain = nonceDomainDDI, 1008 | + .fourCC = 'trdv', 1009 | + .firmwareFlags = NULL, 1010 | + .entitlementValue = "personalized.ddi" 1011 | + }, 1012 | + 1013 | + [kTCTypeLTRSWithDDINonce] = { 1014 | + .chipEnvironment = chipEnvironmentPersonalized, 1015 | + .nonceDomain = nonceDomainDDI, 1016 | + .fourCC = 'ltrs', 1017 | + .firmwareFlags = NULL, 1018 | + .entitlementValue = "personalized.ddi" 1019 | + }, 1020 | + 1021 | + [kTCTypeCryptex] = { 1022 | + .chipEnvironment = chipEnvironmentPersonalized, 1023 | + .nonceDomain = nonceDomainCryptex, 1024 | + .fourCC = 'ltrs', 1025 | + .firmwareFlags = NULL, 1026 | + .entitlementValue = "personalized.cryptex-research" 1027 | + }, 1028 | + 1029 | + [kTCTypeEphemeralCryptex] = { 1030 | + .chipEnvironment = chipEnvironmentEphemeralCryptex, 1031 | + .nonceDomain = nonceDomainEphemeralCryptex, 1032 | + .fourCC = 'ltrs', 1033 | + .firmwareFlags = NULL, 1034 | + .entitlementValue = "personalized.ephemeral-cryptex" 1035 | + }, 1036 | + 1037 | + [kTCTypeUpdateBrain] = { 1038 | + .chipEnvironment = chipEnvironmentGlobalFF00, 1039 | + .nonceDomain = NULL, 1040 | + .fourCC = 'ltrs', 1041 | + .firmwareFlags = NULL, 1042 | + .entitlementValue = "global.ota-update-brain" 1043 | + }, 1044 | + 1045 | + [kTCTypeInstallAssistant] = { 1046 | + .chipEnvironment = chipEnvironmentGlobalFF01, 1047 | + .nonceDomain = NULL, 1048 | + .fourCC = 'ltrs', 1049 | + .firmwareFlags = NULL, 1050 | + .entitlementValue = "global.install-assistant" 1051 | + }, 1052 | + 1053 | + [kTCTypeBootabilityBrain] = { 1054 | + .chipEnvironment = chipEnvironmentGlobalFF06, 1055 | + .nonceDomain = NULL, 1056 | + .fourCC = 'trbb', 1057 | + .firmwareFlags = NULL, 1058 | + .entitlementValue = "global.bootability-brain" 1059 | + }, 1060 | + 1061 | + [kTCTypeCryptex1BootOS] = { 1062 | + .chipEnvironment = chipEnvironmentCryptex1Boot, 1063 | + .nonceDomain = NULL, 1064 | + .fourCC = 'trcs', 1065 | + .firmwareFlags = firmwareFlagsSplat, 1066 | + .entitlementValue = "cryptex1.boot.os" 1067 | + }, 1068 | + 1069 | + [kTCTypeCryptex1BootApp] = { 1070 | + .chipEnvironment = chipEnvironmentCryptex1Boot, 1071 | + .nonceDomain = NULL, 1072 | + .fourCC = 'trca', 1073 | + .firmwareFlags = firmwareFlagsSplat, 1074 | + .entitlementValue = "cryptex1.boot.app" 1075 | + }, 1076 | + 1077 | + [kTCTypeCryptex1PreBootApp] = { 1078 | + .chipEnvironment = chipEnvironmentCryptex1PreBoot, 1079 | + .nonceDomain = NULL, 1080 | + .fourCC = 'trca', 1081 | + .firmwareFlags = firmwareFlagsSplat, 1082 | + .entitlementValue = "cryptex1.preboot.app" 1083 | + }, 1084 | + 1085 | + [kTCTypeGlobalDiskImage] = { 1086 | + .chipEnvironment = chipEnvironmentGlobalFF00, 1087 | + .nonceDomain = NULL, 1088 | + .fourCC = 'ltrs', 1089 | + .firmwareFlags = NULL, 1090 | + .entitlementValue = "global.pdi" 1091 | + }, 1092 | + 1093 | + [kTCTypeMobileAssetBrain] = { 1094 | + .chipEnvironment = chipEnvironmentCryptex1MobileAsset, 1095 | + .nonceDomain = NULL, 1096 | + .fourCC = 'trab', 1097 | + .firmwareFlags = NULL, 1098 | + .entitlementValue = "personalized.mobile-asset-brain" 1099 | + }, 1100 | + 1101 | + [kTCTypeSafariDownlevel] = { 1102 | + .chipEnvironment = chipEnvironmentSafariDownlevel, 1103 | + .nonceDomain = NULL, 1104 | + .fourCC = 'trca', 1105 | + .firmwareFlags = NULL, 1106 | + .entitlementValue = "cryptex1.safari-downlevel" 1107 | + }, 1108 | + 1109 | + [kTCTypeCryptex1PreBootOS] = { 1110 | + .chipEnvironment = chipEnvironmentCryptex1PreBoot, 1111 | + .nonceDomain = NULL, 1112 | + .fourCC = 'trcs', 1113 | + .firmwareFlags = firmwareFlagsSplat, 1114 | + .entitlementValue = "cryptex1.preboot.os" 1115 | + }, 1116 | + 1117 | + [kTCTypeSupplementalPersistent] = { 1118 | + .chipEnvironment = chipEnvironmentSupplemental, 1119 | + .nonceDomain = nonceDomainDDI, 1120 | + .fourCC = 'ltrs', 1121 | + .firmwareFlags = NULL, 1122 | + .entitlementValue = "personalized.supplemental-persistent" 1123 | + }, 1124 | + 1125 | + [kTCTypeSupplementalEphemeral] = { 1126 | + .chipEnvironment = chipEnvironmentSupplemental, 1127 | + .nonceDomain = nonceDomainPDI, 1128 | + .fourCC = 'ltrs', 1129 | + .firmwareFlags = NULL, 1130 | + .entitlementValue = "personalized.supplemental-ephemeral" 1131 | + }, 1132 | + 1133 | + [kTCTypeCryptex1Generic] = { 1134 | + .chipEnvironment = chipEnvironmentCryptex1Generic, 1135 | + .nonceDomain = NULL, 1136 | + .fourCC = 'gtcd', 1137 | + .firmwareFlags = NULL, 1138 | + .entitlementValue = "cryptex1.generic" 1139 | + }, 1140 | + 1141 | + [kTCTypeCryptex1GenericSupplemental] = { 1142 | + .chipEnvironment = chipEnvironmentCryptex1GenericSupplemental, 1143 | + .nonceDomain = NULL, 1144 | + .fourCC = 'gtcd', 1145 | + .firmwareFlags = NULL, 1146 | + .entitlementValue = "cryptex1.generic.supplemental" 1147 | + } 1148 | +}; 1149 | + 1150 | +#pragma GCC diagnostic pop 1151 | + 1152 | +__END_DECLS 1153 | +#endif /* libTrustCache_TypesConfig_h */ 1154 | -------------------------------------------------------------------------------- /patches/14.4/entitlements.patch: -------------------------------------------------------------------------------- 1 | diff --git a/EXTERNAL_HEADERS/CoreEntitlements/CoreEntitlements.h b/EXTERNAL_HEADERS/CoreEntitlements/CoreEntitlements.h 2 | index 60e7e8f9..001dfff2 100644 3 | --- a/EXTERNAL_HEADERS/CoreEntitlements/CoreEntitlements.h 4 | +++ b/EXTERNAL_HEADERS/CoreEntitlements/CoreEntitlements.h 5 | @@ -5,6 +5,11 @@ 6 | #ifndef CORE_ENTITLEMENTS_H 7 | #define CORE_ENTITLEMENTS_H 8 | 9 | +#define kCSWebBrowserNetworkEntitlement (("com.apple.developer.web-browser-engine.networking")) 10 | +#define kCSWebBrowserWebContentEntitlement (("com.apple.developer.web-browser-engine.webcontent")) 11 | +#define kCSWebBrowserGPUEntitlement (("com.apple.developer.web-browser-engine.rendering")) 12 | +#define kCSWebBrowserHostEntitlement (("com.apple.developer.web-browser-engine.host")) 13 | + 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | diff --git a/bsd/kern/kern_exec.c b/bsd/kern/kern_exec.c 18 | index 685f28bf..0834a5a2 100644 19 | --- a/bsd/kern/kern_exec.c 20 | +++ b/bsd/kern/kern_exec.c 21 | @@ -183,7 +183,7 @@ 22 | 23 | #include "kern_exec_internal.h" 24 | 25 | -#include 26 | +#include 27 | 28 | #include 29 | 30 | diff --git a/bsd/net/necp_client.c b/bsd/net/necp_client.c 31 | index 7e18ca4a..5c20b6dc 100644 32 | --- a/bsd/net/necp_client.c 33 | +++ b/bsd/net/necp_client.c 34 | @@ -68,7 +68,7 @@ 35 | 36 | #include 37 | 38 | -#include 39 | +#include 40 | 41 | #if SKYWALK 42 | #include 43 | -------------------------------------------------------------------------------- /patches/14.4/iokit.patch: -------------------------------------------------------------------------------- 1 | diff --git a/iokit/DriverKit/IORPC.h b/iokit/DriverKit/IORPC.h 2 | index 7ffc6b73..5d49f179 100644 3 | --- a/iokit/DriverKit/IORPC.h 4 | +++ b/iokit/DriverKit/IORPC.h 5 | @@ -267,4 +267,6 @@ struct OSClassDescription { 6 | char metaMethodNames[0]; 7 | }; 8 | 9 | +IORPCMessage *IORPCMessageFromMach(IORPCMessageMach * msg, bool reply); 10 | + 11 | #endif /* _IORPC_H */ 12 | diff --git a/iokit/DriverKit/IOReturn.h b/iokit/DriverKit/IOReturn.h 13 | index e36d37b3..71f6b40f 100644 14 | --- a/iokit/DriverKit/IOReturn.h 15 | +++ b/iokit/DriverKit/IOReturn.h 16 | @@ -36,6 +36,10 @@ 17 | #ifndef __IOKIT_IORETURN_H 18 | #define __IOKIT_IORETURN_H 19 | 20 | +#include 21 | +IORPCMessage * 22 | +IORPCMessageFromMach(IORPCMessageMach * msg, bool reply); 23 | + 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | diff --git a/iokit/IOKit/IORPC.h b/iokit/IOKit/IORPC.h 28 | index 7ffc6b73..5d49f179 100644 29 | --- a/iokit/IOKit/IORPC.h 30 | +++ b/iokit/IOKit/IORPC.h 31 | @@ -267,4 +267,6 @@ struct OSClassDescription { 32 | char metaMethodNames[0]; 33 | }; 34 | 35 | +IORPCMessage *IORPCMessageFromMach(IORPCMessageMach * msg, bool reply); 36 | + 37 | #endif /* _IORPC_H */ 38 | diff --git a/iokit/Kernel/IOUserServer.cpp b/iokit/Kernel/IOUserServer.cpp 39 | index d61ffd1f..9100d9f1 100644 40 | --- a/iokit/Kernel/IOUserServer.cpp 41 | +++ b/iokit/Kernel/IOUserServer.cpp 42 | @@ -2404,7 +2404,7 @@ OSMetaClassBase::Invoke(IORPC rpc) 43 | IORPCMessage * message; 44 | 45 | assert(rpc.sendSize >= (sizeof(IORPCMessageMach) + sizeof(IORPCMessage))); 46 | - message = rpc.kernelContent; 47 | + message = IORPCMessageFromMach(rpc.message, false); 48 | if (!message) { 49 | return kIOReturnIPCError; 50 | } 51 | @@ -3630,6 +3630,45 @@ IORPCMessageFromMachReply(IORPCMessageMach * msg) 52 | return (IORPCMessage *)(uintptr_t) desc; 53 | } 54 | 55 | +IORPCMessage * 56 | +IORPCMessageFromMach(IORPCMessageMach * msg, bool reply) 57 | +{ 58 | + mach_msg_size_t idx, count; 59 | + mach_msg_port_descriptor_t * desc; 60 | + mach_msg_port_descriptor_t * maxDesc; 61 | + size_t size, msgsize; 62 | + bool upgrade; 63 | + 64 | + msgsize = msg->msgh.msgh_size; 65 | + count = msg->msgh_body.msgh_descriptor_count; 66 | + desc = &msg->objects[0]; 67 | + maxDesc = (typeof(maxDesc))(((uintptr_t) msg) + msgsize); 68 | + upgrade = (msg->msgh.msgh_id != (reply ? kIORPCVersionCurrentReply : kIORPCVersionCurrent)); 69 | + 70 | + if (upgrade) { 71 | + OSReportWithBacktrace("obsolete message"); 72 | + return NULL; 73 | + } 74 | + 75 | + for (idx = 0; idx < count; idx++) { 76 | + if (desc >= maxDesc) { 77 | + return NULL; 78 | + } 79 | + switch (desc->type) { 80 | + case MACH_MSG_PORT_DESCRIPTOR: 81 | + size = sizeof(mach_msg_port_descriptor_t); 82 | + break; 83 | + case MACH_MSG_OOL_DESCRIPTOR: 84 | + size = sizeof(mach_msg_ool_descriptor_t); 85 | + break; 86 | + default: 87 | + return NULL; 88 | + } 89 | + desc = (typeof(desc))(((uintptr_t) desc) + size); 90 | + } 91 | + return (IORPCMessage *)(uintptr_t) desc; 92 | +} 93 | + 94 | ipc_port_t 95 | IOUserServer::copySendRightForObject(OSObject * object, ipc_kobject_type_t type) 96 | { 97 | -------------------------------------------------------------------------------- /patches/14.4/machine_routines.patch: -------------------------------------------------------------------------------- 1 | diff --git a/osfmk/arm64/machine_routines.c b/osfmk/arm64/machine_routines.c 2 | index 3ed62bd6..f1d0d190 100644 3 | --- a/osfmk/arm64/machine_routines.c 4 | +++ b/osfmk/arm64/machine_routines.c 5 | @@ -2097,7 +2097,7 @@ static inline uint64_t 6 | nonspeculative_timebase(void) 7 | { 8 | #if defined(HAS_ACNTVCT) 9 | - return __builtin_arm_rsr64("ACNTVCT_EL0"); 10 | + return __builtin_arm_rsr64("S3_4_c15_c10_6"); 11 | #elif __ARM_ARCH_8_6__ 12 | return __builtin_arm_rsr64("CNTVCTSS_EL0"); 13 | #else 14 | -------------------------------------------------------------------------------- /patches/14.4/python.patch: -------------------------------------------------------------------------------- 1 | diff --git a/tools/lldbmacros/core/operating_system.py b/tools/lldbmacros/core/operating_system.py 2 | index 0ea8b27c..43ad85b5 100755 3 | --- a/tools/lldbmacros/core/operating_system.py 4 | +++ b/tools/lldbmacros/core/operating_system.py 5 | @@ -1,4 +1,4 @@ 6 | -#!/usr/bin/python 7 | +#!/usr/bin/env python 8 | # 9 | 10 | #source of register info is from http://opensource.apple.com/source/gdb/gdb-962/src/gdb/arm-tdep.c 11 | diff --git a/tools/lldbmacros/core/syntax_checker.py b/tools/lldbmacros/core/syntax_checker.py 12 | index 62d4681f..606ce299 100755 13 | --- a/tools/lldbmacros/core/syntax_checker.py 14 | +++ b/tools/lldbmacros/core/syntax_checker.py 15 | @@ -10,9 +10,6 @@ Usage: 16 | """ 17 | import sys 18 | import os 19 | -import re 20 | - 21 | -tabs_search_rex = re.compile("^\s*\t+",re.MULTILINE|re.DOTALL) 22 | 23 | def find_non_ascii(s): 24 | for c in s: 25 | @@ -32,20 +29,6 @@ if __name__ == "__main__": 26 | print("Note: %s is not a valid python file. Skipping." % fname) 27 | continue 28 | fh = open(fname) 29 | - strdata = fh.readlines() 30 | - lineno = 0 31 | - syntax_fail = False 32 | - for linedata in strdata: 33 | - lineno += 1 34 | - if len(tabs_search_rex.findall(linedata)) > 0 : 35 | - print("Error: Found a TAB character at %s:%d" % (fname, lineno), file=sys.stderr) 36 | - syntax_fail = True 37 | - if find_non_ascii(linedata): 38 | - print("Error: Found a non ascii character at %s:%d" % (fname, lineno), file=sys.stderr) 39 | - syntax_fail = True 40 | - if syntax_fail: 41 | - print("Error: Syntax check failed. Please fix the errors and try again.", file=sys.stderr) 42 | - sys.exit(1) 43 | #now check for error in compilation 44 | try: 45 | with open(fname, 'r') as file: 46 | diff --git a/tools/lldbmacros/scheduler.py b/tools/lldbmacros/scheduler.py 47 | index 20db7d56..b343a4e7 100755 48 | --- a/tools/lldbmacros/scheduler.py 49 | +++ b/tools/lldbmacros/scheduler.py 50 | @@ -127,13 +127,13 @@ def showinterruptsourceinfo(cmd_args = None): 51 | print(object_info) 52 | print("--- Dumping IOFilterInterruptEventSource object ---\n") 53 | #Dump the IOFilterInterruptEventSource object. 54 | - target_info=re.search('target =\s+(.*)',object_info) 55 | + target_info=re.search('target =\\s+(.*)',object_info) 56 | target= target_info.group() 57 | target= target.split() 58 | #Dump the Object pointer of the source who is triggering the Interrupts. 59 | vector_info=lldb_run_command("dumpobject {:s} ".format(target[2])) 60 | print(vector_info) 61 | - owner_info= re.search('owner =\s+(.*)',vector_info) 62 | + owner_info= re.search('owner =\\s+(.*)',vector_info) 63 | owner= owner_info.group() 64 | owner= owner.split() 65 | print("\n\n") 66 | diff --git a/tools/lldbmacros/userspace.py b/tools/lldbmacros/userspace.py 67 | index 4edff39e..af53f7c9 100755 68 | --- a/tools/lldbmacros/userspace.py 69 | +++ b/tools/lldbmacros/userspace.py 70 | @@ -265,7 +265,7 @@ Application Specific Information: 71 | Synthetic crash log generated from Kernel userstacks 72 | 73 | """ 74 | - user_lib_rex = re.compile("([0-9a-fx]+)\s-\s([0-9a-fx]+)\s+(.*?)\s", re.IGNORECASE|re.MULTILINE) 75 | + user_lib_rex = re.compile("([0-9a-fx]+)\\s-\\s([0-9a-fx]+)\\s+(.*?)\\s", re.IGNORECASE|re.MULTILINE) 76 | from datetime import datetime 77 | if pval: 78 | ts = datetime.fromtimestamp(int(pval.p_start.tv_sec)) 79 | diff --git a/tools/lldbmacros/utils.py b/tools/lldbmacros/utils.py 80 | index e2d168fe..f92c6eb5 100755 81 | --- a/tools/lldbmacros/utils.py 82 | +++ b/tools/lldbmacros/utils.py 83 | @@ -530,7 +530,7 @@ def dsymForUUID(uuid): 84 | # because of 85 | #plist = plistlib.readPlistFromString(output) 86 | #beginworkaround 87 | - keyvalue_extract_re = re.compile("(.*?)\s*(.*?)",re.IGNORECASE|re.MULTILINE|re.DOTALL) 88 | + keyvalue_extract_re = re.compile("(.*?)\\s*(.*?)",re.IGNORECASE|re.MULTILINE|re.DOTALL) 89 | plist={} 90 | plist[uuid] = {} 91 | for item in keyvalue_extract_re.findall(output): 92 | diff --git a/tools/lldbmacros/xnu.py b/tools/lldbmacros/xnu.py 93 | index d3e27fc6..5e3c50ff 100755 94 | --- a/tools/lldbmacros/xnu.py 95 | +++ b/tools/lldbmacros/xnu.py 96 | @@ -1168,7 +1168,7 @@ def __lldb_init_module(debugger, internal_dict): 97 | if _xnu_framework_init: 98 | return 99 | _xnu_framework_init = True 100 | - debugger.HandleCommand('type summary add --regex --summary-string "${var%s}" -C yes -p -v "char *\[[0-9]*\]"') 101 | + debugger.HandleCommand('type summary add --regex --summary-string "${var%s}" -C yes -p -v "char *\\[[0-9]*\\]"') 102 | debugger.HandleCommand('type format add --format hex -C yes uintptr_t') 103 | kern = KernelTarget(debugger) 104 | if not hasattr(lldb.SBValue, 'GetValueAsAddress'): 105 | diff --git a/tools/lldbmacros/xnutriage.py b/tools/lldbmacros/xnutriage.py 106 | index bd071529..5dbd1b0c 100755 107 | --- a/tools/lldbmacros/xnutriage.py 108 | +++ b/tools/lldbmacros/xnutriage.py 109 | @@ -89,7 +89,7 @@ def parseLR(cmd_args=None): 110 | paniclog_data += returnfunc("\n(lldb) paniclog\n", "paniclog") 111 | 112 | if panic_found == 1: 113 | - srch_string = "lr:\s+0x[a-fA-F0-9]+\s" 114 | + srch_string = "lr:\\s+0x[a-fA-F0-9]+\\s" 115 | lr_pc_srch = re.findall(srch_string, paniclog_data) 116 | if lr_pc_srch: 117 | print(paniclog_data, lr_pc_srch) 118 | @@ -110,7 +110,7 @@ def parseLRfromfile(cmd_args=None): 119 | """ 120 | f = open('/tmp/lrparsefile', 'r') 121 | parse_data= f.read() 122 | - srch_string = "lr:\s+0x[a-fA-F0-9]+\s" 123 | + srch_string = "lr:\\s+0x[a-fA-F0-9]+\\s" 124 | lr_pc_srch = re.findall(srch_string, parse_data) 125 | if lr_pc_srch: 126 | print(paniclog_data, lr_pc_srch) 127 | diff --git a/tools/lldbmacros/zonetriage.py b/tools/lldbmacros/zonetriage.py 128 | index 57b1cc73..5575c215 100755 129 | --- a/tools/lldbmacros/zonetriage.py 130 | +++ b/tools/lldbmacros/zonetriage.py 131 | @@ -26,7 +26,7 @@ import os.path 132 | panic_string = None 133 | ## If the following panic strings are modified in xnu/osfmk/kern/zalloc.c, they must be updated here to reflect the change. 134 | zone_element_modified = ".*a freed zone element has been modified in zone (?P.+): expected (0x)?([0-9A-Fa-f]*)? but found (0x)?([0-9A-Fa-f]*)?, bits changed (0x)?([0-9A-Fa-f]*)?, at offset ([0-9]*)? of ([0-9]*)? in element (?P0x[0-9A-Fa-f]*), cookies (0x)?([0-9A-Fa-f]*)? (0x)?([0-9A-Fa-f]*)?.*" 135 | -zone_map_exhausted = ".*zalloc: zone map exhausted while allocating from zone .+, likely due to memory leak in zone (?P.+) \(([0-9]*)? total bytes, ([0-9]*)? elements allocated\).*" 136 | +zone_map_exhausted = ".*zalloc: zone map exhausted while allocating from zone .+, likely due to memory leak in zone (?P.+) \\(([0-9]*)? total bytes, ([0-9]*)? elements allocated\\).*" 137 | 138 | # Macro: zonetriage, zonetriage_freedelement, zonetriage_memoryleak 139 | @lldb_command('zonetriage') 140 | diff --git a/tools/tests/perf_index/test_controller.py b/tools/tests/perf_index/test_controller.py 141 | index 73d2a1b3..e762505b 100755 142 | --- a/tools/tests/perf_index/test_controller.py 143 | +++ b/tools/tests/perf_index/test_controller.py 144 | @@ -1,4 +1,4 @@ 145 | -#!/usr/bin/python 146 | +#!/usr/bin/env python 147 | from __future__ import absolute_import, print_function 148 | import socket 149 | import time 150 | -------------------------------------------------------------------------------- /patches/14.4/skywalk.patch: -------------------------------------------------------------------------------- 1 | diff --git a/bsd/skywalk/packet/packet_kern.c b/bsd/skywalk/packet/packet_kern.c 2 | index 7dbbdf88..04d6de7a 100644 3 | --- a/bsd/skywalk/packet/packet_kern.c 4 | +++ b/bsd/skywalk/packet/packet_kern.c 5 | @@ -287,6 +287,37 @@ kern_packet_get_inet_checksum(const kern_packet_t ph, uint16_t *start, 6 | return __packet_get_inet_checksum(ph, start, val, tx); 7 | } 8 | 9 | +errno_t 10 | +kern_packet_set_fpd_command(const kern_packet_t ph, 11 | + uint8_t cmd) 12 | +{ 13 | + errno_t result; 14 | + 15 | + if (cmd > 7) 16 | + return 22; 17 | + result = 0; 18 | + PKT_ADDR(ph)->pkt_fpd_metadata |= ((cmd & 7) << 6) | 0x8000; 19 | + return result; 20 | +} 21 | + 22 | +errno_t 23 | +kern_packet_set_fpd_sequence_number(const kern_packet_t ph, 24 | + uint32_t seq_num) 25 | +{ 26 | + PKT_ADDR(ph)->pkt_fpd_seqnum = seq_num; 27 | + PKT_ADDR(ph)->pkt_fpd_metadata |= 0x8000; 28 | + return 0; 29 | +} 30 | + 31 | +errno_t 32 | +kern_packet_set_fpd_context_id(const kern_packet_t ph, 33 | + uint16_t ctx_id) 34 | +{ 35 | + PKT_ADDR(ph)->pkt_fpd_metadata |= ctx_id & 0x3F | 0x8000; 36 | + return 0; 37 | +} 38 | + 39 | + 40 | void 41 | kern_packet_set_flow_uuid(const kern_packet_t ph, const uuid_t flow_uuid) 42 | { 43 | @@ -955,24 +986,6 @@ kern_packet_copy_bytes(kern_packet_t pkt, size_t off, size_t len, void* out_data 44 | return 0; 45 | } 46 | 47 | -errno_t 48 | -kern_packet_set_fpd_sequence_number(__unused const kern_packet_t ph, __unused uint32_t seq_num) 49 | -{ 50 | - return 0; 51 | -} 52 | - 53 | -errno_t 54 | -kern_packet_set_fpd_context_id(__unused const kern_packet_t ph, __unused uint16_t ctx_id) 55 | -{ 56 | - return 0; 57 | -} 58 | - 59 | -errno_t 60 | -kern_packet_set_fpd_command(__unused const kern_packet_t ph, __unused uint8_t cmd) 61 | -{ 62 | - return 0; 63 | -} 64 | - 65 | errno_t 66 | kern_packet_get_flowid(const kern_packet_t ph, packet_flowid_t *pflowid) 67 | { 68 | diff --git a/bsd/skywalk/packet/packet_var.h b/bsd/skywalk/packet/packet_var.h 69 | index 6474f5f0..cf37cb09 100644 70 | --- a/bsd/skywalk/packet/packet_var.h 71 | +++ b/bsd/skywalk/packet/packet_var.h 72 | @@ -441,7 +441,8 @@ struct __kern_packet { 73 | 74 | void * pkt_priv; /* free to use for every layer */ 75 | 76 | - 77 | + uint32_t pkt_fpd_seqnum; // @ 0xd0 78 | + uint16_t pkt_fpd_metadata; // @ 0xd4 79 | /* 80 | * Kernel specific. 81 | * 82 | -------------------------------------------------------------------------------- /patches/15.0/entitlements.patch: -------------------------------------------------------------------------------- 1 | diff --git a/EXTERNAL_HEADERS/CoreEntitlements/CoreEntitlements.h b/EXTERNAL_HEADERS/CoreEntitlements/CoreEntitlements.h 2 | index 60e7e8f9..001dfff2 100644 3 | --- a/EXTERNAL_HEADERS/CoreEntitlements/CoreEntitlements.h 4 | +++ b/EXTERNAL_HEADERS/CoreEntitlements/CoreEntitlements.h 5 | @@ -5,6 +5,11 @@ 6 | #ifndef CORE_ENTITLEMENTS_H 7 | #define CORE_ENTITLEMENTS_H 8 | 9 | +#define kCSWebBrowserNetworkEntitlement (("com.apple.developer.web-browser-engine.networking")) 10 | +#define kCSWebBrowserWebContentEntitlement (("com.apple.developer.web-browser-engine.webcontent")) 11 | +#define kCSWebBrowserGPUEntitlement (("com.apple.developer.web-browser-engine.rendering")) 12 | +#define kCSWebBrowserHostEntitlement (("com.apple.developer.web-browser-engine.host")) 13 | + 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | diff --git a/bsd/kern/kern_exec.c b/bsd/kern/kern_exec.c 18 | index 685f28bf..0834a5a2 100644 19 | --- a/bsd/kern/kern_exec.c 20 | +++ b/bsd/kern/kern_exec.c 21 | @@ -183,7 +183,7 @@ 22 | 23 | #include "kern_exec_internal.h" 24 | 25 | -#include 26 | +#include 27 | 28 | #include 29 | 30 | diff --git a/bsd/net/necp_client.c b/bsd/net/necp_client.c 31 | index 7e18ca4a..5c20b6dc 100644 32 | --- a/bsd/net/necp_client.c 33 | +++ b/bsd/net/necp_client.c 34 | @@ -68,7 +68,7 @@ 35 | 36 | #include 37 | 38 | -#include 39 | +#include 40 | 41 | #if SKYWALK 42 | #include 43 | -------------------------------------------------------------------------------- /patches/15.0/iokit.patch: -------------------------------------------------------------------------------- 1 | diff --git a/iokit/DriverKit/IORPC.h b/iokit/DriverKit/IORPC.h 2 | index 7ffc6b73..5d49f179 100644 3 | --- a/iokit/DriverKit/IORPC.h 4 | +++ b/iokit/DriverKit/IORPC.h 5 | @@ -267,4 +267,6 @@ struct OSClassDescription { 6 | char metaMethodNames[0]; 7 | }; 8 | 9 | +IORPCMessage *IORPCMessageFromMach(IORPCMessageMach * msg, bool reply); 10 | + 11 | #endif /* _IORPC_H */ 12 | diff --git a/iokit/DriverKit/IOReturn.h b/iokit/DriverKit/IOReturn.h 13 | index e36d37b3..71f6b40f 100644 14 | --- a/iokit/DriverKit/IOReturn.h 15 | +++ b/iokit/DriverKit/IOReturn.h 16 | @@ -36,6 +36,10 @@ 17 | #ifndef __IOKIT_IORETURN_H 18 | #define __IOKIT_IORETURN_H 19 | 20 | +#include 21 | +IORPCMessage * 22 | +IORPCMessageFromMach(IORPCMessageMach * msg, bool reply); 23 | + 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | diff --git a/iokit/IOKit/IORPC.h b/iokit/IOKit/IORPC.h 28 | index 7ffc6b73..5d49f179 100644 29 | --- a/iokit/IOKit/IORPC.h 30 | +++ b/iokit/IOKit/IORPC.h 31 | @@ -267,4 +267,6 @@ struct OSClassDescription { 32 | char metaMethodNames[0]; 33 | }; 34 | 35 | +IORPCMessage *IORPCMessageFromMach(IORPCMessageMach * msg, bool reply); 36 | + 37 | #endif /* _IORPC_H */ 38 | diff --git a/iokit/Kernel/IOUserServer.cpp b/iokit/Kernel/IOUserServer.cpp 39 | index d61ffd1f..9100d9f1 100644 40 | --- a/iokit/Kernel/IOUserServer.cpp 41 | +++ b/iokit/Kernel/IOUserServer.cpp 42 | @@ -2404,7 +2404,7 @@ OSMetaClassBase::Invoke(IORPC rpc) 43 | IORPCMessage * message; 44 | 45 | assert(rpc.sendSize >= (sizeof(IORPCMessageMach) + sizeof(IORPCMessage))); 46 | - message = rpc.kernelContent; 47 | + message = IORPCMessageFromMach(rpc.message, false); 48 | if (!message) { 49 | return kIOReturnIPCError; 50 | } 51 | @@ -3630,6 +3630,45 @@ IORPCMessageFromMachReply(IORPCMessageMach * msg) 52 | return (IORPCMessage *)(uintptr_t) desc; 53 | } 54 | 55 | +IORPCMessage * 56 | +IORPCMessageFromMach(IORPCMessageMach * msg, bool reply) 57 | +{ 58 | + mach_msg_size_t idx, count; 59 | + mach_msg_port_descriptor_t * desc; 60 | + mach_msg_port_descriptor_t * maxDesc; 61 | + size_t size, msgsize; 62 | + bool upgrade; 63 | + 64 | + msgsize = msg->msgh.msgh_size; 65 | + count = msg->msgh_body.msgh_descriptor_count; 66 | + desc = &msg->objects[0]; 67 | + maxDesc = (typeof(maxDesc))(((uintptr_t) msg) + msgsize); 68 | + upgrade = (msg->msgh.msgh_id != (reply ? kIORPCVersionCurrentReply : kIORPCVersionCurrent)); 69 | + 70 | + if (upgrade) { 71 | + OSReportWithBacktrace("obsolete message"); 72 | + return NULL; 73 | + } 74 | + 75 | + for (idx = 0; idx < count; idx++) { 76 | + if (desc >= maxDesc) { 77 | + return NULL; 78 | + } 79 | + switch (desc->type) { 80 | + case MACH_MSG_PORT_DESCRIPTOR: 81 | + size = sizeof(mach_msg_port_descriptor_t); 82 | + break; 83 | + case MACH_MSG_OOL_DESCRIPTOR: 84 | + size = sizeof(mach_msg_ool_descriptor_t); 85 | + break; 86 | + default: 87 | + return NULL; 88 | + } 89 | + desc = (typeof(desc))(((uintptr_t) desc) + size); 90 | + } 91 | + return (IORPCMessage *)(uintptr_t) desc; 92 | +} 93 | + 94 | ipc_port_t 95 | IOUserServer::copySendRightForObject(OSObject * object, ipc_kobject_type_t type) 96 | { 97 | -------------------------------------------------------------------------------- /patches/15.0/link_kdk.patch: -------------------------------------------------------------------------------- 1 | diff --git a/makedefs/MakeInc.def b/makedefs/MakeInc.def 2 | index 3468fbff8..87bb7e540 100644 3 | --- a/makedefs/MakeInc.def 4 | +++ b/makedefs/MakeInc.def 5 | @@ -971,6 +971,10 @@ LDFILES_KERNEL_ONLY = $(TARGET)/all-kpi.exp $(TARGET)/all-alias.exp $(TARGET)/sy 6 | # 7 | LD_KERNEL_LIBS = -lcc_kext 8 | LD_KERNEL_ARCHIVES = $(LDFLAGS_KERNEL_SDK) -lfirehose_kernel 9 | +# Link opensource binary library 10 | +ifneq ($(filter T6000 T6020 T8101 T8103 T8112 VMAPPLE T6000 T6020 T8101 T8103 T8112 VMAPPLE,$(CURRENT_MACHINE_CONFIG)),) 11 | + LDFLAGS_KERNEL_ONLY += -rdynamic -Wl,-force_load,$(KDKROOT)/System/Library/KernelSupport/lib$(CURRENT_MACHINE_CONFIG).os.$(CURRENT_KERNEL_CONFIG).a 12 | +endif 13 | 14 | # 15 | # SPTM TODO: This is a hack to always link the SPTM library when building the 16 | -------------------------------------------------------------------------------- /patches/15.0/link_kdk146.patch: -------------------------------------------------------------------------------- 1 | diff --git a/makedefs/MakeInc.def b/makedefs/MakeInc.def 2 | index c66add18d..b63c1c521 100644 3 | --- a/makedefs/MakeInc.def 4 | +++ b/makedefs/MakeInc.def 5 | @@ -889,7 +889,10 @@ LDFILES_KERNEL_ONLY = $(TARGET)/all-kpi.exp $(TARGET)/all-alias.exp $(TARGET)/sy 6 | # 7 | LD_KERNEL_LIBS = -lcc_kext 8 | LD_KERNEL_ARCHIVES = $(LDFLAGS_KERNEL_SDK) -lfirehose_kernel 9 | - 10 | +# Link opensource binary library 11 | +ifneq ($(filter T6000 T6020 T8101 T8103 T8112 VMAPPLE T6000 T6020 T8101 T8103 T8112 VMAPPLE,$(CURRENT_MACHINE_CONFIG)),) 12 | + LDFLAGS_KERNEL_ONLY += -rdynamic -Wl,-force_load,$(KDKROOT)/System/Library/KernelSupport/lib$(CURRENT_MACHINE_CONFIG).os.$(CURRENT_KERNEL_CONFIG).a 13 | +endif 14 | 15 | # 16 | # DTrace support 17 | -------------------------------------------------------------------------------- /patches/15.0/remove_tightbeam.patch: -------------------------------------------------------------------------------- 1 | diff --git a/config/Private.Tightbeam.exports b/config/Private.Tightbeam.exports 2 | index 2344c8e09..2be1e2e74 100644 3 | --- a/config/Private.Tightbeam.exports 4 | +++ b/config/Private.Tightbeam.exports 5 | @@ -1,89 +1,3 @@ 6 | # Tightbeam Kext Interface 7 | # 8 | # 9 | -_tb_client_connection_activate 10 | -_tb_client_connection_create 11 | -_tb_client_connection_destruct 12 | -_tb_client_connection_create_with_endpoint 13 | -_tb_client_connection_create_with_endpoint_static 14 | -_tb_client_connection_message_construct 15 | -_tb_client_connection_message_destruct 16 | -_tb_client_connection_message_reset 17 | -_tb_connection_get_transport 18 | -_tb_connection_send_query 19 | -_tb_forwarding_connection_activate 20 | -_tb_forwarding_connection_create 21 | -_tb_forwarding_connection_destruct 22 | -_tb_forwarding_connection_create_with_endpoint 23 | -_tb_owned_buffer_allocate 24 | -_tb_owned_buffer_deallocate 25 | -_tb_service_connection_activate 26 | -_tb_service_connection_create 27 | -_tb_service_connection_destruct 28 | -_tb_service_connection_create_with_endpoint 29 | -_tb_service_connection_message_configure_reply 30 | -_tb_service_connection_message_construct 31 | -_tb_service_connection_message_destruct 32 | -_tb_transport_call_message_handler 33 | -_tb_transport_get_context 34 | -_tb_transport_message_buffer_copy 35 | -_tb_transport_message_buffer_wrap_buffer 36 | -_tb_transport_set_message_handler 37 | -_tb_transport_set_message_handler_f 38 | -_tb_transport_set_reply_sent_handler 39 | -_tb_endpoint_create 40 | -_tb_endpoint_create_with_data 41 | -_tb_endpoint_create_with_value 42 | -_tb_endpoint_create_with_value_static 43 | -_tb_endpoint_destruct 44 | -_tb_endpoint_get_data 45 | -_tb_endpoint_get_options 46 | -_tb_endpoint_get_type 47 | -_tb_endpoint_get_value 48 | -_tb_message_complete 49 | -_tb_message_configure_recieved 50 | -_tb_message_construct 51 | -_tb_message_decode_bool 52 | -_tb_message_decode_f32 53 | -_tb_message_decode_f64 54 | -_tb_message_decode_s16 55 | -_tb_message_decode_s32 56 | -_tb_message_decode_s64 57 | -_tb_message_decode_s8 58 | -_tb_message_decode_u16 59 | -_tb_message_decode_u32 60 | -_tb_message_decode_u64 61 | -_tb_message_decode_u8 62 | -_tb_message_destruct 63 | -_tb_message_encode_bool 64 | -_tb_message_encode_buffer 65 | -_tb_message_encode_f32 66 | -_tb_message_encode_f64 67 | -_tb_message_encode_s16 68 | -_tb_message_encode_s32 69 | -_tb_message_encode_s64 70 | -_tb_message_encode_s8 71 | -_tb_message_encode_u16 72 | -_tb_message_encode_u32 73 | -_tb_message_encode_u64 74 | -_tb_message_encode_u8 75 | -_tb_message_get_disposition 76 | -_tb_message_get_state 77 | -_tb_message_get_client_identifier 78 | -_tb_message_get_transport_buffer 79 | -_tb_message_measure_subrange 80 | -_tb_message_set_client_identifier 81 | -_tb_message_set_disposition 82 | -_tb_message_set_state 83 | -_tb_message_size_bool 84 | -_tb_message_size_f32 85 | -_tb_message_size_f64 86 | -_tb_message_size_s16 87 | -_tb_message_size_s32 88 | -_tb_message_size_s64 89 | -_tb_message_size_s8 90 | -_tb_message_size_u16 91 | -_tb_message_size_u32 92 | -_tb_message_size_u64 93 | -_tb_message_size_u8 94 | -_tb_message_subrange 95 | -------------------------------------------------------------------------------- /patches/15.0/restore_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 1: The tag to restore from 4 | # 2: The path to restore from 5 | restore_files_from_tag() { 6 | # Search for all files that were deleted at this tag in the given path, 7 | # and restore them in the current directory. This doesn't touch 8 | # files in the same directory that are still present. 9 | 10 | local TAG="${1}" 11 | local DIR="${2}" 12 | 13 | for file in $(git diff --name-only --diff-filter=D "${TAG}"..HEAD -- "${DIR}"); do 14 | echo "Checking out ${file}" 15 | git checkout "${TAG}" "${file}" 16 | done 17 | } 18 | 19 | restore_files_from_tag xnu-8796.101.5 EXTERNAL_HEADERS/TrustCache 20 | restore_files_from_tag xnu-10063.121.3 iokit/DriverKit 21 | -------------------------------------------------------------------------------- /patches/15.0/skywalk.patch: -------------------------------------------------------------------------------- 1 | diff --git a/bsd/skywalk/packet/packet_kern.c b/bsd/skywalk/packet/packet_kern.c 2 | index 7dbbdf88..04d6de7a 100644 3 | --- a/bsd/skywalk/packet/packet_kern.c 4 | +++ b/bsd/skywalk/packet/packet_kern.c 5 | @@ -287,6 +287,37 @@ kern_packet_get_inet_checksum(const kern_packet_t ph, uint16_t *start, 6 | return __packet_get_inet_checksum(ph, start, val, tx); 7 | } 8 | 9 | +errno_t 10 | +kern_packet_set_fpd_command(const kern_packet_t ph, 11 | + uint8_t cmd) 12 | +{ 13 | + errno_t result; 14 | + 15 | + if (cmd > 7) 16 | + return 22; 17 | + result = 0; 18 | + PKT_ADDR(ph)->pkt_fpd_metadata |= ((cmd & 7) << 6) | 0x8000; 19 | + return result; 20 | +} 21 | + 22 | +errno_t 23 | +kern_packet_set_fpd_sequence_number(const kern_packet_t ph, 24 | + uint32_t seq_num) 25 | +{ 26 | + PKT_ADDR(ph)->pkt_fpd_seqnum = seq_num; 27 | + PKT_ADDR(ph)->pkt_fpd_metadata |= 0x8000; 28 | + return 0; 29 | +} 30 | + 31 | +errno_t 32 | +kern_packet_set_fpd_context_id(const kern_packet_t ph, 33 | + uint16_t ctx_id) 34 | +{ 35 | + PKT_ADDR(ph)->pkt_fpd_metadata |= ctx_id & 0x3F | 0x8000; 36 | + return 0; 37 | +} 38 | + 39 | + 40 | void 41 | kern_packet_set_flow_uuid(const kern_packet_t ph, const uuid_t flow_uuid) 42 | { 43 | @@ -955,24 +986,6 @@ kern_packet_copy_bytes(kern_packet_t pkt, size_t off, size_t len, void* out_data 44 | return 0; 45 | } 46 | 47 | -errno_t 48 | -kern_packet_set_fpd_sequence_number(__unused const kern_packet_t ph, __unused uint32_t seq_num) 49 | -{ 50 | - return 0; 51 | -} 52 | - 53 | -errno_t 54 | -kern_packet_set_fpd_context_id(__unused const kern_packet_t ph, __unused uint16_t ctx_id) 55 | -{ 56 | - return 0; 57 | -} 58 | - 59 | -errno_t 60 | -kern_packet_set_fpd_command(__unused const kern_packet_t ph, __unused uint8_t cmd) 61 | -{ 62 | - return 0; 63 | -} 64 | - 65 | errno_t 66 | kern_packet_get_flowid(const kern_packet_t ph, packet_flowid_t *pflowid) 67 | { 68 | diff --git a/bsd/skywalk/packet/packet_var.h b/bsd/skywalk/packet/packet_var.h 69 | index 6474f5f0..cf37cb09 100644 70 | --- a/bsd/skywalk/packet/packet_var.h 71 | +++ b/bsd/skywalk/packet/packet_var.h 72 | @@ -441,7 +441,8 @@ struct __kern_packet { 73 | 74 | void * pkt_priv; /* free to use for every layer */ 75 | 76 | - 77 | + uint32_t pkt_fpd_seqnum; // @ 0xd0 78 | + uint16_t pkt_fpd_metadata; // @ 0xd4 79 | /* 80 | * Kernel specific. 81 | * 82 | -------------------------------------------------------------------------------- /patches/TrustCache.patch: -------------------------------------------------------------------------------- 1 | diff --git a/EXTERNAL_HEADERS/TrustCache/API.h b/EXTERNAL_HEADERS/TrustCache/API.h 2 | new file mode 100644 3 | index 00000000..d13cddf3 4 | --- /dev/null 5 | +++ b/EXTERNAL_HEADERS/TrustCache/API.h 6 | @@ -0,0 +1,188 @@ 7 | +#ifndef libTrustCache_API_h 8 | +#define libTrustCache_API_h 9 | + 10 | +#include 11 | +__BEGIN_DECLS 12 | + 13 | +#include 14 | +#include 15 | +#include 16 | +#include 17 | +#include 18 | +#include 19 | +#include 20 | + 21 | +/** 22 | + * NOTE: This library does not enforce any concurrency by itself. To be safe in a multi-threaded 23 | + * environment, the caller must manually enforce concurrency on the runtime data structure as 24 | + * otherwise the library is susceptible to memory corruption from race conditions. 25 | + */ 26 | + 27 | +/** 28 | + * Initialize a runtime to the default values. 29 | + * 30 | + * If the system supports read-only segments, and the runtime is allocated within the read-only 31 | + * segment, then this function needs to be called before the segment is enforced to be read-only. 32 | + * For more information, please look at . 33 | + */ 34 | +static inline void 35 | +trustCacheInitializeRuntime(TrustCacheRuntime_t *runtime, 36 | + TrustCacheMutableRuntime_t *mutableRT, 37 | + bool allowSecondStaticTC, 38 | + bool allowEngineeringTC, 39 | + bool allowLegacyTC, 40 | + const img4_runtime_t *image4RT) 41 | +{ 42 | + /* Zero out everything */ 43 | + memset(runtime, 0, sizeof(*runtime)); 44 | + memset(mutableRT, 0, sizeof(*mutableRT)); 45 | + 46 | + /* Set the mutable runtime pointer */ 47 | + runtime->mutableRT = mutableRT; 48 | + 49 | + /* Setup trust cache type permissions */ 50 | + runtime->allowSecondStaticTC = allowSecondStaticTC; 51 | + runtime->allowEngineeringTC = allowEngineeringTC; 52 | + runtime->allowLegacyTC = allowLegacyTC; 53 | + 54 | + /* Set the image4 runtime */ 55 | + runtime->image4RT = image4RT; 56 | +} 57 | + 58 | +/** 59 | + * Construct a trust cache object from some module bytes. The module is validated for 60 | + * correctness before being returned. 61 | + */ 62 | +TCReturn_t 63 | +trustCacheConstructInvalid(TrustCache_t *trustCache, 64 | + const uint8_t *moduleAddr, 65 | + size_t moduleSize); 66 | + 67 | +/** 68 | + * Check the runtime for a trust cache which matches a particular UUID. Since we do 69 | + * not allow trust caches with duplocate UUIDs, there can only ever be a single trust 70 | + * cache with a particular UUID within the runtime. 71 | + */ 72 | +TCReturn_t 73 | +trustCacheCheckRuntimeForUUID(const TrustCacheRuntime_t *runtime, 74 | + const uint8_t checkUUID[kUUIDSize], 75 | + const TrustCache_t **trustCacheRet); 76 | + 77 | +/** 78 | + * Add a trust cache module directly to the runtime. This function is used to add modules which 79 | + * don't need to be separately authenticated. Currently, the only trust cache types which can be 80 | + * used with this function are static and engineering trust caches. 81 | + * 82 | + * If the system supports read-only segments, and the runtime is allocated within the read-only 83 | + * segment, then this function needs to be called before the segment is enforced to be read-only. 84 | + * For more information, please look at . 85 | + */ 86 | +TCReturn_t 87 | +trustCacheLoadModule(TrustCacheRuntime_t *runtime, 88 | + const TCType_t type, 89 | + TrustCache_t *trustCache, 90 | + const uintptr_t dataAddr, 91 | + const size_t dataSize); 92 | + 93 | +/** 94 | + * Load a trust cache onto the system. This function validates the trust cache for a proper 95 | + * signature and adds it to the runtime. 96 | + * 97 | + * Both the payload and the manifest must be provided and they will be validated as image4 98 | + * objects. 99 | + */ 100 | +TCReturn_t 101 | +trustCacheLoad(TrustCacheRuntime_t *runtime, 102 | + TCType_t type, 103 | + TrustCache_t *trustCache, 104 | + const uintptr_t payloadAddr, 105 | + const size_t payloadSize, 106 | + const uintptr_t manifestAddr, 107 | + const size_t manifestSize); 108 | + 109 | +/** 110 | + * Extract an image4 artifact from an image4 file or an image4 payload and extract the 111 | + * trust cache module embedded within it. The module is validated for correctness 112 | + * before being returned, however the image4 signature is not verified. 113 | + * 114 | + * The returned trust cache object is marked with an invalid type. 115 | + */ 116 | +TCReturn_t 117 | +trustCacheExtractModule(TrustCache_t *trustCache, 118 | + const uint8_t *dataAddr, 119 | + size_t dataSize); 120 | + 121 | +/** 122 | + * Query a trust cache for a particular CDHash. The returned token can then be used to 123 | + * query further attributes from the matched entry. 124 | + */ 125 | +TCReturn_t 126 | +trustCacheQuery(const TrustCacheRuntime_t *runtime, 127 | + TCQueryType_t queryType, 128 | + const uint8_t CDHash[kTCEntryHashSize], 129 | + TrustCacheQueryToken_t *queryToken); 130 | + 131 | +/** 132 | + * Get the module bytes backng a trust cache object. The environment may have chosen 133 | + * to allocate the module bytes within read-only memory, so the bytes returned may 134 | + * not be mutable. 135 | + */ 136 | +TCReturn_t 137 | +trustCacheGetModule(const TrustCache_t *trustCache, 138 | + const uint8_t **moduleAddrRet, 139 | + size_t *moduleSizeRet); 140 | + 141 | +/** 142 | + * Get the UUID of the trust cache module represented by the wrapped trust cache object. 143 | + */ 144 | +TCReturn_t 145 | +trustCacheGetUUID(const TrustCache_t *trustCache, 146 | + uint8_t returnUUID[kUUIDSize]); 147 | + 148 | +/** 149 | + * Get the capabilities of a trust cache. This function can be used to query which fields a given 150 | + * trust cache supports. 151 | + * 152 | + * The fields which are supported are based on the version of the trust cache module. 153 | + */ 154 | +TCReturn_t 155 | +trustCacheGetCapabilities(const TrustCache_t *trustCache, 156 | + TCCapabilities_t *capabilities); 157 | + 158 | +/** 159 | + * Acquire the trust cache type for a query token. 160 | + */ 161 | +TCReturn_t 162 | +trustCacheQueryGetTCType(const TrustCacheQueryToken_t *queryToken, 163 | + TCType_t *typeRet); 164 | + 165 | +/** 166 | + * Acquire the capabilities of the trust cache through a query token. 167 | + */ 168 | +TCReturn_t 169 | +trustCacheQueryGetCapabilities(const TrustCacheQueryToken_t *queryToken, 170 | + TCCapabilities_t *capabilities); 171 | + 172 | +/** 173 | + * Acquire the hash type for the CDHash through a query token. 174 | + */ 175 | +TCReturn_t 176 | +trustCacheQueryGetHashType(const TrustCacheQueryToken_t *queryToken, 177 | + uint8_t *hashTypeRet); 178 | + 179 | +/** 180 | + * Acquire the flags for a trust cache entry through a query token. 181 | + */ 182 | +TCReturn_t 183 | +trustCacheQueryGetFlags(const TrustCacheQueryToken_t *queryToken, 184 | + uint64_t *flagsRet); 185 | + 186 | +/** 187 | + * Acquire the constraint category for a trust cache entry through a query token. 188 | + */ 189 | +TCReturn_t 190 | +trustCacheQueryGetConstraintCategory(const TrustCacheQueryToken_t *queryToken, 191 | + uint8_t *constraintCategoryRet); 192 | + 193 | +__END_DECLS 194 | +#endif /* libTrustCache_API_h */ 195 | diff --git a/EXTERNAL_HEADERS/TrustCache/RawTypes.h b/EXTERNAL_HEADERS/TrustCache/RawTypes.h 196 | new file mode 100644 197 | index 00000000..16b684e2 198 | --- /dev/null 199 | +++ b/EXTERNAL_HEADERS/TrustCache/RawTypes.h 200 | @@ -0,0 +1,103 @@ 201 | +#ifndef libTrustCache_RawTypes_h 202 | +#define libTrustCache_RawTypes_h 203 | + 204 | +#include 205 | +__BEGIN_DECLS 206 | + 207 | +#include 208 | +#include 209 | + 210 | +/* 211 | + * CDHashes in the trust cache are always truncated to the length of a SHA1 hash. 212 | + */ 213 | +#define kTCEntryHashSize CCSHA1_OUTPUT_SIZE 214 | + 215 | +/* UUIDs are always 16 bytes */ 216 | +#define kUUIDSize 16 217 | + 218 | +/* Versions supported by the library */ 219 | +enum { 220 | + kTCVersion0 = 0x0, 221 | + kTCVersion1 = 0x1, 222 | + kTCVersion2 = 0x2, 223 | + 224 | + kTCVersionTotal, 225 | +}; 226 | + 227 | +/* Flags for the trust cache look ups */ 228 | +enum { 229 | + kTCFlagAMFID = 0x01, 230 | + kTCFlagANEModel = 0x02, 231 | +}; 232 | + 233 | +typedef struct _TrustCacheModuleBase { 234 | + /* The version for this trust cache module */ 235 | + uint32_t version; 236 | +} __attribute__((packed)) TrustCacheModuleBase_t; 237 | + 238 | +#pragma mark Trust Cache Version 0 239 | + 240 | +typedef uint8_t TrustCacheEntry0_t[kTCEntryHashSize]; 241 | + 242 | +typedef struct _TrustCacheModule0 { 243 | + /* Must be 0 */ 244 | + uint32_t version; 245 | + 246 | + /* ID which uniquely identifies the trust cache */ 247 | + uint8_t uuid[kUUIDSize]; 248 | + 249 | + /* The number of entries present in the trust cache */ 250 | + uint32_t numEntries; 251 | + 252 | + /* Dynamic data containing all the entries */ 253 | + TrustCacheEntry0_t entries[0]; 254 | +} __attribute__((packed)) TrustCacheModule0_t; 255 | + 256 | +#pragma mark Trust Cache Version 1 257 | + 258 | +typedef struct _TrustCacheEntry1 { 259 | + uint8_t CDHash[kTCEntryHashSize]; 260 | + uint8_t hashType; 261 | + uint8_t flags; 262 | +} __attribute__((packed)) TrustCacheEntry1_t; 263 | + 264 | +typedef struct _TrustCacheModule1 { 265 | + /* Must be 1 */ 266 | + uint32_t version; 267 | + 268 | + /* ID which uniquely identifies the trust cache */ 269 | + uint8_t uuid[kUUIDSize]; 270 | + 271 | + /* The number of entries present in the trust cache */ 272 | + uint32_t numEntries; 273 | + 274 | + /* Dynamic data containing all the entries */ 275 | + TrustCacheEntry1_t entries[0]; 276 | +} __attribute__((packed)) TrustCacheModule1_t; 277 | + 278 | +#pragma mark Trust Cache Version 2 279 | + 280 | +typedef struct _TrustCacheEntry2 { 281 | + uint8_t CDHash[kTCEntryHashSize]; 282 | + uint8_t hashType; 283 | + uint8_t flags; 284 | + uint8_t constraintCategory; 285 | + uint8_t reserved0; 286 | +} __attribute__((packed)) TrustCacheEntry2_t; 287 | + 288 | +typedef struct _TrustCacheModule2 { 289 | + /* Must be 2 */ 290 | + uint32_t version; 291 | + 292 | + /* ID which uniquely identifies the trust cache */ 293 | + uint8_t uuid[kUUIDSize]; 294 | + 295 | + /* The number of entries present in the trust cache */ 296 | + uint32_t numEntries; 297 | + 298 | + /* Dynamic data containing all the entries */ 299 | + TrustCacheEntry2_t entries[0]; 300 | +} __attribute__((packed)) TrustCacheModule2_t; 301 | + 302 | +__END_DECLS 303 | +#endif /* libTrustCache_RawTypes_h */ 304 | diff --git a/EXTERNAL_HEADERS/TrustCache/Return.h b/EXTERNAL_HEADERS/TrustCache/Return.h 305 | new file mode 100644 306 | index 00000000..440a53c4 307 | --- /dev/null 308 | +++ b/EXTERNAL_HEADERS/TrustCache/Return.h 309 | @@ -0,0 +1,123 @@ 310 | +#ifndef libTrustCache_Return_h 311 | +#define libTrustCache_Return_h 312 | + 313 | +#include 314 | +__BEGIN_DECLS 315 | + 316 | +#include 317 | + 318 | +/* Components which can return information from the library */ 319 | +enum { 320 | + kTCComponentLoadModule = 0x00, 321 | + kTCComponentLoad = 0x01, 322 | + kTCComponentImage4Validate = 0x02, 323 | + kTCComponentImage4Callback = 0x03, 324 | + kTCComponentConstructInvalid = 0x04, 325 | + kTCComponentCheckRuntimeForUUID = 0x05, 326 | + kTCComponentExtractModule = 0x06, 327 | + kTCComponentGetUUID = 0x07, 328 | + kTCComponentGetModule = 0x08, 329 | + 330 | + /* Query Functions */ 331 | + kTCComponentQuery = 0x10, 332 | + kTCComponentQueryChain = 0x11, 333 | + kTCComponentQueryRuntime = 0x12, 334 | + kTCComponentQueryTCType = 0x13, 335 | + kTCComponentQueryHashType = 0x14, 336 | + kTCComponentQueryFlags = 0x15, 337 | + kTCComponentQueryConstraintCategory = 0x16, 338 | + 339 | + /* Module based */ 340 | + kTCComponentQueryModule = 0x40, 341 | + kTCComponentValidateModule = 0x41, 342 | + kTCComponentQueryModule0 = 0x42, 343 | + kTCComponentValidateModule0 = 0x43, 344 | + kTCComponentQueryModule1 = 0x44, 345 | + kTCComponentValidateModule1 = 0x45, 346 | + kTCComponentQueryModule2 = 0x46, 347 | + kTCComponentValidateModule2 = 0x47, 348 | + kTCComponentModuleCapabilities = 0x48, 349 | + 350 | + /* Other functions which can return a value */ 351 | + kTCComponentLinkedListAddHead = 0x80, 352 | + kTCComponentLinkedListRemove = 0x81, 353 | + kTCComponentExtractImage4Payload = 0x82, 354 | + 355 | + /* Cannot exceed this value */ 356 | + kTCComponentTotal = 0xFF, 357 | +}; 358 | + 359 | +/* Error types which can be returned from the library */ 360 | +enum { 361 | + kTCReturnSuccess = 0x00, 362 | + 363 | + /* Generic error condition - avoid using this */ 364 | + kTCReturnError = 0x01, 365 | + 366 | + /* Specific error conditions */ 367 | + kTCReturnOverflow = 0x20, 368 | + kTCReturnUnsupported = 0x21, 369 | + kTCReturnInvalidModule = 0x22, 370 | + kTCReturnDuplicate = 0x23, 371 | + kTCReturnNotFound = 0x24, 372 | + kTCReturnInvalidArguments = 0x25, 373 | + kTCReturnInsufficientLength = 0x26, 374 | + kTCReturnNotPermitted = 0x27, 375 | + kTCReturnLinkedListCorrupted = 0x28, 376 | + 377 | + /* Image 4 return errors */ 378 | + kTCReturnImage4Expired = 0xA0, 379 | + kTCReturnImage4UnknownFormat = 0xA1, 380 | + kTCReturnImage4WrongObject = 0xA2, 381 | + kTCReturnImage4WrongCrypto = 0xA3, 382 | + kTCReturnImage4ManifestViolation = 0xA4, 383 | + kTCReturnImage4PayloadViolation = 0xA5, 384 | + kTCReturnImage4PermissionDenied = 0xA6, 385 | + kTCReturnImage4NoChipAvailable = 0xA7, 386 | + kTCReturnImage4NoNonceAvailable = 0xA8, 387 | + kTCReturnImage4NoDeviceAvailable = 0xA9, 388 | + kTCReturnImage4DecodeError = 0xAA, 389 | + kTCReturnImage4UnknownError = 0xAF, 390 | + 391 | + /* Cannot exceed this value */ 392 | + kTCReturnTotal = 0xFF 393 | +}; 394 | + 395 | +typedef struct _TCReturn { 396 | + union { 397 | + /* Raw 32 bit representation of the return code */ 398 | + uint32_t rawValue; 399 | + 400 | + /* Formatted representation of the return code */ 401 | + struct { 402 | + /* Component of the library which is returning the code */ 403 | + uint8_t component; 404 | + 405 | + /* Error code which is being returned */ 406 | + uint8_t error; 407 | + 408 | + /* Unique error path within the component */ 409 | + uint16_t uniqueError; 410 | + } __attribute__((packed)); 411 | + } __attribute__((packed)); 412 | +} __attribute__((packed)) TCReturn_t; 413 | + 414 | +/* Ensure the size of the structure remains as expected */ 415 | +_Static_assert(sizeof(TCReturn_t) == sizeof(uint32_t), "TCReturn_t is not 32 bits large"); 416 | + 417 | +static inline TCReturn_t 418 | +buildTCRet(uint8_t component, 419 | + uint8_t error, 420 | + uint16_t uniqueError) 421 | +{ 422 | + TCReturn_t ret = { 423 | + .component = component, 424 | + .error = error, 425 | + .uniqueError = uniqueError 426 | + }; 427 | + 428 | + return ret; 429 | +} 430 | + 431 | +__END_DECLS 432 | +#endif /* libTrustCache_Return_h */ 433 | diff --git a/EXTERNAL_HEADERS/TrustCache/Types.h b/EXTERNAL_HEADERS/TrustCache/Types.h 434 | new file mode 100644 435 | index 00000000..f3412f38 436 | --- /dev/null 437 | +++ b/EXTERNAL_HEADERS/TrustCache/Types.h 438 | @@ -0,0 +1,320 @@ 439 | +#ifndef libTrustCache_Types_h 440 | +#define libTrustCache_Types_h 441 | + 442 | +#include 443 | +__BEGIN_DECLS 444 | + 445 | +#include 446 | +#include 447 | +#include 448 | + 449 | +typedef uint8_t TCType_t; 450 | +enum { 451 | + /* 452 | + * These types of trust caches are always loaded as modules. Their validation 453 | + * is done externally by upper-level software. 454 | + * 455 | + * Static trust caches are bundled with the operating system and are the primary 456 | + * method of denoting platform trust. Engineering trust caches are similar to 457 | + * static trust caches except that they can be created by engineers at their 458 | + * desk as a root for a static trust cache. Legacy trust caches are image3 signed 459 | + * modules. This library does not support validating image3 signatures, so it 460 | + * accepts the trust caches only as direct modules. These are still considered 461 | + * loadable trust caches. 462 | + */ 463 | + kTCTypeStatic = 0x00, 464 | + kTCTypeEngineering = 0x01, 465 | + kTCTypeLegacy = 0x02, 466 | + 467 | + /* 468 | + * Do NOT change the order of the types listed here. This header is shared across 469 | + * a variety of projects and they update at different cadences. Adding a new type 470 | + * requires appending to the end of the enumeration, instead of insertion in the 471 | + * middle somewhere. 472 | + */ 473 | + 474 | + /* 475 | + * Type: Personalized 476 | + * These are engineering roots which are only ever valid for development devices. 477 | + * These can be created by engineers at their desks for testing software. 478 | + */ 479 | + kTCTypeDTRS = 0x03, 480 | + 481 | + /* 482 | + * Type: Personalized 483 | + * These are loadable trust caches which are viable for all kinds of devices and 484 | + * can be used for testing, but also for shipping code in production devices. 485 | + */ 486 | + kTCTypeLTRS = 0x04, 487 | + 488 | + /* 489 | + * Type: Personalized 490 | + * Used by disk images which are used to supply platform code for a number of use 491 | + * cases, including the multidude of disk images supplied for engineering use-cases 492 | + * such as the factoey disk image. 493 | + */ 494 | + kTCTypePersonalizedDiskImage = 0x05, 495 | + 496 | + /* 497 | + * Type: Categorized 498 | + * Developer disk images which are personalized per device. These have a different 499 | + * tag than standard loadable trust caches and helps differentiate them. However, 500 | + * these were never productionized and are for all purposes, retired. 501 | + */ 502 | + kTCTypeDeveloperDiskImage = 0x06, 503 | + 504 | + /* 505 | + * Type: Personalized 506 | + * These trust caches are similar to a personalized LTRS trust cache type except 507 | + * they are personalized against a long lived nonce, allowing these to remain 508 | + * useable across reboots of the system. 509 | + */ 510 | + kTCTypeLTRSWithDDINonce = 0x07, 511 | + 512 | + /* 513 | + * Type: Personalized 514 | + * These trust cache types are used to authenticate code shipped in Cryptexes for 515 | + * security research devices. Outside of the SRD, these are also used in some data 516 | + * center use cases which deploy code through Cryptexes. 517 | + */ 518 | + kTCTypeCryptex = 0x08, 519 | + 520 | + /* 521 | + * Type: Personalized (against supplemental root) 522 | + * These are special trust caches which validate against a supplemental root beyond 523 | + * Tatsu. These are only meant for special deployments within some data centers. 524 | + * 525 | + * NOTE: This type is deprecated in favor of the newer Supplemental Persistent 526 | + * and Supplemental Ephemeral types. 527 | + */ 528 | + kTCTypeEphemeralCryptex = 0x09, 529 | + 530 | + /* 531 | + * Type: Global 532 | + * OTA updates ship an update brain to assist with the OS update. The brain is some 533 | + * code with platform privileges which can do whatever the current OS needs it to do 534 | + * in order to update the system. 535 | + */ 536 | + kTCTypeUpdateBrain = 0x0A, 537 | + 538 | + /* 539 | + * Type: Global 540 | + * Trust caches which are loaded by the Install Assistant on macOS in order to help 541 | + * with installing macOS. 542 | + */ 543 | + kTCTypeInstallAssistant = 0x0B, 544 | + 545 | + /* 546 | + * Type: Global 547 | + * These are used by macOS systems to ship a bootability brain. The bootability brain 548 | + * is a piece of code which helps determine if macOS systems of a different version 549 | + * are bootable or not. The brain is useful because the logic for determining that a 550 | + * system is bootable or not differs with each release. 551 | + */ 552 | + kTCTypeBootabilityBrain = 0x0C, 553 | + 554 | + /* 555 | + * Type: Personalized (against Cryptex 1 Boot/Preboot environments) 556 | + * These trust cache types are used by SPLAT at different stages of the boot pipeline 557 | + * for loading code responsible for system boot up, such as the shared cache. 558 | + * 559 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 560 | + * manifest itself. 561 | + */ 562 | + kTCTypeCryptex1BootOS = 0x0D, 563 | + kTCTypeCryptex1BootApp = 0x0E, 564 | + kTCTypeCryptex1PreBootApp = 0x0F, 565 | + 566 | + /* 567 | + * Type: Global 568 | + * These are disk images which are globally signed against the FF00 chip environment. 569 | + * They are used when disk images want to supply code for devices across the fleet 570 | + * without requiring individual personalization for each. 571 | + * 572 | + * The developer disk image is supplied through this mechanism as well, as of January 573 | + * 5th, 2022. 574 | + */ 575 | + kTCTypeGlobalDiskImage = 0x10, 576 | + 577 | + /* 578 | + * Type: Personalized (Cryptex1 mobile asset brain) 579 | + * The mobile asset brain contains the core logic for mobileassetd, which is a system 580 | + * daemon responsible for downloading and maintaining assets on the device. The brain 581 | + * is meant to be back-deployable, which is what the trust cache helps with. 582 | + * 583 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 584 | + * manifest itself. 585 | + */ 586 | + kTCTypeMobileAssetBrain = 0x11, 587 | + 588 | + /* 589 | + * Type: Personalized (Cryptex1 boot reduced) 590 | + * Safari is backported to older builds. Since Safari is now moving to a SPLAT based 591 | + * mount volume, we need to support loading a trust cache which is used to mount and 592 | + * run Safari from the future. 593 | + * 594 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 595 | + * manifest itself. 596 | + */ 597 | + kTCTypeSafariDownlevel = 0x12, 598 | + 599 | + /* 600 | + * Type: Personalized (Cryptex 1 Preboot) 601 | + * This trust cache type is used for the semi-SPLAT use-case for loading the new dyld 602 | + * shared cache onto the platform, along with some other system libraries. This is 603 | + * only required for macOS. 604 | + * 605 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 606 | + * manifest itself. 607 | + */ 608 | + kTCTypeCryptex1PreBootOS = 0x13, 609 | + 610 | + /* 611 | + * Type: Personalized (Supplemental Root) 612 | + * Persistent trust caches which are signed by an authority different from Tatsu. 613 | + * These are only required for deployment on darwinOS platforms. 614 | + */ 615 | + kTCTypeSupplementalPersistent = 0x14, 616 | + 617 | + /* 618 | + * Type: Personalized (Supplemental Root) 619 | + * Ephemeral trust caches which are signed by an authority different from Tatsu. 620 | + * These are only required for deployment on darwinOS platforms. 621 | + */ 622 | + kTCTypeSupplementalEphemeral = 0x15, 623 | + 624 | + /* 625 | + * Type: Personalized (Cryptex1 Generic) 626 | + * This type can be used by the assortment of PDIs we ship. Each PDI train can opt 627 | + * into allocating a Cryptex1 sub-type for itself, and then ship on the OS being 628 | + * signed by the Cryptex1 generic environment. This allows the PDI to adopt Cryptex1 629 | + * personalization without requiring a new bespoke trust cache type. 630 | + * 631 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 632 | + * manifest itself. 633 | + */ 634 | + kTCTypeCryptex1Generic = 0x16, 635 | + 636 | + /* 637 | + * Type: Personalized (Cryptex1 Generic Supplemental) 638 | + * Similar to the kTCTypeCryptex1Generic type except the manifest is signed by the 639 | + * supplemental root of trust. Only viable for some data center use-cases. 640 | + * 641 | + * The personalization uses a Cryptex1 nonce domain, which is embedded within the 642 | + * manifest itself. 643 | + */ 644 | + kTCTypeCryptex1GenericSupplemental = 0x17, 645 | + 646 | + kTCTypeTotal, 647 | + 648 | + /* Invalid type */ 649 | + kTCTypeInvalid = 0xFF, 650 | +}; 651 | + 652 | +/* Availability macros for different trust cache types */ 653 | +#define kLibTrustCacheHasCryptex1BootOS 1 654 | +#define kLibTrustCacheHasCryptex1BootApp 1 655 | +#define kLibTrustCacheHasCryptex1PreBootApp 1 656 | +#define kLibTrustCacheHasMobileAssetBrain 1 657 | +#define kLibTrustCacheHasSafariDownlevel 1 658 | +#define kLibTrustCacheHasCryptex1PreBootOS 1 659 | +#define kLibTrustCacheHasSupplementalPersistent 1 660 | +#define kLibTrustCacheHasSupplementalEphemeral 1 661 | +#define kLibTrustCacheHasCryptex1Generic 1 662 | +#define kLibTrustCacheHasCryptex1GenericSupplemental 1 663 | + 664 | +typedef struct _TrustCache { 665 | + /* Linked list linkage for the trust cache */ 666 | + struct _TrustCache *next; 667 | + struct _TrustCache *prev; 668 | + 669 | + /* The type of this trust cache */ 670 | + TCType_t type; 671 | + 672 | + /* TODO: Add reference counts when we support unloading */ 673 | + 674 | + /* The trust cache module itself */ 675 | + size_t moduleSize; 676 | + const TrustCacheModuleBase_t *module; 677 | +} TrustCache_t; 678 | + 679 | +typedef uint8_t TCQueryType_t; 680 | +enum { 681 | + /* Query all types of trust caches in the runtime */ 682 | + kTCQueryTypeAll = 0x00, 683 | + 684 | + /* Static query type includes engineering trust caches */ 685 | + kTCQueryTypeStatic = 0x01, 686 | + 687 | + /* Most first party trust cache types are loadable ones */ 688 | + kTCQueryTypeLoadable = 0x02, 689 | + 690 | + kTCQueryTypeTotal, 691 | +}; 692 | + 693 | +typedef uint64_t TCCapabilities_t; 694 | +enum { 695 | + /* Supports no capabilities */ 696 | + kTCCapabilityNone = 0, 697 | + 698 | + /* Supports the hash type field */ 699 | + kTCCapabilityHashType = (1 << 0), 700 | + 701 | + /* Supports the flags field */ 702 | + kTCCapabilityFlags = (1 << 1), 703 | + 704 | + /* Supports the constraints category field */ 705 | + kTCCapabilityConstraintsCategory = (1 << 2), 706 | +}; 707 | + 708 | +typedef struct _TrustCacheQueryToken { 709 | + /* Trust cache where query was found */ 710 | + const TrustCache_t *trustCache; 711 | + 712 | + /* Entry within the trust cache where query was found */ 713 | + const void *trustCacheEntry; 714 | +} TrustCacheQueryToken_t; 715 | + 716 | +/* 717 | + * The runtime data structure is setup in a very special way. To make use of HW mitigations 718 | + * offered by the silicon, the runtime can be placed in a region which is locked down by the 719 | + * HW at some commit point. This theoretically allows the static and the engineering trust 720 | + * caches to be locked down and immutable if the storage for the trust cache data structure 721 | + * is also allocated within this same immutable memory segment. 722 | + * 723 | + * At the same time, we need to be able to support dynamically loaded trust caches on the 724 | + * system. We can't keep a list head within the runtime for these trust caches, since that 725 | + * head will be locked down when the runtime is locked, preventing us from adding a new link 726 | + * in the chain. To solve this, the runtime instead stores a pointer to a wrapped data structure. 727 | + * This pointer itself is locked down and can't be changed, but the contents of the wrapped 728 | + * structure are mutable, making it a good place to store the linked list head. 729 | + */ 730 | + 731 | +/* Data structure expected to be stored within mutable memory */ 732 | +typedef struct _TrustCacheMutableRuntime { 733 | + /* Loadable trust caches on the system */ 734 | + TrustCache_t *loadableTCHead; 735 | +} TrustCacheMutableRuntime_t; 736 | + 737 | +/* Data structure expected to be stored within immutable memory */ 738 | +typedef struct _TrustCacheRuntime { 739 | + /* Runtime to use for image 4 object verification */ 740 | + const img4_runtime_t *image4RT; 741 | + 742 | + /* Configuration for trust cache types */ 743 | + bool allowSecondStaticTC; 744 | + bool allowEngineeringTC; 745 | + bool allowLegacyTC; 746 | + 747 | + /* Static trust cache for the system */ 748 | + TrustCache_t *staticTCHead; 749 | + 750 | + /* Engineering trust caches for the system */ 751 | + TrustCache_t *engineeringTCHead; 752 | + 753 | + /* Mutable runtime instance */ 754 | + TrustCacheMutableRuntime_t *mutableRT; 755 | +} TrustCacheRuntime_t; 756 | + 757 | +__END_DECLS 758 | +#endif /* libTrustCache_Types_h */ 759 | diff --git a/EXTERNAL_HEADERS/TrustCache/TypesConfig.h b/EXTERNAL_HEADERS/TrustCache/TypesConfig.h 760 | new file mode 100644 761 | index 00000000..d93e8b09 762 | --- /dev/null 763 | +++ b/EXTERNAL_HEADERS/TrustCache/TypesConfig.h 764 | @@ -0,0 +1,389 @@ 765 | +#ifndef libTrustCache_TypesConfig_h 766 | +#define libTrustCache_TypesConfig_h 767 | + 768 | +#include 769 | +__BEGIN_DECLS 770 | + 771 | +#include 772 | + 773 | +#if XNU_KERNEL_PRIVATE 774 | +/* 775 | + * The AppleImage4 API definitions are accessed through the 'img4if' indirection 776 | + * layer within XNU itself. Kernel extensions can access them directly from the 777 | + * AppleImage4 headers. 778 | + */ 779 | +#include 780 | +#endif 781 | + 782 | +#if !XNU_KERNEL_PRIVATE 783 | +/* 784 | + * XNU does not make this header available and uses different availability macros 785 | + * than kernel extensions or base user-space applications. 786 | + */ 787 | +#include 788 | +#endif 789 | + 790 | +#pragma mark Chip Environments 791 | + 792 | +static const img4_chip_t* 793 | +chipEnvironmentPersonalized(void) { 794 | + return img4_chip_select_personalized_ap(); 795 | +} 796 | + 797 | +static const img4_chip_t* 798 | +chipEnvironmentCategorized(void) { 799 | + return img4_chip_select_categorized_ap(); 800 | +} 801 | + 802 | +static const img4_chip_t* 803 | +chipEnvironmentGlobalFF00(void) { 804 | + return IMG4_CHIP_AP_SOFTWARE_FF00; 805 | +} 806 | + 807 | +static const img4_chip_t* 808 | +chipEnvironmentGlobalFF01(void) { 809 | + return IMG4_CHIP_AP_SOFTWARE_FF01; 810 | +} 811 | + 812 | +static const img4_chip_t* 813 | +chipEnvironmentGlobalFF06(void) { 814 | + return IMG4_CHIP_AP_SOFTWARE_FF06; 815 | +} 816 | + 817 | +static const img4_chip_t* 818 | +chipEnvironmentEphemeralCryptex(void) { 819 | + return IMG4_CHIP_AP_SUPPLEMENTAL; 820 | +} 821 | + 822 | +static const img4_chip_t* 823 | +chipEnvironmentCryptex1Boot(void) { 824 | +#if IMG4_API_VERSION >= 20211126 825 | + return img4_chip_select_cryptex1_boot(); 826 | +#else 827 | + return NULL; 828 | +#endif 829 | +} 830 | + 831 | +static const img4_chip_t* 832 | +chipEnvironmentCryptex1PreBoot(void) { 833 | +#if IMG4_API_VERSION >= 20211126 834 | + return img4_chip_select_cryptex1_preboot(); 835 | +#else 836 | + return NULL; 837 | +#endif 838 | +} 839 | + 840 | +static const img4_chip_t* 841 | +chipEnvironmentCryptex1MobileAsset(void) { 842 | +#if IMG4_API_VERSION >= 20211126 843 | + return IMG4_CHIP_CRYPTEX1_ASSET; 844 | +#else 845 | + return NULL; 846 | +#endif 847 | +} 848 | + 849 | +static const img4_chip_t* 850 | +chipEnvironmentSafariDownlevel(void) { 851 | +#if IMG4_API_VERSION >= 20211126 852 | + return IMG4_CHIP_CRYPTEX1_BOOT_REDUCED; 853 | +#else 854 | + return NULL; 855 | +#endif 856 | +} 857 | + 858 | +static const img4_chip_t* 859 | +chipEnvironmentSupplemental(void) { 860 | + return IMG4_CHIP_AP_SUPPLEMENTAL; 861 | +} 862 | + 863 | +static const img4_chip_t* 864 | +chipEnvironmentCryptex1Generic(void) { 865 | +#if IMG4_API_VERSION >= 20221202 866 | + return IMG4_CHIP_CRYPTEX1_GENERIC; 867 | +#else 868 | + return NULL; 869 | +#endif 870 | +} 871 | + 872 | +static const img4_chip_t* 873 | +chipEnvironmentCryptex1GenericSupplemental(void) { 874 | +#if IMG4_API_VERSION >= 20221202 875 | + return IMG4_CHIP_CRYPTEX1_GENERIC_SUPPLEMENTAL; 876 | +#else 877 | + return NULL; 878 | +#endif 879 | +} 880 | + 881 | +#pragma mark Nonce Domains 882 | + 883 | +static const img4_nonce_domain_t* 884 | +nonceDomainTrustCache(void) { 885 | + return IMG4_NONCE_DOMAIN_TRUST_CACHE; 886 | +} 887 | + 888 | +static const img4_nonce_domain_t* 889 | +nonceDomainDDI(void) { 890 | + return IMG4_NONCE_DOMAIN_DDI; 891 | +} 892 | + 893 | +static const img4_nonce_domain_t* 894 | +nonceDomainCryptex(void) { 895 | + return IMG4_NONCE_DOMAIN_CRYPTEX; 896 | +} 897 | + 898 | +static const img4_nonce_domain_t* 899 | +nonceDomainEphemeralCryptex(void) { 900 | + return IMG4_NONCE_DOMAIN_EPHEMERAL_CRYPTEX; 901 | +} 902 | + 903 | +static const img4_nonce_domain_t* 904 | +nonceDomainPDI(void) { 905 | + return IMG4_NONCE_DOMAIN_PDI; 906 | +} 907 | + 908 | +#pragma mark Firmware Flags 909 | + 910 | +static img4_firmware_flags_t 911 | +firmwareFlagsDTRS(void) { 912 | + return IMG4_FIRMWARE_FLAG_RESPECT_AMNM; 913 | +} 914 | + 915 | +static img4_firmware_flags_t 916 | +firmwareFlagsSplat(void) { 917 | +#if XNU_TARGET_OS_OSX && (defined(__arm__) || defined(__arm64__)) 918 | + return IMG4_FIRMWARE_FLAG_SUBSEQUENT_STAGE; 919 | +#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX && (TARGET_CPU_ARM || TARGET_CPU_ARM64) 920 | + return IMG4_FIRMWARE_FLAG_SUBSEQUENT_STAGE; 921 | +#else 922 | + return IMG4_FIRMWARE_FLAG_INIT; 923 | +#endif 924 | +} 925 | + 926 | +#pragma mark Type Configuration 927 | + 928 | +typedef struct _TrustCacheTypeConfig { 929 | + /* Chip environment to use for validation */ 930 | + const img4_chip_t* (*chipEnvironment)(void); 931 | + 932 | + /* Nonce domain for anti-replay */ 933 | + const img4_nonce_domain_t* (*nonceDomain)(void); 934 | + 935 | + /* Four CC identifier for this type */ 936 | + img4_4cc_t fourCC; 937 | + 938 | + /* Firmware flags to add for this configuration */ 939 | + img4_firmware_flags_t (*firmwareFlags)(void); 940 | + 941 | + /* 942 | + * Higher level policy imposes restrictions on which process can load 943 | + * which trust cache. These restrictions are enforced through the use 944 | + * of the entitlement "com.apple.private.pmap.load-trust-cache". The 945 | + * value here is the required value of the above entitlement. 946 | + */ 947 | + const char *entitlementValue; 948 | +} TrustCacheTypeConfig_t; 949 | + 950 | +#pragma GCC diagnostic push 951 | +#pragma GCC diagnostic ignored "-Wfour-char-constants" 952 | + 953 | +static const TrustCacheTypeConfig_t TCTypeConfig[kTCTypeTotal] = { 954 | + /* Static trust caches are loaded as raw modules */ 955 | + [kTCTypeStatic] = { 956 | + .chipEnvironment = NULL, 957 | + .nonceDomain = NULL, 958 | + .fourCC = 0, 959 | + .firmwareFlags = NULL, 960 | + .entitlementValue = NULL 961 | + }, 962 | + 963 | + /* Engineering trust caches are loaded as raw modules */ 964 | + [kTCTypeEngineering] = { 965 | + .chipEnvironment = NULL, 966 | + .nonceDomain = NULL, 967 | + .fourCC = 0, 968 | + .firmwareFlags = NULL, 969 | + .entitlementValue = NULL 970 | + }, 971 | + 972 | + /* Legacy trust caches are loaded as raw modules */ 973 | + [kTCTypeLegacy] = { 974 | + .chipEnvironment = NULL, 975 | + .nonceDomain = NULL, 976 | + .fourCC = 0, 977 | + .firmwareFlags = NULL, 978 | + .entitlementValue = NULL 979 | + }, 980 | + 981 | + [kTCTypeDTRS] = { 982 | + .chipEnvironment = chipEnvironmentPersonalized, 983 | + .nonceDomain = NULL, 984 | + .fourCC = 'dtrs', 985 | + .firmwareFlags = firmwareFlagsDTRS, 986 | + .entitlementValue = "personalized.engineering-root" 987 | + }, 988 | + 989 | + [kTCTypeLTRS] = { 990 | + .chipEnvironment = chipEnvironmentPersonalized, 991 | + .nonceDomain = nonceDomainTrustCache, 992 | + .fourCC = 'ltrs', 993 | + .firmwareFlags = NULL, 994 | + .entitlementValue = "personalized.trust-cache" 995 | + }, 996 | + 997 | + [kTCTypePersonalizedDiskImage] = { 998 | + .chipEnvironment = chipEnvironmentPersonalized, 999 | + .nonceDomain = nonceDomainPDI, 1000 | + .fourCC = 'ltrs', 1001 | + .firmwareFlags = NULL, 1002 | + .entitlementValue = "personalized.pdi" 1003 | + }, 1004 | + 1005 | + [kTCTypeDeveloperDiskImage] = { 1006 | + .chipEnvironment = chipEnvironmentCategorized, 1007 | + .nonceDomain = nonceDomainDDI, 1008 | + .fourCC = 'trdv', 1009 | + .firmwareFlags = NULL, 1010 | + .entitlementValue = "personalized.ddi" 1011 | + }, 1012 | + 1013 | + [kTCTypeLTRSWithDDINonce] = { 1014 | + .chipEnvironment = chipEnvironmentPersonalized, 1015 | + .nonceDomain = nonceDomainDDI, 1016 | + .fourCC = 'ltrs', 1017 | + .firmwareFlags = NULL, 1018 | + .entitlementValue = "personalized.ddi" 1019 | + }, 1020 | + 1021 | + [kTCTypeCryptex] = { 1022 | + .chipEnvironment = chipEnvironmentPersonalized, 1023 | + .nonceDomain = nonceDomainCryptex, 1024 | + .fourCC = 'ltrs', 1025 | + .firmwareFlags = NULL, 1026 | + .entitlementValue = "personalized.cryptex-research" 1027 | + }, 1028 | + 1029 | + [kTCTypeEphemeralCryptex] = { 1030 | + .chipEnvironment = chipEnvironmentEphemeralCryptex, 1031 | + .nonceDomain = nonceDomainEphemeralCryptex, 1032 | + .fourCC = 'ltrs', 1033 | + .firmwareFlags = NULL, 1034 | + .entitlementValue = "personalized.ephemeral-cryptex" 1035 | + }, 1036 | + 1037 | + [kTCTypeUpdateBrain] = { 1038 | + .chipEnvironment = chipEnvironmentGlobalFF00, 1039 | + .nonceDomain = NULL, 1040 | + .fourCC = 'ltrs', 1041 | + .firmwareFlags = NULL, 1042 | + .entitlementValue = "global.ota-update-brain" 1043 | + }, 1044 | + 1045 | + [kTCTypeInstallAssistant] = { 1046 | + .chipEnvironment = chipEnvironmentGlobalFF01, 1047 | + .nonceDomain = NULL, 1048 | + .fourCC = 'ltrs', 1049 | + .firmwareFlags = NULL, 1050 | + .entitlementValue = "global.install-assistant" 1051 | + }, 1052 | + 1053 | + [kTCTypeBootabilityBrain] = { 1054 | + .chipEnvironment = chipEnvironmentGlobalFF06, 1055 | + .nonceDomain = NULL, 1056 | + .fourCC = 'trbb', 1057 | + .firmwareFlags = NULL, 1058 | + .entitlementValue = "global.bootability-brain" 1059 | + }, 1060 | + 1061 | + [kTCTypeCryptex1BootOS] = { 1062 | + .chipEnvironment = chipEnvironmentCryptex1Boot, 1063 | + .nonceDomain = NULL, 1064 | + .fourCC = 'trcs', 1065 | + .firmwareFlags = firmwareFlagsSplat, 1066 | + .entitlementValue = "cryptex1.boot.os" 1067 | + }, 1068 | + 1069 | + [kTCTypeCryptex1BootApp] = { 1070 | + .chipEnvironment = chipEnvironmentCryptex1Boot, 1071 | + .nonceDomain = NULL, 1072 | + .fourCC = 'trca', 1073 | + .firmwareFlags = firmwareFlagsSplat, 1074 | + .entitlementValue = "cryptex1.boot.app" 1075 | + }, 1076 | + 1077 | + [kTCTypeCryptex1PreBootApp] = { 1078 | + .chipEnvironment = chipEnvironmentCryptex1PreBoot, 1079 | + .nonceDomain = NULL, 1080 | + .fourCC = 'trca', 1081 | + .firmwareFlags = firmwareFlagsSplat, 1082 | + .entitlementValue = "cryptex1.preboot.app" 1083 | + }, 1084 | + 1085 | + [kTCTypeGlobalDiskImage] = { 1086 | + .chipEnvironment = chipEnvironmentGlobalFF00, 1087 | + .nonceDomain = NULL, 1088 | + .fourCC = 'ltrs', 1089 | + .firmwareFlags = NULL, 1090 | + .entitlementValue = "global.pdi" 1091 | + }, 1092 | + 1093 | + [kTCTypeMobileAssetBrain] = { 1094 | + .chipEnvironment = chipEnvironmentCryptex1MobileAsset, 1095 | + .nonceDomain = NULL, 1096 | + .fourCC = 'trab', 1097 | + .firmwareFlags = NULL, 1098 | + .entitlementValue = "personalized.mobile-asset-brain" 1099 | + }, 1100 | + 1101 | + [kTCTypeSafariDownlevel] = { 1102 | + .chipEnvironment = chipEnvironmentSafariDownlevel, 1103 | + .nonceDomain = NULL, 1104 | + .fourCC = 'trca', 1105 | + .firmwareFlags = NULL, 1106 | + .entitlementValue = "cryptex1.safari-downlevel" 1107 | + }, 1108 | + 1109 | + [kTCTypeCryptex1PreBootOS] = { 1110 | + .chipEnvironment = chipEnvironmentCryptex1PreBoot, 1111 | + .nonceDomain = NULL, 1112 | + .fourCC = 'trcs', 1113 | + .firmwareFlags = firmwareFlagsSplat, 1114 | + .entitlementValue = "cryptex1.preboot.os" 1115 | + }, 1116 | + 1117 | + [kTCTypeSupplementalPersistent] = { 1118 | + .chipEnvironment = chipEnvironmentSupplemental, 1119 | + .nonceDomain = nonceDomainDDI, 1120 | + .fourCC = 'ltrs', 1121 | + .firmwareFlags = NULL, 1122 | + .entitlementValue = "personalized.supplemental-persistent" 1123 | + }, 1124 | + 1125 | + [kTCTypeSupplementalEphemeral] = { 1126 | + .chipEnvironment = chipEnvironmentSupplemental, 1127 | + .nonceDomain = nonceDomainPDI, 1128 | + .fourCC = 'ltrs', 1129 | + .firmwareFlags = NULL, 1130 | + .entitlementValue = "personalized.supplemental-ephemeral" 1131 | + }, 1132 | + 1133 | + [kTCTypeCryptex1Generic] = { 1134 | + .chipEnvironment = chipEnvironmentCryptex1Generic, 1135 | + .nonceDomain = NULL, 1136 | + .fourCC = 'gtcd', 1137 | + .firmwareFlags = NULL, 1138 | + .entitlementValue = "cryptex1.generic" 1139 | + }, 1140 | + 1141 | + [kTCTypeCryptex1GenericSupplemental] = { 1142 | + .chipEnvironment = chipEnvironmentCryptex1GenericSupplemental, 1143 | + .nonceDomain = NULL, 1144 | + .fourCC = 'gtcd', 1145 | + .firmwareFlags = NULL, 1146 | + .entitlementValue = "cryptex1.generic.supplemental" 1147 | + } 1148 | +}; 1149 | + 1150 | +#pragma GCC diagnostic pop 1151 | + 1152 | +__END_DECLS 1153 | +#endif /* libTrustCache_TypesConfig_h */ 1154 | -------------------------------------------------------------------------------- /patches/iobuffermemd_monterey.patch: -------------------------------------------------------------------------------- 1 | diff --git a/iokit/Kernel/IOBufferMemoryDescriptor.cpp b/iokit/Kernel/IOBufferMemoryDescriptor.cpp 2 | index f0d246a7..f1d35835 100644 3 | --- a/iokit/Kernel/IOBufferMemoryDescriptor.cpp 4 | +++ b/iokit/Kernel/IOBufferMemoryDescriptor.cpp 5 | @@ -332,7 +332,7 @@ IOBufferMemoryDescriptor::initWithPhysicalMask( 6 | KMA_GUARD_LAST | KMA_ZERO); 7 | 8 | if (((uint32_t) alignment) != alignment) { 9 | - return NULL; 10 | + return false; 11 | } 12 | if (kheap == KHEAP_DATA_BUFFERS) { 13 | kma_flags = (kma_flags_t) (kma_flags | KMA_DATA); 14 | -------------------------------------------------------------------------------- /patches/kas_info.patch: -------------------------------------------------------------------------------- 1 | diff --git a/bsd/sys/kas_info.h b/bsd/sys/kas_info.h 2 | index ae2d5f3b..4024f745 100644 3 | --- a/bsd/sys/kas_info.h 4 | +++ b/bsd/sys/kas_info.h 5 | @@ -44,7 +44,12 @@ __BEGIN_DECLS 6 | #define KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR (0) /* returns uint64_t */ 7 | #define KAS_INFO_KERNEL_SEGMENT_VMADDR_SELECTOR (1) 8 | 9 | -#define KAS_INFO_MAX_SELECTOR (2) 10 | +// CoreSymbolication`_createSymbolicatorWithMachKernelExcludingSearchPathsFlagsAndNotification 11 | +// expects kas_info to not return an error for these two segments; required for DTrace to work. 12 | +#define KAS_INFO_KERNEL_SPECIAL_SEGMENT_1 (2) 13 | +#define KAS_INFO_KERNEL_SPECIAL_SEGMENT_2 (3) 14 | + 15 | +#define KAS_INFO_MAX_SELECTOR (4) 16 | 17 | #ifndef KERNEL 18 | 19 | diff --git a/bsd/vm/vm_unix.c b/bsd/vm/vm_unix.c 20 | index 45b6ffe0..3e475918 100644 21 | --- a/bsd/vm/vm_unix.c 22 | +++ b/bsd/vm/vm_unix.c 23 | @@ -3732,6 +3732,9 @@ kas_info(struct proc *p, 24 | } 25 | } 26 | break; 27 | + case KAS_INFO_KERNEL_SPECIAL_SEGMENT_1: 28 | + case KAS_INFO_KERNEL_SPECIAL_SEGMENT_2: 29 | + break; 30 | default: 31 | return EINVAL; 32 | } 33 | -------------------------------------------------------------------------------- /patches/machine_routines.patch: -------------------------------------------------------------------------------- 1 | diff --git a/osfmk/arm64/machine_routines.c b/osfmk/arm64/machine_routines.c 2 | index 3ed62bd6..f1d0d190 100644 3 | --- a/osfmk/arm64/machine_routines.c 4 | +++ b/osfmk/arm64/machine_routines.c 5 | @@ -2097,7 +2097,7 @@ static inline uint64_t 6 | nonspeculative_timebase(void) 7 | { 8 | #if defined(HAS_ACNTVCT) 9 | - return __builtin_arm_rsr64("ACNTVCT_EL0"); 10 | + return __builtin_arm_rsr64("S3_4_c15_c10_6"); 11 | #elif __ARM_ARCH_8_6__ 12 | return __builtin_arm_rsr64("CNTVCTSS_EL0"); 13 | #else 14 | -------------------------------------------------------------------------------- /patches/skywalk_sonoma.patch: -------------------------------------------------------------------------------- 1 | diff --git a/bsd/net/skywalk_stubs.c b/bsd/net/skywalk_stubs.c 2 | index 611f39c6..beff6424 100644 3 | --- a/bsd/net/skywalk_stubs.c 4 | +++ b/bsd/net/skywalk_stubs.c 5 | @@ -135,6 +135,9 @@ STUB(kern_packet_get_transport_last_packet); 6 | STUB(kern_packet_get_transport_traffic_background) 7 | STUB(kern_packet_get_transport_traffic_realtime) 8 | STUB(kern_packet_set_compression_generation_count); 9 | +STUB(kern_packet_set_fpd_command); 10 | +STUB(kern_packet_set_fpd_context_id); 11 | +STUB(kern_packet_set_fpd_sequence_number); 12 | STUB(kern_packet_set_flow_uuid); 13 | STUB(kern_packet_set_inet_checksum); 14 | STUB(kern_packet_set_headroom); 15 | diff --git a/bsd/skywalk/packet/os_packet.h b/bsd/skywalk/packet/os_packet.h 16 | index 18b582ba..5d4a1500 100644 17 | --- a/bsd/skywalk/packet/os_packet.h 18 | +++ b/bsd/skywalk/packet/os_packet.h 19 | @@ -883,6 +883,13 @@ extern errno_t kern_pbufpool_alloc_buflet_nosleep(const kern_pbufpool_t, 20 | kern_buflet_t *); 21 | extern void kern_pbufpool_destroy(kern_pbufpool_t); 22 | extern kern_segment_idx_t kern_segment_get_index(const kern_segment_t); 23 | + 24 | +/* 25 | + * FPD. 26 | + */ 27 | +extern errno_t kern_packet_set_fpd_command(const kern_packet_t, uint8_t); 28 | +extern errno_t kern_packet_set_fpd_context_id(const kern_packet_t, uint16_t); 29 | +extern errno_t kern_packet_set_fpd_sequence_number(const kern_packet_t, uint32_t); 30 | __END_DECLS 31 | #endif /* KERNEL */ 32 | #endif /* PRIVATE */ 33 | diff --git a/bsd/skywalk/packet/packet_kern.c b/bsd/skywalk/packet/packet_kern.c 34 | index 1e822d15..08f4109a 100644 35 | --- a/bsd/skywalk/packet/packet_kern.c 36 | +++ b/bsd/skywalk/packet/packet_kern.c 37 | @@ -287,6 +287,36 @@ kern_packet_get_inet_checksum(const kern_packet_t ph, uint16_t *start, 38 | return __packet_get_inet_checksum(ph, start, val, tx); 39 | } 40 | 41 | +errno_t 42 | +kern_packet_set_fpd_command(const kern_packet_t ph, 43 | + uint8_t cmd) 44 | +{ 45 | + errno_t result; 46 | + 47 | + if (cmd > 7) 48 | + return 22; 49 | + result = 0; 50 | + PKT_ADDR(ph)->pkt_fpd_metadata |= ((cmd & 7) << 6) | 0x8000; 51 | + return result; 52 | +} 53 | + 54 | +errno_t 55 | +kern_packet_set_fpd_sequence_number(const kern_packet_t ph, 56 | + uint32_t seq_num) 57 | +{ 58 | + PKT_ADDR(ph)->pkt_fpd_seqnum = seq_num; 59 | + PKT_ADDR(ph)->pkt_fpd_metadata |= 0x8000; 60 | + return 0; 61 | +} 62 | + 63 | +errno_t 64 | +kern_packet_set_fpd_context_id(const kern_packet_t ph, 65 | + uint16_t ctx_id) 66 | +{ 67 | + PKT_ADDR(ph)->pkt_fpd_metadata |= ctx_id & 0x3F | 0x8000; 68 | + return 0; 69 | +} 70 | + 71 | void 72 | kern_packet_set_flow_uuid(const kern_packet_t ph, const uuid_t flow_uuid) 73 | { 74 | diff --git a/bsd/skywalk/packet/packet_var.h b/bsd/skywalk/packet/packet_var.h 75 | index 6c328f83..bf8371c1 100644 76 | --- a/bsd/skywalk/packet/packet_var.h 77 | +++ b/bsd/skywalk/packet/packet_var.h 78 | @@ -441,6 +441,8 @@ struct __kern_packet { 79 | 80 | void * pkt_priv; /* free to use for every layer */ 81 | 82 | + uint32_t pkt_fpd_seqnum; // @ 0xd0 83 | + uint16_t pkt_fpd_metadata; // @ 0xd4 84 | 85 | /* 86 | * Kernel specific. 87 | diff --git a/config/Private.exports b/config/Private.exports 88 | index 6977f083..eb4bbb4b 100644 89 | --- a/config/Private.exports 90 | +++ b/config/Private.exports 91 | @@ -634,6 +634,9 @@ _kern_packet_set_wake_flag 92 | _kern_packet_set_compression_generation_count 93 | _kern_packet_set_expire_time 94 | _kern_packet_set_expiry_action 95 | +_kern_packet_set_fpd_command 96 | +_kern_packet_set_fpd_context_id 97 | +_kern_packet_set_fpd_sequence_number 98 | _kern_packet_set_flow_uuid 99 | _kern_packet_set_group_start 100 | _kern_packet_set_group_end 101 | -------------------------------------------------------------------------------- /patches/skywalk_ventura.patch: -------------------------------------------------------------------------------- 1 | diff --git a/bsd/net/skywalk_stubs.c b/bsd/net/skywalk_stubs.c 2 | index ddfdd7486..152f83a1c 100644 3 | --- a/bsd/net/skywalk_stubs.c 4 | +++ b/bsd/net/skywalk_stubs.c 5 | @@ -135,6 +135,9 @@ STUB(kern_packet_get_transport_last_packet); 6 | STUB(kern_packet_get_transport_traffic_background) 7 | STUB(kern_packet_get_transport_traffic_realtime) 8 | STUB(kern_packet_set_compression_generation_count); 9 | +STUB(kern_packet_set_fpd_command); 10 | +STUB(kern_packet_set_fpd_context_id); 11 | +STUB(kern_packet_set_fpd_sequence_number); 12 | STUB(kern_packet_set_flow_uuid); 13 | STUB(kern_packet_set_inet_checksum); 14 | STUB(kern_packet_set_headroom); 15 | diff --git a/bsd/skywalk/packet/os_packet.h b/bsd/skywalk/packet/os_packet.h 16 | index 170382f0f..9ad34ed76 100644 17 | --- a/bsd/skywalk/packet/os_packet.h 18 | +++ b/bsd/skywalk/packet/os_packet.h 19 | @@ -875,6 +875,13 @@ extern void kern_pbufpool_free_buflet(const kern_pbufpool_t pp, 20 | kern_buflet_t pbuf); 21 | extern void kern_pbufpool_destroy(kern_pbufpool_t); 22 | extern kern_segment_idx_t kern_segment_get_index(const kern_segment_t); 23 | + 24 | +/* 25 | + * FPD. 26 | + */ 27 | +extern errno_t kern_packet_set_fpd_command(const kern_packet_t, uint8_t); 28 | +extern errno_t kern_packet_set_fpd_context_id(const kern_packet_t, uint16_t); 29 | +extern errno_t kern_packet_set_fpd_sequence_number(const kern_packet_t, uint32_t); 30 | __END_DECLS 31 | #endif /* KERNEL */ 32 | #endif /* PRIVATE */ 33 | diff --git a/bsd/skywalk/packet/packet_kern.c b/bsd/skywalk/packet/packet_kern.c 34 | index d52fddc46..10da9ce73 100644 35 | --- a/bsd/skywalk/packet/packet_kern.c 36 | +++ b/bsd/skywalk/packet/packet_kern.c 37 | @@ -287,6 +287,36 @@ kern_packet_get_inet_checksum(const kern_packet_t ph, uint16_t *start, 38 | return __packet_get_inet_checksum(ph, start, val, tx); 39 | } 40 | 41 | +errno_t 42 | +kern_packet_set_fpd_command(const kern_packet_t ph, 43 | + uint8_t cmd) 44 | +{ 45 | + errno_t result; 46 | + 47 | + if (cmd > 7) 48 | + return 22; 49 | + result = 0; 50 | + PKT_ADDR(ph)->pkt_fpd_metadata |= ((cmd & 7) << 6) | 0x8000; 51 | + return result; 52 | +} 53 | + 54 | +errno_t 55 | +kern_packet_set_fpd_sequence_number(const kern_packet_t ph, 56 | + uint32_t seq_num) 57 | +{ 58 | + PKT_ADDR(ph)->pkt_fpd_seqnum = seq_num; 59 | + PKT_ADDR(ph)->pkt_fpd_metadata |= 0x8000; 60 | + return 0; 61 | +} 62 | + 63 | +errno_t 64 | +kern_packet_set_fpd_context_id(const kern_packet_t ph, 65 | + uint16_t ctx_id) 66 | +{ 67 | + PKT_ADDR(ph)->pkt_fpd_metadata |= ctx_id & 0x3F | 0x8000; 68 | + return 0; 69 | +} 70 | + 71 | void 72 | kern_packet_set_flow_uuid(const kern_packet_t ph, const uuid_t flow_uuid) 73 | { 74 | diff --git a/bsd/skywalk/packet/packet_var.h b/bsd/skywalk/packet/packet_var.h 75 | index 001d2a1db..390f6365e 100644 76 | --- a/bsd/skywalk/packet/packet_var.h 77 | +++ b/bsd/skywalk/packet/packet_var.h 78 | @@ -474,7 +474,9 @@ struct __kern_packet { 79 | 80 | void * pkt_priv; /* free to use for every layer */ 81 | 82 | - 83 | + uint32_t pkt_fpd_seqnum; // @ 0xd0 84 | + uint16_t pkt_fpd_metadata; // @ 0xd4 85 | + 86 | /* 87 | * Kernel specific. 88 | * 89 | diff --git a/config/Private.exports b/config/Private.exports 90 | index 779bc8cb4..ce0e8ca60 100644 91 | --- a/config/Private.exports 92 | +++ b/config/Private.exports 93 | @@ -569,6 +569,9 @@ _kern_packet_set_wake_flag 94 | _kern_packet_set_compression_generation_count 95 | _kern_packet_set_expire_time 96 | _kern_packet_set_expiry_action 97 | +_kern_packet_set_fpd_command 98 | +_kern_packet_set_fpd_context_id 99 | +_kern_packet_set_fpd_sequence_number 100 | _kern_packet_set_flow_uuid 101 | _kern_packet_set_group_start 102 | _kern_packet_set_group_end 103 | -------------------------------------------------------------------------------- /patches/syntax_checker_sonoma.patch: -------------------------------------------------------------------------------- 1 | diff --git a/tools/lldbmacros/core/syntax_checker.py b/tools/lldbmacros/core/syntax_checker.py 2 | index 05aba3b4..2233be9d 100755 3 | --- a/tools/lldbmacros/core/syntax_checker.py 4 | +++ b/tools/lldbmacros/core/syntax_checker.py 5 | @@ -1,7 +1,6 @@ 6 | #!/usr/bin/env python3 7 | from __future__ import absolute_import, print_function 8 | 9 | - 10 | helpdoc = """ 11 | A simple utility that verifies the syntax for python scripts. 12 | The checks it does are : 13 | @@ -12,9 +11,6 @@ Usage: 14 | """ 15 | import sys 16 | import os 17 | -import re 18 | - 19 | -tabs_search_rex = re.compile("^\s*\t+",re.MULTILINE|re.DOTALL) 20 | 21 | def find_non_ascii(s): 22 | for c in s: 23 | @@ -34,20 +30,6 @@ if __name__ == "__main__": 24 | print("Note: %s is not a valid python file. Skipping." % fname) 25 | continue 26 | fh = open(fname) 27 | - strdata = fh.readlines() 28 | - lineno = 0 29 | - syntax_fail = False 30 | - for linedata in strdata: 31 | - lineno += 1 32 | - if len(tabs_search_rex.findall(linedata)) > 0 : 33 | - print("Error: Found a TAB character at %s:%d" % (fname, lineno), file=sys.stderr) 34 | - syntax_fail = True 35 | - if find_non_ascii(linedata): 36 | - print("Error: Found a non ascii character at %s:%d" % (fname, lineno), file=sys.stderr) 37 | - syntax_fail = True 38 | - if syntax_fail: 39 | - print("Error: Syntax check failed. Please fix the errors and try again.", file=sys.stderr) 40 | - sys.exit(1) 41 | #now check for error in compilation 42 | try: 43 | with open(fname, 'r') as file: 44 | -------------------------------------------------------------------------------- /patches/syntax_checker_ventura.patch: -------------------------------------------------------------------------------- 1 | diff --git a/tools/lldbmacros/core/syntax_checker.py b/tools/lldbmacros/core/syntax_checker.py 2 | index 3ebc2951..174ffefa 100755 3 | --- a/tools/lldbmacros/core/syntax_checker.py 4 | +++ b/tools/lldbmacros/core/syntax_checker.py 5 | @@ -12,9 +12,6 @@ Usage: 6 | """ 7 | import sys 8 | import os 9 | -import re 10 | - 11 | -tabs_search_rex = re.compile("^\s*\t+",re.MULTILINE|re.DOTALL) 12 | 13 | def find_non_ascii(s): 14 | for c in s: 15 | @@ -34,29 +31,6 @@ if __name__ == "__main__": 16 | print("Note: %s is not a valid python file. Skipping." % fname) 17 | continue 18 | fh = open(fname) 19 | - strdata = fh.readlines() 20 | - lineno = 0 21 | - syntax_fail = False 22 | - for linedata in strdata: 23 | - lineno += 1 24 | - if len(tabs_search_rex.findall(linedata)) > 0 : 25 | - print("Error: Found a TAB character at %s:%d" % (fname, lineno), file=sys.stderr) 26 | - syntax_fail = True 27 | - if find_non_ascii(linedata): 28 | - print("Error: Found a non ascii character at %s:%d" % (fname, lineno), file=sys.stderr) 29 | - syntax_fail = True 30 | - if syntax_fail: 31 | - print("Error: Syntax check failed. Please fix the errors and try again.", file=sys.stderr) 32 | - sys.exit(1) 33 | - #now check for error in compilation 34 | - try: 35 | - with open(fname, 'r') as file: 36 | - source = file.read() + '\n' 37 | - compile_result = compile(source, fname, 'exec') 38 | - except Exception as exc: 39 | - print(str(exc), file=sys.stderr) 40 | - print("Error: Compilation failed. Please fix the errors and try again.", file=sys.stderr) 41 | - sys.exit(1) 42 | print("Success: Checked %s. No syntax errors found." % fname) 43 | sys.exit(0) 44 | 45 | -------------------------------------------------------------------------------- /templates/codeql.pkr.hcl: -------------------------------------------------------------------------------- 1 | packer { 2 | required_plugins { 3 | tart = { 4 | version = ">= 1.14.0" 5 | source = "github.com/cirruslabs/tart" 6 | } 7 | } 8 | } 9 | 10 | variable "macos_version" { 11 | type = string 12 | } 13 | 14 | variable "macos_vm_name" { 15 | type = string 16 | } 17 | 18 | source "tart-cli" "tart" { 19 | vm_base_name = "ghcr.io/cirruslabs/macos-${var.macos_version}:latest" 20 | vm_name = "${var.macos_vm_name}" 21 | cpu_count = 4 22 | memory_gb = 8 23 | disk_size_gb = 90 24 | headless = true 25 | ssh_password = "admin" 26 | ssh_username = "admin" 27 | ssh_timeout = "120s" 28 | } 29 | 30 | build { 31 | sources = ["source.tart-cli.tart"] 32 | 33 | provisioner "shell" { 34 | inline = [ 35 | "source ~/.zprofile", 36 | "brew --version", 37 | "brew update", 38 | "brew upgrade", 39 | "brew install jq gum cmake ninja", 40 | ] 41 | } 42 | 43 | provisioner "shell" { 44 | inline = [ 45 | "source ~/.zprofile", 46 | "brew --version", 47 | "brew update", 48 | "brew upgrade", 49 | "brew install codeql", 50 | "codeql pack download codeql/cpp-queries", 51 | ] 52 | } 53 | 54 | // `ipsw` development tools 55 | provisioner "shell" { 56 | inline = [ 57 | "source ~/.zprofile", 58 | "brew --version", 59 | "brew update", 60 | "brew upgrade", 61 | "brew install go goreleaser zig unicorn libusb", 62 | "brew install blacktop/tap/ipsw", 63 | "go install golang.org/x/tools/...@latest", 64 | "go install github.com/spf13/cobra-cli@latest", 65 | "go get -d golang.org/x/tools/cmd/cover", 66 | "go get -d golang.org/x/tools/cmd/stringer", 67 | "go install github.com/caarlos0/svu@v1.4.1", 68 | ] 69 | } 70 | 71 | } 72 | --------------------------------------------------------------------------------