112507 reachability closed: notification registration refused (-300)

- New kern.ipc.lifecycle module: dead-name registration, dead-name send,
  notification receive, name reuse — single-threaded, safe on device
- Device receipt (iPhone19,7, iOS 27.0.1, ad-hoc signed): request DEAD_NAME
  returns -300 (MIG_TYPE_ERROR); send -> MACH_SEND_INVALID_DEST; receive
  times out; 0/12,288 registrations armed in kern.ipc
- macOS 27 sweep: 13 notification-type/right combinations, all -300
- kern.ipc now counts armed registrations and retracts the old 'survived'
  verdict when armed == 0; the request table is never armed
- docs/KERNEL-RW-ASSESSMENT.md: 112507 marked closed for this app
- app 2.2 build 5; 57 modules
This commit is contained in:
JBJF committed 2026-10-31 15:59:20 +08:00
1 parent c30aadf9bb
commit 6f4ed67c38
9 files changed
+217 -40

No files matched your search

+24 -11
View File
@@ -17,7 +17,7 @@
// ── shared stats (mutex-guarded, mirror of KernelIPC.Stats) ──
typedef struct {
long operations, allocations, notifications, sends, deallocations;
long operations, allocations, notifications, sends, deallocations, armed;
int budget_exhausted;
long notifications_refused;
long budget;
@@ -50,10 +50,10 @@ static void record(kern_return_t kr) {
//
// Resource discipline: mod_refs with a negative delta against a zero send-ref count
// does not return an error on this platform — it SIGKILLs the process. Check first.
typedef struct { long alloc, notify, send, dealloc; } ring_result;
typedef struct { long alloc, notify, send, dealloc, armed; } ring_result;
static ring_result ring(mach_port_t task, int depth, int *budget, long *refused) {
ring_result r = {0, 0, 0, 0};
ring_result r = {0, 0, 0, 0, 0};
mach_port_name_t ports[512];
int nports = 0;
if (depth > 512) depth = 512;
@@ -79,9 +79,11 @@ static ring_result ring(mach_port_t task, int depth, int *budget, long *refused)
kern_return_t kr1 = mach_port_request_notification(
task, p, MACH_NOTIFY_SEND_POSSIBLE, 1, p,
(mach_msg_type_name_t)MACH_MSG_TYPE_MAKE_SEND, &prev);
if (kr1 != KERN_SUCCESS) {
if (kr1 == KERN_SUCCESS) {
r.armed++;
} else {
record(kr1);
if (kr1 == KERN_INVALID_CAPABILITY) (*refused)++;
(*refused)++;
}
if (prev != 0) mach_port_mod_refs(task, prev, MACH_PORT_RIGHT_SEND, -1);
r.notify++;
@@ -90,9 +92,11 @@ static ring_result ring(mach_port_t task, int depth, int *budget, long *refused)
kern_return_t kr2 = mach_port_request_notification(
task, p, MACH_NOTIFY_DEAD_NAME, 0, p,
(mach_msg_type_name_t)MACH_MSG_TYPE_MAKE_SEND, &prev2);
if (kr2 != KERN_SUCCESS) {
if (kr2 == KERN_SUCCESS) {
r.armed++;
} else {
record(kr2);
if (kr2 == KERN_INVALID_CAPABILITY) (*refused)++;
(*refused)++;
}
if (prev2 != 0) mach_port_mod_refs(task, prev2, MACH_PORT_RIGHT_SEND, -1);
r.notify++;
@@ -159,7 +163,7 @@ static int g_depth = 48;
static void *worker(void *arg) {
(void)arg;
long local_alloc = 0, local_notify = 0, local_send = 0, local_dealloc = 0, local_ops = 0;
long local_alloc = 0, local_notify = 0, local_send = 0, local_dealloc = 0, local_ops = 0, local_armed = 0;
while (!past_deadline()) {
pthread_mutex_lock(&S.lock);
@@ -184,6 +188,7 @@ static void *worker(void *arg) {
local_notify += res.notify;
local_send += res.send;
local_dealloc += res.dealloc;
local_armed += res.armed;
local_ops += 4;
pthread_mutex_lock(&S.lock);
@@ -197,6 +202,7 @@ static void *worker(void *arg) {
S.notifications += local_notify;
S.sends += local_send;
S.deallocations += local_dealloc;
S.armed += local_armed;
pthread_mutex_unlock(&S.lock);
return NULL;
}
@@ -246,8 +252,8 @@ int main(int argc, char **argv) {
for (int i = 0; i < workers; i++) pthread_create(&threads[i], NULL, worker, NULL);
for (int i = 0; i < workers; i++) pthread_join(threads[i], NULL);
printf("ops=%ld alloc=%ld notify=%ld send=%ld dealloc=%ld\n",
S.operations, S.allocations, S.notifications, S.sends, S.deallocations);
printf("ops=%ld alloc=%ld notify=%ld send=%ld dealloc=%ld armed=%ld\n",
S.operations, S.allocations, S.notifications, S.sends, S.deallocations, S.armed);
if (S.budget_exhausted) printf("(budget reached, converged early — by design, not a failure)\n");
if (S.notifications_refused > 0) {
printf("notifications refused %ld times — this platform does not allow notification\n"
@@ -260,7 +266,14 @@ int main(int argc, char **argv) {
printf(" %s (%d) x %ld\n", S.err_names[i], S.err_codes[i], S.err_counts[i]);
}
}
printf("CVE-2026-112507 · survived the interleaving, no request-table fault surfaced\n");
if (S.armed == 0 && S.notifications > 0) {
printf("notification registration never succeeded (-300, MIG type error).\n");
printf("the request-table path was never armed: this run is not a 112507 test.\n");
printf("CVE-2026-112507 · NOT REACHED from this process\n");
} else {
printf("CVE-2026-112507 · %ld registrations armed, survived the interleaving, "
"no request-table fault surfaced\n", S.armed);
}
pthread_mutex_destroy(&S.lock);
return 0;
}