Skip to content

Bug Report: mach_port leaks in setInstruction #11

@ChengzhiHuang

Description

@ChengzhiHuang
uint32_t setInstruction(vm_address_t address, uint32_t newInst) {

  if (task_threads(mach_task_self(), &threads, &thread_count) != KERN_SUCCESS) {
    thread_count = 0;
  }

  // skip many codes

  vm_size_t size = thread_count * sizeof(thread_t);
  vm_deallocate(mach_task_self(), (vm_address_t) threads, size);

}

The code only deallocate threads, but don't release the thread_ports . The right function is to release the thread_ports before calling vm_deallocate .

If you don't release it, it will cause SIGKILL (Exceeded system-wide per-process Port Limit) .

  // release thread port
  for(mach_msg_type_number_t i = 0; i < thread_count; i++)
  {
    mach_port_deallocate(mach_task_self(), threads[i]);
  }
  // and then do vm_deallocate
  vm_size_t size = thread_count * sizeof(thread_t);
  vm_deallocate(mach_task_self(), (vm_address_t) threads, size);

You can also see the right deallocate code in XNU-test files.

Here is a sample link.

	for (unsigned int i = 0; i < th_cnt; i++) {
		test_thread_port(th_list[i], type, victim); /* polymorphic */
		kr = mach_port_deallocate(mach_task_self(), th_list[i]);
		T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "mach_port_deallocate");
	}

I can make a pull request if you confirm this needs to be fixed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions