ptrauth_data_tests_sysctl.c [plain text]
#if DEVELOPMENT || DEBUG
#if __has_feature(ptrauth_calls)
#include <sys/errno.h>
#include <sys/sysctl.h>
#include <sys/ubc.h>
#include <kern/kalloc.h>
#include <libkern/libkern.h>
#include <pexpert/pexpert.h>
#include <mach/task.h>
#include <kern/task.h>
#include <sys/ubc_internal.h>
extern kern_return_t ptrauth_data_tests(void);
#define VALIDATE_PTR(decl, ptr, key, discr) { \
decl raw = *(decl *)&(ptr); \
decl cmp = ptrauth_sign_unauthenticated(ptr, key, \
ptrauth_blend_discriminator(&ptr, ptrauth_string_discriminator(discr))); \
if (cmp != raw) { \
printf("kern.run_pac_test: %s (%s) (discr=%s) is not signed as expected (%p vs %p)\n", #decl, #ptr, #discr, raw, cmp); \
kr = EINVAL; \
} \
}
#define ALLOC_VALIDATE_DATA_PTR(structure, decl, member, discr) { \
structure *tmp = kheap_alloc(KHEAP_TEMP, sizeof(structure), Z_WAITOK | Z_ZERO); \
if (!tmp) return ENOMEM; \
tmp->member = (void*)0xffffffff41414141; \
VALIDATE_DATA_PTR(decl, tmp->member, discr) \
kheap_free(KHEAP_TEMP, tmp, sizeof(structure)); \
}
#define VALIDATE_DATA_PTR(decl, ptr, discr) VALIDATE_PTR(decl, ptr, ptrauth_key_process_independent_data, discr)
static int
sysctl_run_ptrauth_data_tests SYSCTL_HANDLER_ARGS
{
#pragma unused(arg1, arg2, oidp)
unsigned int dummy;
int error, changed, kr;
error = sysctl_io_number(req, 0, sizeof(dummy), &dummy, &changed);
if (error || !changed) {
return error;
}
ALLOC_VALIDATE_DATA_PTR(struct proc, void *, task, "proc.task");
ALLOC_VALIDATE_DATA_PTR(struct proc, struct proc *, p_pptr, "proc.p_pptr");
ALLOC_VALIDATE_DATA_PTR(struct proc, struct vnode *, p_textvp, "proc.p_textvp");
ALLOC_VALIDATE_DATA_PTR(struct proc, struct pgrp *, p_pgrp, "proc.p_pgrp");
ALLOC_VALIDATE_DATA_PTR(struct cs_blob, struct cs_blob *, csb_next, "cs_blob.csb_next");
ALLOC_VALIDATE_DATA_PTR(struct cs_blob, const CS_CodeDirectory *, csb_cd, "cs_blob.csb_cd");
ALLOC_VALIDATE_DATA_PTR(struct cs_blob, const char *, csb_teamid, "cs_blob.csb_teamid");
ALLOC_VALIDATE_DATA_PTR(struct cs_blob, const CS_GenericBlob *, csb_entitlements_blob, "cs_blob.csb_entitlements_blob");
ALLOC_VALIDATE_DATA_PTR(struct cs_blob, void *, csb_entitlements, "cs_blob.csb_entitlements");
kr = ptrauth_data_tests();
if (error == 0) {
error = mach_to_bsd_errno(kr);
}
return kr;
}
SYSCTL_PROC(_kern, OID_AUTO, run_ptrauth_data_tests,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED | CTLFLAG_MASKED,
0, 0, sysctl_run_ptrauth_data_tests, "I", "");
#endif
#endif