1 /* 2 * Copyright (c) 2022 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 #ifndef _KERN_EXT_PANICLOG_H_ 30 #define _KERN_EXT_PANICLOG_H_ 31 32 #include <sys/queue.h> 33 #include <uuid/uuid.h> 34 #include <os/base.h> 35 36 #define EXT_PANICLOG_ENABLE 1 37 38 #define EXT_PANICLOG_VERSION 2 39 40 #define MAX_DATA_ID_SIZE 32 41 42 #define MAX_EXT_PANICLOG_SIZE 32 * 1024 43 44 #define MAX_EXT_PANICLOG_LOGS 100 45 46 /* 47 * From the panic log metrics, we estimate that the paniclog takes up 48 * ~15K bytes and other log takes ~1K bytes. This 64K bytes ensures that 49 * we have enough space for other log and nested panics 50 */ 51 #define OTHER_LOG_REQUIRED_SIZE (64 * 1024) 52 53 #define PANIC_WITH_DATA_UUID "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 54 #define PANIC_WITH_DATA_MAX_LEN 2048 55 #define PANIC_WITH_DATA_DATA_ID "Panic with Data Buffer" 56 57 #define EXTPANICLOG_ENTITLEMENT "com.apple.private.allow-ext_paniclog" 58 59 /* 60 * These flags are set internally and are passed along with each handle in 61 * the extensible paniclog to be processed by DumpPanic. 62 */ 63 OS_CLOSED_OPTIONS(ext_paniclog_flags, uint32_t, 64 EXT_PANICLOG_FLAGS_NONE = 0x0, 65 EXT_PANICLOG_FLAGS_ADD_SEPARATE_KEY = 0x1); 66 67 OS_CLOSED_OPTIONS(ext_paniclog_create_options, uint32_t, 68 EXT_PANICLOG_OPTIONS_NONE = 0x0, 69 EXT_PANICLOG_OPTIONS_WITH_BUFFER = 0x1, 70 /* Adds the 'data ID' as a key and handle data as its value directly 71 * in the paniclog instead of within the 'ExtensiblePaniclog' field 72 */ 73 EXT_PANICLOG_OPTIONS_ADD_SEPARATE_KEY = 0x2); 74 75 #if KERNEL_PRIVATE 76 77 enum ext_paniclog_test_options { 78 EXT_PANICLOG_TEST_HANDLE_CREATE = 1, 79 EXT_PANICLOG_TEST_SET_ACTIVE_INACTIVE, 80 EXT_PANICLOG_TEST_INSERT_DATA, 81 EXT_PANICLOG_TEST_WRITE_PANIC_DATA, 82 EXT_PANICLOG_TEST_MULTIPLE_HANDLES, 83 EXT_PANICLOG_TEST_MULTIPLE_HANDLES_PANIC, 84 EXT_PANICLOG_TEST_INSERT_DUMMY_HANDLES, 85 EXT_PANICLOG_TEST_INSERT_STRUCT_HANDLES, 86 EXT_PANICLOG_TEST_INSERT_DUMMY_HANDLES_AS_SEPARATE_FIELDS, 87 EXT_PANICLOG_TEST_END, 88 }; 89 90 typedef struct ext_paniclog_handle { 91 LIST_ENTRY(ext_paniclog_handle) handles; 92 uuid_t uuid; 93 char data_id[MAX_DATA_ID_SIZE]; 94 void * XNU_PTRAUTH_SIGNED_PTR("ext_paniclog_handle.buf_addr") buf_addr; 95 uint32_t max_len; 96 uint32_t used_len; 97 ext_paniclog_create_options_t options; 98 ext_paniclog_flags_t flags; 99 uint8_t active; 100 } ext_paniclog_handle_t; 101 102 typedef struct ext_paniclog_header { 103 uint32_t len; 104 uuid_t uuid; 105 ext_paniclog_flags_t flags; 106 } ext_paniclog_header_t; 107 108 void ext_paniclog_init(void); 109 int ext_paniclog_handle_set_active(ext_paniclog_handle_t *handle); 110 int ext_paniclog_handle_set_inactive(ext_paniclog_handle_t *handle); 111 ext_paniclog_handle_t *ext_paniclog_handle_alloc_with_uuid(uuid_t uuid, const char *data_id, uint32_t max_len, ext_paniclog_create_options_t options); 112 ext_paniclog_handle_t *ext_paniclog_handle_alloc_with_buffer(uuid_t uuid, const char *data_id, uint32_t max_len, void * buff, ext_paniclog_create_options_t options); 113 void ext_paniclog_handle_free(ext_paniclog_handle_t *handle); 114 int ext_paniclog_insert_data(ext_paniclog_handle_t *handle, void *addr, uint32_t len); 115 int ext_paniclog_append_data(ext_paniclog_handle_t *handle, void *addr, uint32_t len); 116 void *ext_paniclog_get_buffer(ext_paniclog_handle_t *handle); 117 uint32_t ext_paniclog_write_panicdata(void); 118 void *ext_paniclog_claim_buffer(ext_paniclog_handle_t *handle); 119 int ext_paniclog_yield_buffer(ext_paniclog_handle_t *handle, uint32_t used_len); 120 int ext_paniclog_set_used_len(ext_paniclog_handle_t *handle, uint32_t used_len); 121 bool is_debug_ptr_in_ext_paniclog(void); 122 123 /* 124 * This function is used to panic and add a buffer data to the extensible paniclog. 125 * uuid here is used to decode the data. 126 */ 127 __abortlike __printflike(5, 6) 128 void panic_with_data(uuid_t uuid, void *addr, uint32_t len, uint64_t debugger_options_mask, const char *format, ...); 129 int ext_paniclog_test_hook(uint32_t option); 130 void ext_paniclog_panic_with_data(uuid_t uuid, void *addr, uint32_t len); 131 #endif // KERNEL_PRIVATE 132 133 #endif // _KERN_EXT_PANICLOG_H_ 134