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:
1 parent
c30aadf9bb
commit
6f4ed67c38
9 files changed
+217
-40
No files matched your search
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user