Files
orca/config/scripts/desktop-distribution/macos/macos-executable-uuid.test.mjs
Jinwoo Hong fde1ae70da fix(mac): give Orca's main executable its own UUID so Local Network access works (#41676)
* fix(mac): give Orca's main executable its own Mach-O UUID

macOS Local Network privacy identifies an app by its main executable's
UUID. The packaged executable is stock Electron's, so it shares that UUID
with every other app on the same Electron version and macOS can apply
another app's Local Network decision to Orca. Rewrite LC_UUID in every
slice to a value derived from the app id, executable name and CPU type,
before signing.

* fix(mac): re-sign rewritten executables ad hoc, cover the terminal host, assert UUIDs at release

Rewriting LC_UUID breaks Electron's linker ad hoc signature, and arm64
kills unsigned code, so identity-less local builds (where app signing is
skipped) produced an Orca.app that died at launch. Re-sign the rewritten
executable ad hoc, outside the bundle so codesign does not treat it as
the bundle; real signing replaces it later.

The terminal host's executable is a stock Node binary whose UUID is
shared by every copy of that Node release, so give it its own stable
UUID the same way. Packaging and release verification now fail when a
shipped executable does not carry its expected UUID.

* fix(mac): scope the executable UUID rewrite to the main app

The terminal host gets a separate design; leave it unchanged here.
2026-11-13 04:53:48 -05:00

100 lines
3.7 KiB
JavaScript

import { execFileSync } from 'node:child_process'
import { copyFileSync, mkdtempSync, rmSync } from 'node:fs'
import { createRequire } from 'node:module'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { describe, expect, it } from 'vitest'
const require = createRequire(import.meta.url)
const {
assertMacExecutableUuid,
giveMacExecutableUniqueUuid,
rewriteMachOUuids
} = require('./macos-executable-uuid.cjs')
const ARM64 = 0x0100000c
const X86_64 = 0x01000007
const STOCK_UUID = Buffer.from('4C4C44C055553144A1E0C291B44FDBE3', 'hex')
function thinSlice(cpuType) {
const header = Buffer.alloc(32)
header.writeUInt32LE(0xfeedfacf, 0)
header.writeUInt32LE(cpuType, 4)
header.writeUInt32LE(2, 12)
header.writeUInt32LE(2, 16)
header.writeUInt32LE(16 + 24, 20)
const other = Buffer.alloc(16, 0xaa)
other.writeUInt32LE(0x19, 0)
other.writeUInt32LE(16, 4)
const uuid = Buffer.alloc(24)
uuid.writeUInt32LE(0x1b, 0)
uuid.writeUInt32LE(24, 4)
STOCK_UUID.copy(uuid, 8)
return Buffer.concat([header, other, uuid, Buffer.alloc(8, 0xbb)])
}
function fatBinary(slices) {
const table = Buffer.alloc(8 + slices.length * 20)
table.writeUInt32BE(0xcafebabe, 0)
table.writeUInt32BE(slices.length, 4)
const parts = [table]
let offset = 4096
slices.forEach((slice, i) => {
table.writeUInt32BE(slice.readUInt32LE(4), 8 + i * 20)
table.writeUInt32BE(offset, 8 + i * 20 + 8)
table.writeUInt32BE(slice.length, 8 + i * 20 + 12)
const end = parts.reduce((n, p) => n + p.length, 0)
parts.push(Buffer.alloc(offset - end), slice)
offset += 4096
})
return Buffer.concat(parts)
}
const uuidAt = (buffer, offset) => buffer.subarray(offset, offset + 16).toString('hex')
describe('rewriteMachOUuids', () => {
it('replaces the stock UUID of a thin executable and nothing else', () => {
const original = thinSlice(ARM64)
const rewritten = Buffer.from(original)
rewriteMachOUuids(rewritten, 'com.stablyai.orca', 'Orca')
expect(uuidAt(rewritten, 56)).toBe('e64304103b228bd69677b18884034a30')
expect(Buffer.concat([rewritten.subarray(0, 56), rewritten.subarray(72)])).toEqual(
Buffer.concat([original.subarray(0, 56), original.subarray(72)])
)
})
it('gives every slice of a universal executable its own stable UUID', () => {
const binary = fatBinary([thinSlice(X86_64), thinSlice(ARM64)])
rewriteMachOUuids(binary, 'com.stablyai.orca', 'Orca')
rewriteMachOUuids(binary, 'com.stablyai.orca', 'Orca')
expect(uuidAt(binary, 4096 + 56)).toBe('016ee6813dc381c7a6da12dc23b89dd9')
expect(uuidAt(binary, 8192 + 56)).toBe('e64304103b228bd69677b18884034a30')
})
it('refuses an executable without LC_UUID', () => {
const slice = thinSlice(ARM64)
slice.writeUInt32LE(0x1a, 48)
expect(() => rewriteMachOUuids(slice, 'com.stablyai.orca', 'Orca')).toThrow('has no LC_UUID')
})
})
describe.runIf(process.platform === 'darwin')('giveMacExecutableUniqueUuid', () => {
it('leaves a signed, runnable universal executable that passes the release check', () => {
const dir = mkdtempSync(join(tmpdir(), 'orca-exe-uuid-'))
try {
const executable = join(dir, 'Orca')
// A real platform-signed fat binary: rewriting it without re-signing gets it killed at exec.
copyFileSync('/usr/bin/true', executable)
expect(() => assertMacExecutableUuid(executable, 'com.stablyai.orca')).toThrow(
'expected 016EE681-3DC3-81C7-A6DA-12DC23B89DD9'
)
giveMacExecutableUniqueUuid(executable, 'com.stablyai.orca')
execFileSync(executable)
execFileSync('codesign', ['--verify', '--strict', executable])
assertMacExecutableUuid(executable, 'com.stablyai.orca')
} finally {
rmSync(dir, { recursive: true, force: true })
}
})
})