Cider Isn't Darwin Emulation, Really

fix(cider): the caller owns an xpc pipe reply, and MoneyMoney opens with launchd (#160) master

ONE RELEASE WAS THE WHOLE THING. +[deserializer process:] returns an AUTORELEASED dictionary, and the three pipe entry points that hand a dictionary out through an out-parameter (xpc_pipe_routine, xpc_pipe_receive, xpc_pipe_try_receive) passed that reference straight to the caller. Every caller of those owns what it is handed and releases it, and libinfo does exactly that around every membership lookup. So the reply was released twice, once by the caller and once when the pool drained. WHAT IT COST: trustd answered exactly one trust evaluation and then died draining the message handler's pool, CRASHTRACE signal=11 addr=0x20 in objc_release, on an object that was already gone. StaticCode.cpp evaluates trust at most twice, so the application's second evaluation had nothing to answer it and MoneyMoney sat on Starting MoneyMoney forever. HOW IT WAS FOUND, with the instrument built for it last rung. The drain trace names the dying object but not its origin; CIDER_TRACE_POOL=sites names every autorelease with the caller resolved through dladdr. The pool is LIFO, so the object that crashes the drain is the one autoreleased just before the last one printed: CIDER_POOL autorelease 0x7ef840206450 isa=0x7ef851221620 from -[OS_xpc_pipe sendMessage:withSynchronousReply:flags:] CIDER_POOL releasing 0x7ef8402062b0 ... __NSCFString <- last line before the crash and that isa resolves to OS_xpc_dictionary by sliding libxpc's own class table against the OS_xpc_serializer isa the same log prints. That is the reply. AFTER, all measured in the same driver: * zero trustd crashes in five runs, where it used to die in about three of five * trustd serves six trust evaluations instead of one * the static validation runs to completion: staticValidateCore back, resource scan finished with collected status=0, validateResources back * MoneyMoney opens its main window with launchd running, and the File menu opens on a click with its items, separators and key equivalents. Looked at. * nine of nine test suites still green, and Swift Publisher unchanged It also closes two older guesses. trustd does not go deaf after its first message, and no change to how launchd learns that a MachService job exited was needed for this: the daemon was being killed by a use-after-free of our own making.


Author Niclas Overby Date Commit f35feaec Parent cc288780 Change ID urtpxwup
+114
2 changed files