X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8a3053a07cee346dca737a5670e546fd26a7c9d6..143464d58d2bd6378e74eec636961ceb0d32fb91:/osfmk/kern/telemetry.c?ds=sidebyside diff --git a/osfmk/kern/telemetry.c b/osfmk/kern/telemetry.c index 724f8a2af..15b025418 100644 --- a/osfmk/kern/telemetry.c +++ b/osfmk/kern/telemetry.c @@ -73,6 +73,7 @@ void telemetry_take_sample(thread_t thread, uint8_t microsnapshot_flags); #define TELEMETRY_MAX_BUFFER_SIZE (64*1024) #define TELEMETRY_DEFAULT_NOTIFY_LEEWAY (4*1024) // Userland gets 4k of leeway to collect data after notification +#define TELEMETRY_MAX_UUID_COUNT (128) // Max of 128 non-shared-cache UUIDs to log for symbolication uint32_t telemetry_sample_rate = 0; volatile boolean_t telemetry_needs_record = FALSE; @@ -421,6 +422,14 @@ void telemetry_take_sample(thread_t thread, uint8_t microsnapshot_flags) uuid_info_count = 0; } + /* + * Don't copy in an unbounded amount of memory. The main binary and interesting + * non-shared-cache libraries should be in the first few images. + */ + if (uuid_info_count > TELEMETRY_MAX_UUID_COUNT) { + uuid_info_count = TELEMETRY_MAX_UUID_COUNT; + } + uint32_t uuid_info_size = (uint32_t)(task_has_64BitAddr(thread->task) ? sizeof(struct user64_dyld_uuid_info) : sizeof(struct user32_dyld_uuid_info)); uint32_t uuid_info_array_size = uuid_info_count * uuid_info_size; char *uuid_info_array = NULL; @@ -483,6 +492,10 @@ copytobuffer: */ telemetry_buffer_end_point = current_record_start; telemetry_buffer_current_position = 0; + if (current_record_start == 0) { + /* This sample is too large to fit in the buffer even when we started at 0, so skip it */ + goto cancel_sample; + } goto copytobuffer; } @@ -499,6 +512,10 @@ copytobuffer: if ((telemetry_buffer_size - telemetry_buffer_current_position) < sizeof(struct task_snapshot)) { telemetry_buffer_end_point = current_record_start; telemetry_buffer_current_position = 0; + if (current_record_start == 0) { + /* This sample is too large to fit in the buffer even when we started at 0, so skip it */ + goto cancel_sample; + } goto copytobuffer; } @@ -567,6 +584,10 @@ copytobuffer: if ((telemetry_buffer_size - telemetry_buffer_current_position) < uuid_info_array_size) { telemetry_buffer_end_point = current_record_start; telemetry_buffer_current_position = 0; + if (current_record_start == 0) { + /* This sample is too large to fit in the buffer even when we started at 0, so skip it */ + goto cancel_sample; + } goto copytobuffer; } @@ -588,6 +609,10 @@ copytobuffer: /* wrap and overwrite */ telemetry_buffer_end_point = current_record_start; telemetry_buffer_current_position = 0; + if (current_record_start == 0) { + /* This sample is too large to fit in the buffer even when we started at 0, so skip it */ + goto cancel_sample; + } goto copytobuffer; } @@ -627,6 +652,10 @@ copytobuffer: /* wrap and overwrite */ telemetry_buffer_end_point = current_record_start; telemetry_buffer_current_position = 0; + if (current_record_start == 0) { + /* This sample is too large to fit in the buffer even when we started at 0, so skip it */ + goto cancel_sample; + } goto copytobuffer; } @@ -651,6 +680,10 @@ copytobuffer: if ((telemetry_buffer_size - telemetry_buffer_current_position)/framesize < btcount) { telemetry_buffer_end_point = current_record_start; telemetry_buffer_current_position = 0; + if (current_record_start == 0) { + /* This sample is too large to fit in the buffer even when we started at 0, so skip it */ + goto cancel_sample; + } goto copytobuffer; } @@ -679,6 +712,8 @@ copytobuffer: notify = TRUE; } +cancel_sample: + TELEMETRY_UNLOCK(); KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_STACKSHOT, MICROSTACKSHOT_RECORD) | DBG_FUNC_END, notify, telemetry_bytes_since_last_mark, telemetry_buffer_current_position, telemetry_buffer_end_point, 0);