From 00bf83c00bdd789601d0af3bad04d92d92951111 Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 19 Apr 2021 17:12:20 +0000 Subject: [PATCH] system_cmds-880.100.5.tar.gz --- lsmp.tproj/common.h | 15 +- lsmp.tproj/entitlements.plist | 4 +- lsmp.tproj/lsmp.c | 18 +- lsmp.tproj/port_details.c | 30 +- lsmp.tproj/task_details.c | 111 ++-- nvram.tproj/entitlements.plist | 8 + nvram.tproj/nvram.c | 585 +++++++++--------- system_cmds.xcodeproj/project.pbxproj | 4 + .../taskpolicy-entitlements.plist | 2 +- taskpolicy.tproj/taskpolicy.c | 5 +- vm_purgeable_stat.tproj/entitlements.plist | 2 +- vm_purgeable_stat.tproj/vm_purgeable_stat.c | 7 +- zprint.tproj/zprint.c | 2 + 13 files changed, 414 insertions(+), 379 deletions(-) create mode 100644 nvram.tproj/entitlements.plist diff --git a/lsmp.tproj/common.h b/lsmp.tproj/common.h index 9a47012..a059eb5 100644 --- a/lsmp.tproj/common.h +++ b/lsmp.tproj/common.h @@ -25,6 +25,7 @@ #define system_cmds_common_h #include +#include #include "json.h" #define PROC_NAME_LEN 100 @@ -46,7 +47,7 @@ extern struct prog_configs lsmp_config; /* exception port information */ struct exc_port_info { mach_msg_type_number_t count; - mach_port_t ports[EXC_TYPES_COUNT]; + ipc_info_port_t ports_info[EXC_TYPES_COUNT]; exception_mask_t masks[EXC_TYPES_COUNT]; exception_behavior_t behaviors[EXC_TYPES_COUNT]; thread_state_flavor_t flavors[EXC_TYPES_COUNT]; @@ -74,7 +75,7 @@ struct k2n_table_node *k2n_table_lookup(struct k2n_table_node **table, natural_t /* private structure to wrap up per-task info */ typedef struct my_per_task_info { - task_t task; + task_read_t task; pid_t pid; vm_address_t task_kobject; ipc_info_space_t info; @@ -181,12 +182,12 @@ char *copy_voucher_detail(mach_port_t task, mach_port_name_t voucher, JSON_t jso /* mach port related functions */ const char * kobject_name(natural_t kotype); -void get_receive_port_context(task_t taskp, mach_port_name_t portname, mach_port_context_t *context); -int get_recieve_port_status(task_t taskp, mach_port_name_t portname, mach_port_info_ext_t *info); +void get_receive_port_context(task_read_t taskp, mach_port_name_t portname, mach_port_context_t *context); +int get_recieve_port_status(task_read_t taskp, mach_port_name_t portname, mach_port_info_ext_t *info); void show_task_mach_ports(my_per_task_info_t *taskinfo, uint32_t taskCount, my_per_task_info_t *allTaskInfos, JSON_t json); /* task and thread related helper functions */ -kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_task); +kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_read_t target_task); my_per_task_info_t * allocate_taskinfo_memory(uint32_t taskCount); void deallocate_taskinfo_memory(my_per_task_info_t *data); kern_return_t print_task_exception_info(my_per_task_info_t *taskinfo, JSON_t json); @@ -195,8 +196,8 @@ my_per_task_info_t * get_taskinfo_by_kobject(natural_t kobj); void get_exc_behavior_string(exception_behavior_t b, char *out_string, size_t len); void get_exc_mask_string(exception_mask_t m, char *out_string, size_t len); -kern_return_t get_taskinfo_of_receiver_by_send_right(ipc_info_name_t *sendright, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info); -kern_return_t get_ipc_info_from_lsmp_spaceinfo(mach_port_t port_name, ipc_info_name_t *out_sendright); +kern_return_t get_taskinfo_of_receiver_by_send_right(ipc_info_name_t sendright, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info); +kern_return_t get_taskinfo_of_receiver_by_send_right_info(ipc_info_port_t sendright_info, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info); /* basic util functions */ uint32_t print_hex_data(char *outstr, uint32_t maxlen, char *prefix, char *desc, void *addr, int len); diff --git a/lsmp.tproj/entitlements.plist b/lsmp.tproj/entitlements.plist index b7b4e6c..cdf0e9e 100644 --- a/lsmp.tproj/entitlements.plist +++ b/lsmp.tproj/entitlements.plist @@ -2,9 +2,7 @@ - task_for_pid-allow - - com.apple.system-task-ports + com.apple.system-task-ports.read diff --git a/lsmp.tproj/lsmp.c b/lsmp.tproj/lsmp.c index 71a7c68..114c5b6 100644 --- a/lsmp.tproj/lsmp.c +++ b/lsmp.tproj/lsmp.c @@ -19,6 +19,7 @@ * * @APPLE_LICENSE_HEADER_END@ */ +#include #include #include #include @@ -32,7 +33,7 @@ #include "json.h" #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) -#define TASK_FOR_PID_USAGE_MESG "\nPlease check your boot-args to ensure you have access to task_for_pid()." +#define TASK_FOR_PID_USAGE_MESG "\nPlease check your boot-args to ensure you have access to task_read_for_pid()." #else #define TASK_FOR_PID_USAGE_MESG "" #endif @@ -72,7 +73,7 @@ static void print_task_info(my_per_task_info_t *taskinfo, mach_msg_type_number_t int main(int argc, char *argv[]) { kern_return_t ret; - task_t aTask; + task_read_t aTask; my_per_task_info_t *taskinfo = NULL; task_array_t tasks; char *progname = "lsmp"; @@ -153,10 +154,10 @@ int main(int argc, char *argv[]) { mach_port_deallocate(mach_task_self(), psets[0]); vm_deallocate(mach_task_self(), (vm_address_t)psets, (vm_size_t)psetCount * sizeof(mach_port_t)); - /* convert the processor-set-priv to a list of tasks for the processor set */ - ret = processor_set_tasks(pset_priv, &tasks, &taskCount); + /* convert the processor-set-priv to a list of task read ports for the processor set */ + ret = processor_set_tasks_with_flavor(pset_priv, TASK_FLAVOR_READ, &tasks, &taskCount); if (ret != KERN_SUCCESS) { - fprintf(stderr, "processor_set_tasks() failed: %s\n", mach_error_string(ret)); + fprintf(stderr, "processor_set_tasks_with_flavor() failed: %s\n", mach_error_string(ret)); exit(1); } mach_port_deallocate(mach_task_self(), pset_priv); @@ -164,7 +165,7 @@ int main(int argc, char *argv[]) { /* swap my current instances port to be last to collect all threads and exception port info */ int myTaskPosition = -1; for (int i = 0; i < taskCount; i++) { - if (tasks[i] == mach_task_self()){ + if (mach_task_is_self(tasks[i])){ myTaskPosition = i; break; } @@ -181,7 +182,7 @@ int main(int argc, char *argv[]) { { fprintf(stderr, "warning: should run as root for best output (cross-ref to other tasks' ports).\n"); /* just the one process */ - ret = task_for_pid(mach_task_self(), lsmp_config.pid, &aTask); + ret = task_read_for_pid(mach_task_self(), lsmp_config.pid, &aTask); if (ret != KERN_SUCCESS) { fprintf(stderr, "task_for_pid() failed: %s %s\n", mach_error_string(ret), TASK_FOR_PID_USAGE_MESG); exit(1); @@ -200,8 +201,9 @@ int main(int argc, char *argv[]) { continue; } - if (psettaskinfo[i].pid == lsmp_config.pid) + if (psettaskinfo[i].pid == lsmp_config.pid) { taskinfo = &psettaskinfo[i]; + } } JSON_OBJECT_BEGIN(lsmp_config.json_output); diff --git a/lsmp.tproj/port_details.c b/lsmp.tproj/port_details.c index fb888e4..69fc9be 100644 --- a/lsmp.tproj/port_details.c +++ b/lsmp.tproj/port_details.c @@ -232,7 +232,7 @@ char * copy_voucher_detail(mach_port_t task, mach_port_name_t voucher, JSON_t js return voucher_outstr; } -void get_receive_port_context(task_t taskp, mach_port_name_t portname, mach_port_context_t *context) { +void get_receive_port_context(task_read_t taskp, mach_port_name_t portname, mach_port_context_t *context) { if (context == NULL) { return; } @@ -248,7 +248,7 @@ void get_receive_port_context(task_t taskp, mach_port_name_t portname, mach_port return; } -int get_recieve_port_status(task_t taskp, mach_port_name_t portname, mach_port_info_ext_t *info){ +int get_recieve_port_status(task_read_t taskp, mach_port_name_t portname, mach_port_info_ext_t *info){ if (info == NULL) { return -1; } @@ -625,13 +625,19 @@ static void show_task_table_entry(ipc_info_name_t *entry, my_per_task_info_t *ta if (ret == KERN_SUCCESS && kotype != 0) { JSON_OBJECT_SET(json, identifier, "0x%08x", (natural_t)kobject); JSON_OBJECT_SET(json, type, "%s", kobject_name(kotype)); - if (desc[0]) { - JSON_OBJECT_SET(json, description, "%s", desc); - printf(" 0x%08x %s %s", (natural_t)kobject, kobject_name(kotype), desc); - } else { - printf(" 0x%08x %s", (natural_t)kobject, kobject_name(kotype)); - } - if ((kotype == IKOT_TASK_RESUME) || (kotype == IKOT_TASK_CONTROL) || (kotype == IKOT_TASK_NAME)) { + + if (desc[0]) { + JSON_OBJECT_SET(json, description, "%s", desc); + printf(" 0x%08x %s %s", (natural_t)kobject, kobject_name(kotype), desc); + } else { + printf(" 0x%08x %s", (natural_t)kobject, kobject_name(kotype)); + } + + if ((kotype == IKOT_TASK_RESUME) || + (kotype == IKOT_TASK_CONTROL) || + (kotype == IKOT_TASK_READ) || + (kotype == IKOT_TASK_INSPECT) || + (kotype == IKOT_TASK_NAME)) { if (taskinfo->task_kobject == kobject) { /* neat little optimization since in most cases tasks have themselves in their ipc space */ JSON_OBJECT_SET(json, pid, %d, taskinfo->pid); @@ -645,7 +651,9 @@ static void show_task_table_entry(ipc_info_name_t *entry, my_per_task_info_t *ta } } - if (kotype == IKOT_THREAD_CONTROL) { + if ((kotype == IKOT_THREAD_CONTROL) || + (kotype == IKOT_THREAD_READ) || + (kotype == IKOT_THREAD_INSPECT)) { for (int i = 0; i < taskinfo->threadCount; i++) { if (taskinfo->threadInfos[i].th_kobject == kobject) { printf(" (%#llx)", taskinfo->threadInfos[i].th_id); @@ -673,7 +681,7 @@ static void show_task_table_entry(ipc_info_name_t *entry, my_per_task_info_t *ta /* not kobject - find the receive right holder */ my_per_task_info_t *recv_holder_taskinfo; mach_port_name_t recv_name = MACH_PORT_NULL; - if (KERN_SUCCESS == get_taskinfo_of_receiver_by_send_right(entry, &recv_holder_taskinfo, &recv_name)) { + if (KERN_SUCCESS == get_taskinfo_of_receiver_by_send_right(*entry, &recv_holder_taskinfo, &recv_name)) { mach_port_status_t port_status; mach_port_info_ext_t info; mach_port_context_t port_context = (mach_port_context_t)0; diff --git a/lsmp.tproj/task_details.c b/lsmp.tproj/task_details.c index bf9ef51..123f8aa 100644 --- a/lsmp.tproj/task_details.c +++ b/lsmp.tproj/task_details.c @@ -139,7 +139,7 @@ void deallocate_taskinfo_memory(my_per_task_info_t *data){ } } -kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_task) +kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_read_t target_task) { int i; kern_return_t ret = KERN_SUCCESS; @@ -149,10 +149,10 @@ kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_ taskinfo->task = target_task; pid_for_task(target_task, &taskinfo->pid); - ret = task_get_exception_ports(taskinfo->task, EXC_MASK_ALL, taskinfo->exceptionInfo.masks, &taskinfo->exceptionInfo.count, taskinfo->exceptionInfo.ports, taskinfo->exceptionInfo.behaviors, taskinfo->exceptionInfo.flavors); + ret = task_get_exception_ports_info(taskinfo->task, EXC_MASK_ALL, taskinfo->exceptionInfo.masks, &taskinfo->exceptionInfo.count, taskinfo->exceptionInfo.ports_info, taskinfo->exceptionInfo.behaviors, taskinfo->exceptionInfo.flavors); if (ret != KERN_SUCCESS) { - fprintf(stderr, "task_get_exception_ports() failed: pid:%d error: %s\n",taskinfo->pid, mach_error_string(ret)); + fprintf(stderr, "task_get_exception_ports_info() failed: pid:%d error: %s\n",taskinfo->pid, mach_error_string(ret)); taskinfo->pid = 0; } @@ -180,9 +180,9 @@ kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_ mach_msg_type_number_t th_info_count = THREAD_IDENTIFIER_INFO_COUNT; struct exc_port_info *excinfo = &(taskinfo->threadExceptionInfos[i]); - ret = thread_get_exception_ports(threadPorts[i], EXC_MASK_ALL, excinfo->masks, &excinfo->count, excinfo->ports, excinfo->behaviors, excinfo->flavors); + ret = thread_get_exception_ports_info(threadPorts[i], EXC_MASK_ALL, excinfo->masks, &excinfo->count, excinfo->ports_info, excinfo->behaviors, excinfo->flavors); if (ret != KERN_SUCCESS){ - fprintf(stderr, "thread_get_exception_ports() failed: pid: %d thread: %d error %s\n", taskinfo->pid, threadPorts[i], mach_error_string(ret)); + fprintf(stderr, "thread_get_exception_ports_info() failed: pid: %d thread: %d error %s\n", taskinfo->pid, threadPorts[i], mach_error_string(ret)); } if (excinfo->count != 0) { @@ -236,8 +236,9 @@ kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_ proc_pid_to_name(taskinfo->pid, taskinfo->processName); ret = mach_port_kernel_object(mach_task_self(), taskinfo->task, &kotype, (unsigned *)&kobject); - - if (ret == KERN_SUCCESS && kotype == IKOT_TASK_CONTROL) { + + /* Now that we are using read ports, kotype should be checked against IKOT_TASK_READ */ + if (ret == KERN_SUCCESS && kotype == IKOT_TASK_READ) { taskinfo->task_kobject = kobject; taskinfo->valid = TRUE; } @@ -307,23 +308,32 @@ kern_return_t print_task_exception_info(my_per_task_info_t *taskinfo, JSON_t jso boolean_t header_required = TRUE; for (int i = 0; i < taskinfo->exceptionInfo.count; i++) { - if (taskinfo->exceptionInfo.ports[i] != MACH_PORT_NULL) { + if (taskinfo->exceptionInfo.ports_info[i].iip_port_object != 0) { + my_per_task_info_t * _found_task; + if (header_required) { - printf(" exc_port flavor mask \n"); + printf(" exc_port_object receiver_task flavor mask \n"); header_required = FALSE; } get_exc_behavior_string(taskinfo->exceptionInfo.behaviors[i], behavior_string, sizeof(behavior_string)); get_exc_mask_string(taskinfo->exceptionInfo.masks[i], mask_string, sizeof(mask_string)); JSON_OBJECT_BEGIN(json); - JSON_OBJECT_SET(json, port, "0x%08x", taskinfo->exceptionInfo.ports[i]); + JSON_OBJECT_SET(json, port_object, "0x%08x", taskinfo->exceptionInfo.ports_info[i].iip_port_object); + JSON_OBJECT_SET(json, receiver_object, "0x%08x", taskinfo->exceptionInfo.ports_info[i].iip_receiver_object); JSON_OBJECT_SET(json, flavor, "0x%03x", taskinfo->exceptionInfo.flavors[i]); JSON_OBJECT_SET(json, behavior, "%s", behavior_string); JSON_OBJECT_SET(json, mask, "%s", mask_string); JSON_OBJECT_END(json); // exception port - - printf(" 0x%08x 0x%03x <%s> %s \n" , taskinfo->exceptionInfo.ports[i], taskinfo->exceptionInfo.flavors[i], behavior_string, mask_string); + + _found_task = get_taskinfo_by_kobject((natural_t)taskinfo->exceptionInfo.ports_info[i].iip_receiver_object); + + printf(" 0x%08x (%d) %s 0x%03x <%s> %s \n", + taskinfo->exceptionInfo.ports_info[i].iip_port_object, + _found_task->pid, + _found_task->processName, + taskinfo->exceptionInfo.flavors[i], behavior_string, mask_string); } } @@ -389,39 +399,35 @@ kern_return_t print_task_threads_special_ports(my_per_task_info_t *taskinfo, JSO for (int i = 0; i < excinfo->count; i++) { JSON_OBJECT_BEGIN(json); - if (excinfo->ports[i] != MACH_PORT_NULL) { + if (excinfo->ports_info[i].iip_port_object != 0) { if (header_required) { - printf("\n exc_port flavor mask -> name owner\n"); + printf("\n exc_port_object exc_port_receiver flavor mask -> name owner\n"); header_required = FALSE; } get_exc_behavior_string(excinfo->behaviors[i], behavior_string, sizeof(behavior_string)); get_exc_mask_string(excinfo->masks[i], mask_string, sizeof(mask_string)); - JSON_OBJECT_SET(json, port, "0x%08x", excinfo->ports[i]); + JSON_OBJECT_SET(json, port_object, "0x%08x", excinfo->ports_info[i].iip_port_object); + JSON_OBJECT_SET(json, receiver_object, "0x%08x", excinfo->ports_info[i].iip_receiver_object); JSON_OBJECT_SET(json, flavor, "0x%03x", excinfo->flavors[i]); JSON_OBJECT_SET(json, behavior, "%s", behavior_string); JSON_OBJECT_SET(json, mask, "%s", mask_string); - printf(" 0x%08x 0x%03x <%s> %s " , excinfo->ports[i], excinfo->flavors[i], behavior_string, mask_string); - - ipc_info_name_t actual_sendinfo; - if (KERN_SUCCESS == get_ipc_info_from_lsmp_spaceinfo(excinfo->ports[i], &actual_sendinfo)) { - my_per_task_info_t *recv_holder_taskinfo; - mach_port_name_t recv_name = MACH_PORT_NULL; - if (KERN_SUCCESS == get_taskinfo_of_receiver_by_send_right(&actual_sendinfo, &recv_holder_taskinfo, &recv_name)) { - - JSON_OBJECT_SET(json, name, "0x%08x", recv_name); - JSON_OBJECT_SET(json, ipc-object, "0x%08x", actual_sendinfo.iin_object); - JSON_OBJECT_SET(json, pid, %d, recv_holder_taskinfo->pid); - JSON_OBJECT_SET(json, process, "%s", recv_holder_taskinfo->processName); - - printf(" -> 0x%08x 0x%08x (%d) %s\n", - recv_name, - actual_sendinfo.iin_object, - recv_holder_taskinfo->pid, - recv_holder_taskinfo->processName); - } - + printf(" 0x%08x 0x%08x 0x%03x <%s> %s " , excinfo->ports_info[i].iip_port_object, excinfo->ports_info[i].iip_receiver_object, excinfo->flavors[i], behavior_string, mask_string); + + my_per_task_info_t *recv_holder_taskinfo; + mach_port_name_t recv_name = MACH_PORT_NULL; + if (KERN_SUCCESS == get_taskinfo_of_receiver_by_send_right_info(excinfo->ports_info[i], &recv_holder_taskinfo, &recv_name)) { + JSON_OBJECT_SET(json, name, "0x%08x", recv_name); + JSON_OBJECT_SET(json, ipc-object, "0x%08x", excinfo->ports_info[i].iip_port_object); + JSON_OBJECT_SET(json, pid, %d, recv_holder_taskinfo->pid); + JSON_OBJECT_SET(json, process, "%s", recv_holder_taskinfo->processName); + + printf(" -> 0x%08x 0x%08x (%d) %s\n", + recv_name, + excinfo->ports_info[i].iip_port_object, + recv_holder_taskinfo->pid, + recv_holder_taskinfo->processName); } else { fprintf(stderr, "failed to find"); } @@ -463,14 +469,14 @@ my_per_task_info_t * get_taskinfo_by_kobject(natural_t kobj) { return retval; } -kern_return_t get_taskinfo_of_receiver_by_send_right(ipc_info_name_t *sendright, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info) +static kern_return_t _get_taskinfo_of_receiver_by_send_right(natural_t kobject, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info) { *out_taskinfo = &NOT_FOUND_TASK_INFO; struct k2n_table_node *k2nnode; - for (int j = 0; j < global_taskcount; j++) { - if ((k2nnode = k2n_table_lookup(global_taskinfo[j].k2ntable, sendright->iin_object))) { - assert(k2nnode->info_name->iin_object == sendright->iin_object); + for (unsigned int j = 0; j < global_taskcount; j++) { + if ((k2nnode = k2n_table_lookup(global_taskinfo[j].k2ntable, kobject))) { + assert(k2nnode->info_name->iin_object == kobject); if (k2nnode->info_name->iin_type & MACH_PORT_TYPE_RECEIVE) { *out_taskinfo = &global_taskinfo[j]; @@ -483,25 +489,12 @@ kern_return_t get_taskinfo_of_receiver_by_send_right(ipc_info_name_t *sendright, return KERN_FAILURE; } -kern_return_t get_ipc_info_from_lsmp_spaceinfo(mach_port_t port_name, ipc_info_name_t *out_sendright){ - kern_return_t retval = KERN_FAILURE; - bzero(out_sendright, sizeof(ipc_info_name_t)); - my_per_task_info_t *mytaskinfo = NULL; - for (int i = global_taskcount - 1; i >= 0; i--){ - if (global_taskinfo[i].task == mach_task_self()){ - mytaskinfo = &global_taskinfo[i]; - break; - } - } - if (mytaskinfo) { - for (int k = 0; k < mytaskinfo->tableCount; k++) { - if (port_name == mytaskinfo->table[k].iin_name){ - bcopy(&mytaskinfo->table[k], out_sendright, sizeof(ipc_info_name_t)); - retval = KERN_SUCCESS; - break; - } - } - } - return retval; +kern_return_t get_taskinfo_of_receiver_by_send_right(ipc_info_name_t sendright, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info) +{ + return _get_taskinfo_of_receiver_by_send_right(sendright.iin_object, out_taskinfo, out_recv_info); +} +kern_return_t get_taskinfo_of_receiver_by_send_right_info(ipc_info_port_t sendright_info, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info) +{ + return _get_taskinfo_of_receiver_by_send_right(sendright_info.iip_port_object, out_taskinfo, out_recv_info); } diff --git a/nvram.tproj/entitlements.plist b/nvram.tproj/entitlements.plist new file mode 100644 index 0000000..9866704 --- /dev/null +++ b/nvram.tproj/entitlements.plist @@ -0,0 +1,8 @@ + + + + + com.apple.private.iokit.system-nvram-internal-allow + + + diff --git a/nvram.tproj/nvram.c b/nvram.tproj/nvram.c index 20d1927..b10ab2e 100644 --- a/nvram.tproj/nvram.c +++ b/nvram.tproj/nvram.c @@ -33,26 +33,27 @@ cc -o nvram nvram.c -framework CoreFoundation -framework IOKit -Wall #include // Prototypes -static void UsageMessage(char *message); -static void ParseFile(char *fileName); -static void ParseXMLFile(char *fileName); +static void UsageMessage(const char *message); +static void ParseFile(const char *fileName); +static void ParseXMLFile(const char *fileName); static void SetOrGetOFVariable(char *str); -static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef, - CFTypeRef *valueRef); -static kern_return_t SetOFVariable(char *name, char *value); -static void DeleteOFVariable(char *name); +static kern_return_t GetOFVariable(const char *name, CFStringRef *nameRef, + CFTypeRef *valueRef); +static kern_return_t SetOFVariable(const char *name, const char *value); +static void DeleteOFVariable(const char *name); static void PrintOFVariables(void); static void PrintOFVariable(const void *key,const void *value,void *context); static void SetOFVariableFromFile(const void *key, const void *value, void *context); static void ClearOFVariables(void); static void ClearOFVariable(const void *key,const void *value,void *context); -static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value); +static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, const char *value); -static void NVRamSyncNow(char *name); +static void NVRamSyncNow(void); // Global Variables -static char *gToolName; static io_registry_entry_t gOptionsRef; +static io_registry_entry_t gSystemOptionsRef; +static io_registry_entry_t gSelectedOptionsRef; static bool gUseXML; static bool gUseForceSync; @@ -85,12 +86,7 @@ int main(int argc, char **argv) char *str, errorMessage[256]; kern_return_t result; mach_port_t masterPort; - int argcount = 0; - - // Get the name of the command. - gToolName = strrchr(argv[0], '/'); - if (gToolName != 0) gToolName++; - else gToolName = argv[0]; + int argcount = 0; result = IOMasterPort(bootstrap_port, &masterPort); if (result != KERN_SUCCESS) { @@ -103,106 +99,125 @@ int main(int argc, char **argv) errx(1, "nvram is not supported on this system"); } + gSystemOptionsRef = IORegistryEntryFromPath(masterPort, "IOService:/options/options-system"); + + gSelectedOptionsRef = gOptionsRef; + for (cnt = 1; cnt < argc; cnt++) { str = argv[cnt]; if (str[0] == '-' && str[1] != 0) { // Parse the options. for (str += 1 ; *str; str++) { - switch (*str) { - case 'p' : + switch (*str) { + case 'p' : #if TARGET_OS_BRIDGE - if (gBridgeToIntel) { - fprintf(stderr, "-p not supported for Mac NVRAM store.\n"); - return 1; - } + if (gBridgeToIntel) { + fprintf(stderr, "-p not supported for Mac NVRAM store.\n"); + return 1; + } #endif - PrintOFVariables(); - break; + PrintOFVariables(); + break; - case 'x' : - gUseXML = true; - break; + case 'x' : + gUseXML = true; + break; - case 'f': + case 'f': #if TARGET_OS_BRIDGE - if (gBridgeToIntel) { - fprintf(stderr, "-f not supported for Mac NVRAM store.\n"); - return 1; - } + if (gBridgeToIntel) { + fprintf(stderr, "-f not supported for Mac NVRAM store.\n"); + return 1; + } #endif - cnt++; - if (cnt < argc && *argv[cnt] != '-') { - ParseFile(argv[cnt]); - } else { - UsageMessage("missing filename"); - } - break; - - case 'd': - cnt++; - if (cnt < argc && *argv[cnt] != '-') { + cnt++; + if (cnt < argc && *argv[cnt] != '-') { + ParseFile(argv[cnt]); + } else { + UsageMessage("missing filename"); + } + break; + + case 'd': + cnt++; + if (cnt < argc && *argv[cnt] != '-') { #if TARGET_OS_BRIDGE - if (gBridgeToIntel) { - if ((result = DeleteMacOFVariable(argv[cnt])) != KERN_SUCCESS) { + if (gBridgeToIntel) { + if ((result = DeleteMacOFVariable(argv[cnt])) != KERN_SUCCESS) { errx(1, "Error deleting variable - '%s': %s (0x%08x)", argv[cnt], mach_error_string(result), result); + } } - } - else + else #endif - { - DeleteOFVariable(argv[cnt]); - } - } else { - UsageMessage("missing name"); - } - break; + { + DeleteOFVariable(argv[cnt]); + } + } else { + UsageMessage("missing name"); + } + break; - case 'c': + case 'c': #if TARGET_OS_BRIDGE - if (gBridgeToIntel) { - fprintf(stderr, "-c not supported for Mac NVRAM store.\n"); - return 1; - } + if (gBridgeToIntel) { + fprintf(stderr, "-c not supported for Mac NVRAM store.\n"); + return 1; + } #endif - ClearOFVariables(); - break; - case 's': - // -s option is unadvertised -- advises the kernel more forcibly to - // commit the variable to nonvolatile storage - gUseForceSync = true; - break; + ClearOFVariables(); + break; + case 's': + // -s option is unadvertised -- advises the kernel more forcibly to + // commit the variable to nonvolatile storage + gUseForceSync = true; + break; #if TARGET_OS_BRIDGE - case 'm': - // used to set nvram variables on the Intel side - // from the ARM side (Bridge -> Mac) - fprintf(stdout, "Using Mac NVRAM store.\n"); - - LinkMacNVRAMSymbols(); - gBridgeToIntel = true; - break; + case 'm': + // used to set nvram variables on the Intel side + // from the ARM side (Bridge -> Mac) + fprintf(stdout, "Using Mac NVRAM store.\n"); + + LinkMacNVRAMSymbols(); + gBridgeToIntel = true; + break; #endif - default: - strcpy(errorMessage, "no such option as --"); - errorMessage[strlen(errorMessage)-1] = *str; - UsageMessage(errorMessage); - } + case 'z': + // -z option is unadvertised -- attempts to use the options-system node + // to write to the system NVRAM region if available + if (gSystemOptionsRef) { + fprintf(stderr, "Selecting options-system node.\n"); + gSelectedOptionsRef = gSystemOptionsRef; + } else { + fprintf(stderr, "No options-system node, using options.\n"); + } + break; + + default: + strcpy(errorMessage, "no such option as --"); + errorMessage[strlen(errorMessage)-1] = *str; + UsageMessage(errorMessage); + } + } + } else { + // Other arguments will be firmware variable requests. + argcount++; + SetOrGetOFVariable(str); } - } else { - // Other arguments will be firmware variable requests. - argcount++; - SetOrGetOFVariable(str); - } } // radar:25206371 if (argcount == 0 && gUseForceSync == true) { - NVRamSyncNow(""); + NVRamSyncNow(); } IOObjectRelease(gOptionsRef); + if (gSystemOptionsRef) { + IOObjectRelease(gSystemOptionsRef); + } + return 0; } @@ -210,11 +225,11 @@ int main(int argc, char **argv) // // Print the usage information and exit. // -static void UsageMessage(char *message) +static void UsageMessage(const char *message) { warnx("(usage: %s)", message); - printf("%s [-x] [-p] [-f filename] [-d name] [-c] name[=value] ...\n", gToolName); + printf("nvram [-x] [-p] [-f filename] [-d name] [-c] name[=value] ...\n"); printf("\t-x use XML format for printing or reading variables\n"); printf("\t (must appear before -p or -f)\n"); printf("\t-p print all firmware variables\n"); @@ -252,7 +267,7 @@ enum { // // Open and parse the specified file. // -static void ParseFile(char *fileName) +static void ParseFile(const char *fileName) { long state, ni = 0, vi = 0; int tc; @@ -282,72 +297,72 @@ static void ParseFile(char *fileName) ni = 0; vi = 0; if (tc == '#') { - state = kScanComment; + state = kScanComment; } else if (tc == '\n') { - // state stays kFirstColumn. + // state stays kFirstColumn. } else if (isspace(tc)) { - state = kFindName; + state = kFindName; } else { - state = kCollectName; - name[ni++] = tc; + state = kCollectName; + name[ni++] = tc; } break; case kScanComment : if (tc == '\n') { - state = kFirstColumn; + state = kFirstColumn; } else { - // state stays kScanComment. + // state stays kScanComment. } break; case kFindName : if (tc == '\n') { - state = kFirstColumn; + state = kFirstColumn; } else if (isspace(tc)) { - // state stays kFindName. + // state stays kFindName. } else { - state = kCollectName; - name[ni++] = tc; + state = kCollectName; + name[ni++] = tc; } break; case kCollectName : if (tc == '\n') { - name[ni] = 0; - warnx("Name must be followed by white space - '%s'", name); - state = kFirstColumn; + name[ni] = 0; + warnx("Name must be followed by white space - '%s'", name); + state = kFirstColumn; } else if (isspace(tc)) { - state = kFindValue; + state = kFindValue; } else { - name[ni++] = tc; - // state staus kCollectName. + name[ni++] = tc; + // state staus kCollectName. } break; case kFindValue : case kContinueValue : if (tc == '\n') { - state = kSetenv; + state = kSetenv; } else if (isspace(tc)) { - // state stays kFindValue or kContinueValue. + // state stays kFindValue or kContinueValue. } else { - state = kCollectValue; - value[vi++] = tc; + state = kCollectValue; + value[vi++] = tc; } break; case kCollectValue : if (tc == '\n') { - if (value[vi-1] == '\\') { - value[vi-1] = '\r'; - state = kContinueValue; - } else { - state = kSetenv; - } + if (value[vi-1] == '\\') { + value[vi-1] = '\r'; + state = kContinueValue; + } else { + state = kSetenv; + } } else { - // state stays kCollectValue. - value[vi++] = tc; + // state stays kCollectValue. + value[vi++] = tc; } break; } @@ -373,71 +388,71 @@ static void ParseFile(char *fileName) // Open and parse the specified file in XML format, // and set variables appropriately. // -static void ParseXMLFile(char *fileName) +static void ParseXMLFile(const char *fileName) { - CFPropertyListRef plist; - int fd; - struct stat sb; - char *buffer; - CFReadStreamRef stream; - CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0; - - fd = open(fileName, O_RDONLY | O_NOFOLLOW, S_IFREG); - if (fd == -1) { - errx(1, "Could not open %s: %s", fileName, strerror(errno)); - } + CFPropertyListRef plist; + int fd; + struct stat sb; + char *buffer; + CFReadStreamRef stream; + CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0; + + fd = open(fileName, O_RDONLY | O_NOFOLLOW, S_IFREG); + if (fd == -1) { + errx(1, "Could not open %s: %s", fileName, strerror(errno)); + } - if (fstat(fd, &sb) == -1) { - errx(1, "Could not fstat %s: %s", fileName, strerror(errno)); - } + if (fstat(fd, &sb) == -1) { + errx(1, "Could not fstat %s: %s", fileName, strerror(errno)); + } - if (sb.st_size > UINT32_MAX) { - errx(1, "too big for our purposes"); - } + if (sb.st_size > UINT32_MAX) { + errx(1, "too big for our purposes"); + } - buffer = malloc((size_t)sb.st_size); - if (buffer == NULL) { - errx(1, "Could not allocate buffer"); - } + buffer = malloc((size_t)sb.st_size); + if (buffer == NULL) { + errx(1, "Could not allocate buffer"); + } - if (read(fd, buffer, (size_t)sb.st_size) != sb.st_size) { - errx(1, "Could not read %s: %s", fileName, strerror(errno)); - } + if (read(fd, buffer, (size_t)sb.st_size) != sb.st_size) { + errx(1, "Could not read %s: %s", fileName, strerror(errno)); + } - close(fd); + close(fd); - stream = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, - (const UInt8 *)buffer, - (CFIndex)sb.st_size, - kCFAllocatorNull); - if (stream == NULL) { - errx(1, "Could not create stream from serialized data"); - } + stream = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, + (const UInt8 *)buffer, + (CFIndex)sb.st_size, + kCFAllocatorNull); + if (stream == NULL) { + errx(1, "Could not create stream from serialized data"); + } - if (!CFReadStreamOpen(stream)) { - errx(1, "Could not open the stream"); - } + if (!CFReadStreamOpen(stream)) { + errx(1, "Could not open the stream"); + } - plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, - stream, - (CFIndex)sb.st_size, - kCFPropertyListImmutable, - &format, - NULL); + plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, + stream, + (CFIndex)sb.st_size, + kCFPropertyListImmutable, + &format, + NULL); - if (plist == NULL) { - errx(1, "Error parsing XML file"); - } + if (plist == NULL) { + errx(1, "Error parsing XML file"); + } - CFReadStreamClose(stream); + CFReadStreamClose(stream); - CFRelease(stream); + CFRelease(stream); - free(buffer); + free(buffer); - CFDictionaryApplyFunction(plist, &SetOFVariableFromFile, 0); + CFDictionaryApplyFunction(plist, &SetOFVariableFromFile, 0); - CFRelease(plist); + CFRelease(plist); } // SetOrGetOFVariable(str) @@ -447,14 +462,14 @@ static void ParseXMLFile(char *fileName) // static void SetOrGetOFVariable(char *str) { - long set = 0; - long append = 0; - char *name; - char *value; + long set = 0; + long append = 0; + const char *name; + char *value; CFStringRef nameRef = NULL; CFTypeRef valueRef = NULL; CFMutableStringRef appended = NULL; - kern_return_t result; + kern_return_t result; // OF variable name is first. name = str; @@ -521,7 +536,8 @@ static void SetOrGetOFVariable(char *str) #endif { result = SetOFVariable(name, value); - NVRamSyncNow(name); /* Try syncing the new data to device, best effort! */ + /* Try syncing the new data to device, best effort! */ + NVRamSyncNow(); } if (result != KERN_SUCCESS) { errx(1, "Error setting variable - '%s': %s", name, @@ -530,9 +546,9 @@ static void SetOrGetOFVariable(char *str) } else { PrintOFVariable(nameRef, valueRef, 0); } - if ( nameRef ) CFRelease(nameRef); - if ( valueRef ) CFRelease(valueRef); - if ( appended ) CFRelease(appended); + if (nameRef) CFRelease(nameRef); + if (valueRef) CFRelease(valueRef); + if (appended) CFRelease(appended); } #if TARGET_OS_BRIDGE @@ -586,16 +602,16 @@ static kern_return_t LinkMacNVRAMSymbols() // Get the named firmware variable. // Return it and it's symbol in valueRef and nameRef. // -static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef, - CFTypeRef *valueRef) +static kern_return_t GetOFVariable(const char *name, CFStringRef *nameRef, + CFTypeRef *valueRef) { *nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name, - kCFStringEncodingUTF8); + kCFStringEncodingUTF8); if (*nameRef == 0) { errx(1, "Error creating CFString for key %s", name); } - *valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, *nameRef, 0, 0); + *valueRef = IORegistryEntryCreateCFProperty(gSelectedOptionsRef, *nameRef, 0, 0); if (*valueRef == 0) return kIOReturnNotFound; return KERN_SUCCESS; @@ -619,59 +635,59 @@ static kern_return_t GetMacOFVariable(char *name, char **value) // // Set or create an firmware variable with name and value. // -static kern_return_t SetOFVariable(char *name, char *value) +static kern_return_t SetOFVariable(const char *name, const char *value) { CFStringRef nameRef; CFTypeRef valueRef; CFTypeID typeID; kern_return_t result = KERN_SUCCESS; - nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name, - kCFStringEncodingUTF8); - if (nameRef == 0) { - errx(1, "Error creating CFString for key %s", name); - } + nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name, + kCFStringEncodingUTF8); + if (nameRef == 0) { + errx(1, "Error creating CFString for key %s", name); + } - valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, nameRef, 0, 0); - if (valueRef) { - typeID = CFGetTypeID(valueRef); - CFRelease(valueRef); - - valueRef = ConvertValueToCFTypeRef(typeID, value); - if (valueRef == 0) { - errx(1, "Error creating CFTypeRef for value %s", value); - } result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - } else { - while (1) { - // In the default case, try data, string, number, then boolean. - - valueRef = ConvertValueToCFTypeRef(CFDataGetTypeID(), value); - if (valueRef != 0) { - result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - if (result == KERN_SUCCESS) break; - } + valueRef = IORegistryEntryCreateCFProperty(gSelectedOptionsRef, nameRef, 0, 0); + if (valueRef) { + typeID = CFGetTypeID(valueRef); + CFRelease(valueRef); - valueRef = ConvertValueToCFTypeRef(CFStringGetTypeID(), value); - if (valueRef != 0) { - result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - if (result == KERN_SUCCESS) break; - } + valueRef = ConvertValueToCFTypeRef(typeID, value); + if (valueRef == 0) { + errx(1, "Error creating CFTypeRef for value %s", value); + } result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef); + } else { + while (1) { + // In the default case, try data, string, number, then boolean. - valueRef = ConvertValueToCFTypeRef(CFNumberGetTypeID(), value); - if (valueRef != 0) { - result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - if (result == KERN_SUCCESS) break; - } + valueRef = ConvertValueToCFTypeRef(CFDataGetTypeID(), value); + if (valueRef != 0) { + result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef); + if (result == KERN_SUCCESS) break; + } - valueRef = ConvertValueToCFTypeRef(CFBooleanGetTypeID(), value); - if (valueRef != 0) { - result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - if (result == KERN_SUCCESS) break; - } + valueRef = ConvertValueToCFTypeRef(CFStringGetTypeID(), value); + if (valueRef != 0) { + result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef); + if (result == KERN_SUCCESS) break; + } - break; - } - } + valueRef = ConvertValueToCFTypeRef(CFNumberGetTypeID(), value); + if (valueRef != 0) { + result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef); + if (result == KERN_SUCCESS) break; + } + + valueRef = ConvertValueToCFTypeRef(CFBooleanGetTypeID(), value); + if (valueRef != 0) { + result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef); + if (result == KERN_SUCCESS) break; + } + + break; + } + } CFRelease(nameRef); @@ -689,8 +705,7 @@ static kern_return_t SetMacOFVariable(char *name, char *value) // // Delete the named firmware variable. // -// -static void DeleteOFVariable(char *name) +static void DeleteOFVariable(const char *name) { SetOFVariable(kIONVRAMDeletePropertyKey, name); } @@ -698,16 +713,16 @@ static void DeleteOFVariable(char *name) #if TARGET_OS_BRIDGE static kern_return_t DeleteMacOFVariable(char *name) { - return deleteNVRAMVariable_fptr(gNvramInterface, name); + return deleteNVRAMVariable_fptr(gNvramInterface, name); } #endif -static void NVRamSyncNow(char *name) +static void NVRamSyncNow(void) { if (!gUseForceSync) { - SetOFVariable(kIONVRAMSyncNowPropertyKey, name); + SetOFVariable(kIONVRAMSyncNowPropertyKey, kIONVRAMSyncNowPropertyKey); } else { - SetOFVariable(kIONVRAMForceSyncNowPropertyKey, name); + SetOFVariable(kIONVRAMForceSyncNowPropertyKey, kIONVRAMForceSyncNowPropertyKey); } } @@ -720,7 +735,7 @@ static void PrintOFVariables(void) kern_return_t result; CFMutableDictionaryRef dict; - result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict, 0, 0); + result = IORegistryEntryCreateCFProperties(gSelectedOptionsRef, &dict, 0, 0); if (result != KERN_SUCCESS) { errx(1, "Error getting the firmware variables: %s", mach_error_string(result)); } @@ -764,7 +779,7 @@ static void PrintOFVariable(const void *key, const void *value, void *context) char *valueBuffer = 0; const char *valueString = 0; uint32_t number; - long length; + long length; CFTypeID typeID; if (gUseXML) { @@ -826,18 +841,18 @@ static void PrintOFVariable(const void *key, const void *value, void *context) else { dataBuffer = malloc(length * 3 + 1); if (dataBuffer != 0) { - dataPtr = CFDataGetBytePtr(value); - for (cnt = cnt2 = 0; cnt < length; cnt++) { - dataChar = dataPtr[cnt]; - if (isprint(dataChar) && dataChar != '%') { - dataBuffer[cnt2++] = dataChar; - } else { - sprintf(dataBuffer + cnt2, "%%%02x", dataChar); - cnt2 += 3; - } - } - dataBuffer[cnt2] = '\0'; - valueString = dataBuffer; + dataPtr = CFDataGetBytePtr(value); + for (cnt = cnt2 = 0; cnt < length; cnt++) { + dataChar = dataPtr[cnt]; + if (isprint(dataChar) && dataChar != '%') { + dataBuffer[cnt2++] = dataChar; + } else { + sprintf(dataBuffer + cnt2, "%%%02x", dataChar); + cnt2 += 3; + } + } + dataBuffer[cnt2] = '\0'; + valueString = dataBuffer; } } } else { @@ -861,7 +876,7 @@ static void ClearOFVariables(void) kern_return_t result; CFMutableDictionaryRef dict; - result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict, 0, 0); + result = IORegistryEntryCreateCFProperties(gSelectedOptionsRef, &dict, 0, 0); if (result != KERN_SUCCESS) { errx(1, "Error getting the firmware variables: %s", mach_error_string(result)); } @@ -873,7 +888,7 @@ static void ClearOFVariables(void) static void ClearOFVariable(const void *key, const void *value, void *context) { kern_return_t result; - result = IORegistryEntrySetCFProperty(gOptionsRef, + result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, CFSTR(kIONVRAMDeletePropertyKey), key); if (result != KERN_SUCCESS) { assert(CFGetTypeID(key) == CFStringGetTypeID()); @@ -902,38 +917,40 @@ static void ClearOFVariable(const void *key, const void *value, void *context) // // Convert the value into a CFType given the typeID. // -static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value) +static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, const char *value) { CFTypeRef valueRef = 0; long cnt, cnt2, length; unsigned long number, tmp; if (typeID == CFBooleanGetTypeID()) { - if (!strcmp("true", value)) valueRef = kCFBooleanTrue; - else if (!strcmp("false", value)) valueRef = kCFBooleanFalse; + if (!strcmp("true", value)) valueRef = kCFBooleanTrue; + else if (!strcmp("false", value)) valueRef = kCFBooleanFalse; } else if (typeID == CFNumberGetTypeID()) { - number = strtol(value, 0, 0); - valueRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, - &number); + number = strtol(value, 0, 0); + valueRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, + &number); } else if (typeID == CFStringGetTypeID()) { - valueRef = CFStringCreateWithCString(kCFAllocatorDefault, value, - kCFStringEncodingUTF8); + valueRef = CFStringCreateWithCString(kCFAllocatorDefault, value, + kCFStringEncodingUTF8); } else if (typeID == CFDataGetTypeID()) { - length = strlen(value); - for (cnt = cnt2 = 0; cnt < length; cnt++, cnt2++) { - if (value[cnt] == '%') { - if (!ishexnumber(value[cnt + 1]) || - !ishexnumber(value[cnt + 2])) return 0; - number = toupper(value[++cnt]) - '0'; - if (number > 9) number -= 7; - tmp = toupper(value[++cnt]) - '0'; - if (tmp > 9) tmp -= 7; - number = (number << 4) + tmp; - value[cnt2] = number; - } else value[cnt2] = value[cnt]; - } - valueRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)value, - cnt2, kCFAllocatorDefault); + length = strlen(value); + char valueCopy[length + 1]; + + for (cnt = cnt2 = 0; cnt < length; cnt++, cnt2++) { + if (value[cnt] == '%') { + if ((cnt + 2 > length) || + !ishexnumber(value[cnt + 1]) || + !ishexnumber(value[cnt + 2])) return 0; + number = toupper(value[++cnt]) - '0'; + if (number > 9) number -= 7; + tmp = toupper(value[++cnt]) - '0'; + if (tmp > 9) tmp -= 7; + number = (number << 4) + tmp; + valueCopy[cnt2] = number; + } else valueCopy[cnt2] = value[cnt]; + } + valueRef = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)valueCopy, cnt2); } else return 0; return valueRef; @@ -943,23 +960,23 @@ static void SetOFVariableFromFile(const void *key, const void *value, void *cont { kern_return_t result; - result = IORegistryEntrySetCFProperty(gOptionsRef, key, value); + result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, key, value); if ( result != KERN_SUCCESS ) { - long nameLen; - char *nameBuffer; - char *nameString; - - // Get the variable's name. - nameLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key), - kCFStringEncodingUTF8) + 1; - nameBuffer = malloc(nameLen); - if( nameBuffer && CFStringGetCString(key, nameBuffer, nameLen, kCFStringEncodingUTF8) ) - nameString = nameBuffer; - else { - warnx("Unable to convert property name to C string"); - nameString = ""; - } - errx(1, "Error setting variable - '%s': %s", nameString, - mach_error_string(result)); + long nameLen; + char *nameBuffer; + char *nameString; + + // Get the variable's name. + nameLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key), + kCFStringEncodingUTF8) + 1; + nameBuffer = malloc(nameLen); + if( nameBuffer && CFStringGetCString(key, nameBuffer, nameLen, kCFStringEncodingUTF8) ) + nameString = nameBuffer; + else { + warnx("Unable to convert property name to C string"); + nameString = ""; + } + errx(1, "Error setting variable - '%s': %s", nameString, + mach_error_string(result)); } } diff --git a/system_cmds.xcodeproj/project.pbxproj b/system_cmds.xcodeproj/project.pbxproj index ba1a85a..1236f49 100644 --- a/system_cmds.xcodeproj/project.pbxproj +++ b/system_cmds.xcodeproj/project.pbxproj @@ -2428,6 +2428,7 @@ 97999D301AE84C7600E8B10F /* lskq.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; name = lskq.1; path = lskq.tproj/lskq.1; sourceTree = ""; }; 97999D311AE84C7600E8B10F /* lskq.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = lskq.c; path = lskq.tproj/lskq.c; sourceTree = ""; }; A7C0927020EC491E0068148E /* passwd.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = passwd.entitlements; sourceTree = ""; }; + AD5BBC612551B27F007F6508 /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = entitlements.plist; sourceTree = ""; }; ADA9007717679A8C00161ADF /* purge */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = purge; sourceTree = BUILT_PRODUCTS_DIR; }; ADA900791767A02700161ADF /* purge.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = purge.8; sourceTree = ""; }; ADA9007A1767A02700161ADF /* purge.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = purge.c; sourceTree = ""; }; @@ -3604,6 +3605,7 @@ BA4FD2791372FAFA0025925C /* nvram.tproj */ = { isa = PBXGroup; children = ( + AD5BBC612551B27F007F6508 /* entitlements.plist */, BA4FD27B1372FAFA0025925C /* nvram.8 */, BA4FD27C1372FAFA0025925C /* nvram.c */, ); @@ -7377,6 +7379,7 @@ 1873300218CBD4A700275344 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_ENTITLEMENTS = nvram.tproj/entitlements.plist; HEADER_SEARCH_PATHS = "$(SDKROOT)/usr/local/include"; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = nvram; @@ -8331,6 +8334,7 @@ BAE589A4137836A00049DD3B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_ENTITLEMENTS = nvram.tproj/entitlements.plist; HEADER_SEARCH_PATHS = "$(SDKROOT)/usr/local/include"; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = nvram; diff --git a/taskpolicy.tproj/taskpolicy-entitlements.plist b/taskpolicy.tproj/taskpolicy-entitlements.plist index 39c14ef..f0bf565 100644 --- a/taskpolicy.tproj/taskpolicy-entitlements.plist +++ b/taskpolicy.tproj/taskpolicy-entitlements.plist @@ -2,7 +2,7 @@ - com.apple.security.cs.debugger.root + com.apple.private.task_policy diff --git a/taskpolicy.tproj/taskpolicy.c b/taskpolicy.tproj/taskpolicy.c index 3260bb6..5bc9684 100644 --- a/taskpolicy.tproj/taskpolicy.c +++ b/taskpolicy.tproj/taskpolicy.c @@ -22,6 +22,7 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include #include #include #include @@ -196,9 +197,9 @@ int main(int argc, char * argv[]) qosinfo.task_throughput_qos_tier != THROUGHPUT_QOS_TIER_UNSPECIFIED){ mach_port_t task; if (pid) { - ret = task_for_pid(mach_task_self(), pid, &task); + ret = task_name_for_pid(mach_task_self(), pid, &task); if (ret != KERN_SUCCESS) { - err(EX_SOFTWARE, "task_for_pid(%d) failed", pid); + err(EX_SOFTWARE, "task_name_for_pid(%d) failed", pid); return EX_OSERR; } } else { diff --git a/vm_purgeable_stat.tproj/entitlements.plist b/vm_purgeable_stat.tproj/entitlements.plist index b21dbd8..2ee8d1e 100644 --- a/vm_purgeable_stat.tproj/entitlements.plist +++ b/vm_purgeable_stat.tproj/entitlements.plist @@ -2,7 +2,7 @@ - task_for_pid-allow + com.apple.system-task-ports.inspect diff --git a/vm_purgeable_stat.tproj/vm_purgeable_stat.c b/vm_purgeable_stat.tproj/vm_purgeable_stat.c index bfef539..330704d 100644 --- a/vm_purgeable_stat.tproj/vm_purgeable_stat.c +++ b/vm_purgeable_stat.tproj/vm_purgeable_stat.c @@ -22,6 +22,7 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include #include #include #include @@ -87,7 +88,7 @@ int get_task_from_pid(int pid, task_t *task) fprintf(stderr, "%s\n", PRIV_ERR_MSG); return -1; } - kr = task_for_pid(mach_task_self(), pid, task); + kr = task_inspect_for_pid(mach_task_self(), pid, task); if (kr != KERN_SUCCESS) { fprintf(stderr, "Failed to get task port for pid: %d\n", pid); return -1; @@ -127,9 +128,9 @@ int get_system_tasks(task_array_t *tasks, mach_msg_type_number_t *count) vm_deallocate(mach_task_self(), (vm_address_t)psets, (vm_size_t)psetCount * sizeof(mach_port_t)); /* convert the processor-set-priv to a list of tasks for the processor set */ - ret = processor_set_tasks(pset_priv, tasks, count); + ret = processor_set_tasks_with_flavor(pset_priv, TASK_FLAVOR_INSPECT, tasks, count); if (ret != KERN_SUCCESS) { - fprintf(stderr, "processor_set_tasks() failed: %s\n", mach_error_string(ret)); + fprintf(stderr, "processor_set_tasks_with_flavor() failed: %s\n", mach_error_string(ret)); return -1; } mach_port_deallocate(mach_task_self(), pset_priv); diff --git a/zprint.tproj/zprint.c b/zprint.tproj/zprint.c index 5c90f2d..97f31e4 100644 --- a/zprint.tproj/zprint.c +++ b/zprint.tproj/zprint.c @@ -670,7 +670,9 @@ kern_vm_tag_name(uint64_t tag) case (VM_KERN_MEMORY_REASON): name = "VM_KERN_MEMORY_REASON"; break; case (VM_KERN_MEMORY_SKYWALK): name = "VM_KERN_MEMORY_SKYWALK"; break; case (VM_KERN_MEMORY_LTABLE): name = "VM_KERN_MEMORY_LTABLE"; break; + case (VM_KERN_MEMORY_HV): name = "VM_KERN_MEMORY_HV"; break; case (VM_KERN_MEMORY_ANY): name = "VM_KERN_MEMORY_ANY"; break; + case (VM_KERN_MEMORY_RETIRED): name = "VM_KERN_MEMORY_RETIRED"; break; default: name = NULL; break; } if (name) { -- 2.45.2