Esempio n. 1
0
File: main.c Progetto: Larhard/hurd
error_t
increase_priority (void)
{
  mach_port_t pset = MACH_PORT_NULL, psetcntl = MACH_PORT_NULL;
  error_t err;

  err = thread_get_assignment (mach_thread_self (), &pset);
  if (err)
    goto out;

  err = host_processor_set_priv (_hurd_host_priv, pset, &psetcntl);
  if (err)
    goto out;

  err = thread_max_priority (mach_thread_self (), psetcntl, 0);
  if (err)
    goto out;

  err = task_priority (mach_task_self (), 2, 1);

 out:
  if (MACH_PORT_VALID (pset))
    mach_port_deallocate (mach_task_self (), pset);
  if (MACH_PORT_VALID (psetcntl))
    mach_port_deallocate (mach_task_self (), psetcntl);

  return err;
}
Esempio n. 2
0
kern_return_t
  lotto_pset_port
  (mach_port_t *pset_port,
   boolean_t need_privileged)
{
  /*
   * modifies: pset_port
   * effects:  Attempts to obtain a port for the current processor set.
   *           If unable to obtain a privileged port, an ordinary port is
   *	       returned unless need_privileged is set. If successful, sets
   *	       pset_port and returns KERN_SUCCESS, otherwise KERN_FAILURE.
   *
   */

  host_t auth;
 // mach_port_t auth, pset;
  kern_return_t result;
	
  processor_set_name_t default_pset, pset;

  /* obtain priv host port */
 // auth = mach_host_priv_self();
 // if (!MACH_PORT_VALID(auth))
   // {
      /* fail if unable and need priv */
       if (need_privileged)
	return(KERN_FAILURE);
      
      /* fallback to unprivileged auth */
      auth = mach_host_self();
  //  }
  
  /* obtain default pset port */
  printf("Get Default pset for auth %d\n",auth);
  result = processor_set_default(auth, &default_pset);
  if (result != KERN_SUCCESS)
    return(result);
  
  printf("Get Default pset for auth %d\n",auth);
  /* obtain priv pset port */
  result = host_processor_set_priv(auth, default_pset, &pset);
  if (result != KERN_SUCCESS)
    {
      /* fail uf unable and need priv */
      if (need_privileged)
	return(result);

      /* fallback to default pset port */
      pset = default_pset;
    }

  /* set pset port */
  *pset_port = pset;

  /* everything OK */
  return(KERN_SUCCESS);
}
Esempio n. 3
0
/// Iterate all tasks and update/create their information.
/// @return The call returns -1 on error, 0 indicate successful completion.
static int read_tasks_table(void) 
{
     kern_return_t kr;
     processor_set_t     pset;
     task_array_t tasks;
     processor_set_name_array_t psets;
     mach_msg_type_number_t   i, j, pcnt, tcnt;

     kr = host_processor_sets(task_manager_port, &psets, &pcnt);
    if (kr != KERN_SUCCESS)
    {
          syslog(LOG_ERR, "error in host_processor_sets(): %s", mach_error_string(kr));
          return -1;
     }

     for (i = 0; i < pcnt; i++)
     {
          kr = host_processor_set_priv(task_manager_port, psets[i], &pset);
          if (kr != KERN_SUCCESS)
          {
               syslog(LOG_ERR, "error in host_processor_set_priv(): %s", mach_error_string(kr));
               return -1;
          }

          kr = processor_set_tasks(pset, &tasks, &tcnt);
          if (kr != KERN_SUCCESS)
          {
               syslog(LOG_ERR, "error in processor_set_tasks(): %s", mach_error_string(kr));
               return -1;
          }

          for (j = 0; j < tcnt; j++)
          {
               read_task_info(tasks[j]);

               kr = mach_port_deallocate(mach_task_self(), tasks[j]);
               if (kr != KERN_SUCCESS)
               {
                    syslog(LOG_WARNING, "%s, error in mach_port_deallocate(): %s", __FUNCTION__, mach_error_string(kr));
               }
          }
          kr = vm_deallocate(mach_task_self(), (vm_address_t)tasks, tcnt * sizeof(processor_set_t));
          kr = mach_port_deallocate(mach_task_self(), pset);
          kr = mach_port_deallocate(mach_task_self(), psets[i]);
     }

     kr = vm_deallocate(mach_task_self(), (vm_address_t)psets, pcnt * sizeof(processor_set_t));

     return 0;
}
Esempio n. 4
0
static task_t task_for_pid_workaround(int pid) {
	host_t myhost = mach_host_self();
	mach_port_t psDefault = 0;
	mach_port_t psDefault_control = 0;
	task_array_t tasks = NULL;
	mach_msg_type_number_t numTasks = 0;
	kern_return_t kr = -1;
	int i;

	if (pid == -1) {
		return MACH_PORT_NULL;
	}
	kr = processor_set_default (myhost, &psDefault);
	if (kr != KERN_SUCCESS) {
		return MACH_PORT_NULL;
	}
	kr = host_processor_set_priv (myhost, psDefault, &psDefault_control);
	if (kr != KERN_SUCCESS) {
//		eprintf ("host_processor_set_priv failed with error 0x%x\n", kr);
		//mach_error ("host_processor_set_priv",kr);
		return MACH_PORT_NULL;
	}
	numTasks = 0;
	kr = processor_set_tasks (psDefault_control, &tasks, &numTasks);
	if (kr != KERN_SUCCESS) {
//		eprintf ("processor_set_tasks failed with error %x\n", kr);
		return MACH_PORT_NULL;
	}
	if (pid == 0) {
		/* kernel task */
		return tasks[0];
	}
	for (i = 0; i < numTasks; i++) {
		int pid2 = -1;
		pid_for_task (i, &pid2);
		if (pid == pid2) {
			return tasks[i];
		}
	}
	return MACH_PORT_NULL;
}
Esempio n. 5
0
void
default_pager_set_policy(
	mach_port_t master_host_port)
{
	host_priority_info_data_t	host_pri_info;
	mach_port_t		default_processor_set_name;
	mach_port_t		default_processor_set;
	policy_rr_base_data_t	rr_base;
	policy_rr_limit_data_t	rr_limit;
	kern_return_t		r;
	mach_msg_type_number_t	count;
	static char here[] = "default_pager_set_policy";

	count = HOST_PRIORITY_INFO_COUNT;
	r = host_info(mach_host_self(),
		      HOST_PRIORITY_INFO,
		      (host_info_t) &host_pri_info,
		      &count);
	if (r != KERN_SUCCESS)
		dprintf(("Could not get host priority info.  Error = 0x%x\n",
			 r));

	rr_base.quantum = 0;
	rr_base.base_priority = host_pri_info.system_priority;
	rr_limit.max_priority = host_pri_info.system_priority;

	(void)processor_set_default(mach_host_self(),
				    &default_processor_set_name);
	(void)host_processor_set_priv(master_host_port,
				      default_processor_set_name,
				      &default_processor_set);

	r = task_set_policy(default_pager_self, default_processor_set,
			    POLICY_RR,
			    (policy_base_t) & rr_base, POLICY_RR_BASE_COUNT,
			    (policy_limit_t) & rr_limit, POLICY_RR_LIMIT_COUNT,
			    TRUE);
	if (r != KERN_SUCCESS)
		dprintf(("task_set_policy returned 0x%x %s\n",
			 r, mach_error_string(r)));
}
Esempio n. 6
0
/*
 *  Credits to Jonathan Levin!
 *  This function is able to "exploit" the processor_set_tasks mach trap to retrieve
 *  the kernel's mach port. This only works on systems where SIP is either disabled or
 *  not present at all.
 *  If you want to use an alternative method to read from kernel memory, try with enabling
 *  /dev/kmem and read from that device.
 *
 *  Note that code in this project is tuned to read directly from kernel task, hence you
 *  just need to disable SIP and you're good to go, instead of rewriting code to support
 *  /dev/kmem.
 */
mach_port_t task_for_pid_workaround(int Pid)
{

    host_t        myhost = mach_host_self();
    mach_port_t   psDefault;
    mach_port_t   psDefault_control;

    task_array_t  tasks;
    mach_msg_type_number_t numTasks;
    int i;

    kern_return_t kr;

    kr = processor_set_default(myhost, &psDefault);

    kr = host_processor_set_priv(myhost, psDefault, &psDefault_control);
    if (kr != KERN_SUCCESS) {
        fprintf(stderr, "host_processor_set_priv failed with error %x\n", kr);
        mach_error("host_processor_set_priv",kr);
        exit(1);
    }

    kr = processor_set_tasks(psDefault_control, &tasks, &numTasks);
    if (kr != KERN_SUCCESS) {
        fprintf(stderr,"processor_set_tasks failed with error %x\n",kr);
        exit(1);
    }

    for (i = 0; i < numTasks; i++)
    {
        int pid;
        pid_for_task(tasks[i], &pid);
        if (pid == Pid) return (tasks[i]);
    }

    return (MACH_PORT_NULL);
}
Esempio n. 7
0
bool SysInfo::GetAllProcess()
{
	kern_return_t	error;
	processor_set_t	*psets, pset;
	task_t		*tasks;
	unsigned	i, j, pcnt, tcnt;
	
	m_nTotalTime = 0;
	host_priv_t libtop_port = mach_host_self();

	// 必须获得系统root权限才能访问所有process list,下面这段代码不能获得,暂用pxl制作包来解决权限问题
	host_t myhost = mach_host_self();
	processor_set_name_t p_default_set;
	processor_set_t p_default_set_control;
	/* get the default processor set */
	error = processor_set_default(myhost, &p_default_set);
	if (KERN_SUCCESS != error)
	{
		printf("Error in processor_set_default(): %s \n",mach_error_string(error));

		char szInfo[256] = { 0 };
		snprintf(szInfo, sizeof(szInfo) - 1, "processor_set_default error");
		LogMsg(szInfo);
	}
	/* get the control port for this processor set */
	error = host_processor_set_priv(myhost, p_default_set, &p_default_set_control);
	if (KERN_SUCCESS != error)
	{
	}

	error = host_processor_sets(libtop_port, &psets, &pcnt);
	if (error != KERN_SUCCESS) {
		GetProcessInfo(mach_task_self());
		return TRUE;
	}
	
	m_pInfoList.clear();

	for (i = 0; i < pcnt; i++) {
		error = host_processor_set_priv(libtop_port, psets[i], &pset);
		if (error != KERN_SUCCESS) {
			printf("Error in host_processor_set_priv(): %s \n",mach_error_string(error));
			
			char szInfo[256] = { 0 };
			snprintf(szInfo, sizeof(szInfo) - 1, "host_processor_set_priv error");
			LogMsg(szInfo);

			return true;
		}
		
		error = processor_set_tasks(pset, &tasks, &tcnt);
		if (error != KERN_SUCCESS) {
			printf("Error in processor_set_tasks(): %s \n",mach_error_string(error));
			
			char szInfo[256] = { 0 };
			snprintf(szInfo, sizeof(szInfo) - 1, "processor_set_tasks error");
			LogMsg(szInfo);

			return true;
		}
		
		for (j = 0; j < tcnt; j++) {
			if (GetProcessInfo(tasks[j])) 
			{
				return true;
			}
			mach_port_deallocate(mach_task_self(),tasks[j]);
		}
		error = vm_deallocate((vm_map_t)mach_task_self(),(vm_address_t)tasks, tcnt * sizeof(task_t));
		if (error != KERN_SUCCESS) {
			printf("Error in vm_deallocate(): %s \n",mach_error_string(error));
			return true;
		}
		if ((error = mach_port_deallocate(mach_task_self(),pset)) != KERN_SUCCESS
		    || (error = mach_port_deallocate(mach_task_self(),psets[i])) != KERN_SUCCESS) 
		{
			printf("Error in mach_port_deallocate(): %s \n",mach_error_string(error));
			return true;
		}
	}
	
	error = vm_deallocate((vm_map_t)mach_task_self(),(vm_address_t)psets, pcnt * sizeof(processor_set_t));
	if (error != KERN_SUCCESS) {
		printf("Error in vm_deallocate(): %s \n",mach_error_string(error));
		return true;
	}
	
	return false;
}
Esempio n. 8
0
int
main(int argc, char ** argv)
{
    int option = 0;
    struct config cfg = {0};

    header();
    if (argc < 2)
    {
        usage();
    }
        
    while( (option=getopt(argc,argv,"ha:Aco:Ci:rRs")) != -1 )
    {
        switch(option)
        {
            case 'h':
                usage();
                exit(1);
            case 'a':
                cfg.interrupt = atoi(optarg);
                break;
            case 'A': 
                cfg.show_all_descriptors = 1;
                break;
            case 'c': 
                cfg.create_file_archive = 1;
                break;
            case 'r': 
                cfg.read_file_archive = 1;
                break;
            case 'R': 
                cfg.restore_idt = 1;
                break;
            case 'o':
                if(strlen(optarg) > MAXPATHLEN - 1)
                {
                    ERROR_MSG("File name too long.");
                    return -1;
                }
                strncpy(cfg.out_filename, optarg, sizeof(cfg.out_filename));
                break;
            case 'C': 
                cfg.compare_idt = 1;
                break;
            case 'i': 
                if(strlen(optarg) > MAXPATHLEN - 1)
                {
                    ERROR_MSG("File name too long.");
                    return -1;
                }
                strncpy(cfg.in_filename, optarg, sizeof(cfg.in_filename));
                break;
            case 's': 
                cfg.resolve = 1;
                break;
        }
    }
    OUTPUT_MSG("");
    
    if (getuid() != 0)
    {
        ERROR_MSG("This program needs to be run as root!");
        return -1;
    }
    
    cfg.kernel_type = get_kernel_type();
    if (cfg.kernel_type == -1)
    {
        ERROR_MSG("Unable to retrieve kernel type.");
        return -1;
    }
    else if (cfg.kernel_type == X86)
    {
        ERROR_MSG("32 bits kernels not supported.");
        return -1;
    }
    
    cfg.idt_addr = get_addr_idt(cfg.kernel_type);
    cfg.idt_size = get_size_idt();
    cfg.idt_entries = cfg.idt_size / sizeof(struct descriptor_idt);
    /* we need to populate the size variable else syscall fails */
    cfg.kaslr_size = sizeof(cfg.kaslr_size);
    get_kaslr_slide(&cfg.kaslr_size, &cfg.kaslr_slide);
    
    OUTPUT_MSG("[INFO] Kaslr slide is 0x%llx", cfg.kaslr_slide);
    OUTPUT_MSG("[INFO] IDT base address is: 0x%llx", cfg.idt_addr);
    OUTPUT_MSG("[INFO] IDT size: 0x%x\n", cfg.idt_size);

    /* test if we can read kernel memory using processor_set_tasks() vulnerability */
    /* vulnerability presented at BlackHat Asia 2014 by Ming-chieh Pan, Sung-ting Tsai. */
    /* also described in Mac OS X and iOS Internals, page 387 */
    host_t host_port = mach_host_self();
    mach_port_t proc_set_default = 0;
    mach_port_t proc_set_default_control = 0;
    task_array_t all_tasks = NULL;
    mach_msg_type_number_t all_tasks_cnt = 0;
    kern_return_t kr = 0;
    int valid_kernel_port = 0;
    
    kr = processor_set_default(host_port, &proc_set_default);
    if (kr == KERN_SUCCESS)
    {
        kr = host_processor_set_priv(host_port, proc_set_default, &proc_set_default_control);
        if (kr == KERN_SUCCESS)
        {
            kr = processor_set_tasks(proc_set_default_control, &all_tasks, &all_tasks_cnt);
            if (kr == KERN_SUCCESS)
            {
                DEBUG_MSG("Found valid kernel port using processor_set_tasks() vulnerability!");
                cfg.kernel_port = all_tasks[0];
                valid_kernel_port = 1;
            }
        }
    }
    /* if we can't use the vulnerability then try /dev/kmem */
    if (valid_kernel_port == 0)
    {
        if( (cfg.fd_kmem = open("/dev/kmem",O_RDWR)) == -1 )
        {
            ERROR_MSG("Error while opening /dev/kmem. Is /dev/kmem enabled?");
            ERROR_MSG("Verify that /Library/Preferences/SystemConfiguration/com.apple.Boot.plist has kmem=1 parameter configured.");
            return -1;
        }
    }
    
    if (cfg.resolve == 1)
    {
        retrieve_kernel_symbols(&cfg);
    }
    
    if(cfg.interrupt >= 0 || cfg.show_all_descriptors == 1)
    {
        show_idt_info(&cfg);
    }
    if(cfg.create_file_archive == 1)
    {
        create_idt_archive(&cfg);
    }
    if(cfg.read_file_archive == 1)
    {
        read_idt_archive(&cfg);
    }
    if(cfg.compare_idt == 1)
    {
        compare_idt(&cfg);
    }
    if(cfg.restore_idt == 1)
    {
        compare_idt(&cfg);
    }
    return 0;
}
Esempio n. 9
0
static void *
intrthread(void *arg)
{
	struct irq *irq = arg;
	mach_port_t delivery_port;
        mach_port_t pset, psetcntl;
	int ret;
	int val;

	rumpuser_component_kthread();

	ret = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
				&delivery_port);
	if (ret)
		err(ret, "mach_port_allocate");

	ret = thread_get_assignment (mach_thread_self (), &pset);
	if (ret)
		err(ret, "thread_get_assignment");

	ret = host_processor_set_priv (master_host, pset, &psetcntl);
	if (ret)
		err(ret, "host_processor_set_priv");

	thread_max_priority (mach_thread_self (), psetcntl, 0);
	ret = thread_priority (mach_thread_self (), RUMP_IRQ_PRIO, 0);
	if (ret)
		err(ret, "thread_priority");

	ret = device_intr_register(master_device, irq->intrline,
					0, 0x04000000, delivery_port,
					MACH_MSG_TYPE_MAKE_SEND);
	if (ret) {
		warn("device_intr_register");
		return 0;
	}

	device_intr_enable (master_device, irq->intrline, TRUE);

        int irq_server (mach_msg_header_t *inp, mach_msg_header_t *outp) {
                mach_intr_notification_t *intr_header = (mach_intr_notification_t *) inp;

                ((mig_reply_header_t *) outp)->RetCode = MIG_NO_REPLY;
                if (inp->msgh_id != MACH_INTR_NOTIFY)
                        return 0;

                /* It's an interrupt not for us. It shouldn't happen. */
                if (intr_header->line != irq->intrline) {
                        printf ("We get interrupt %d, %d is expected",
                                       intr_header->line, irq->intrline);
                        return 1;
                }

		rumpcomp_pci_confread(0, irq->device, 0, 0x04, &val);
		if (val & 0x400) {
			printf("interrupt disabled!\n");
			val &= ~0x400;
			rumpcomp_pci_confwrite(0, irq->device, 0, 0x04, val);
		}

		rumpuser_component_schedule(NULL);
		irq->handler(irq->data);
		rumpuser_component_unschedule();

                /* If the irq has been disabled by the linux device,
                 * we don't need to reenable the real one. */
                device_intr_enable (master_device, irq->intrline, TRUE);

                return 1;
        }
Esempio n. 10
0
int
main (int argc, char **argv, char **envp)
{
  mach_port_t boot;
  error_t err;
  mach_port_t pset, psetcntl;
  void *genport;
  process_t startup_port;
  struct argp argp = { 0, 0, 0, "Hurd process server" };

  argp_parse (&argp, argc, argv, 0, 0, 0);

  initialize_version_info ();

  err = task_get_bootstrap_port (mach_task_self (), &boot);
  assert_perror (err);
  if (boot == MACH_PORT_NULL)
    error (2, 0, "proc server can only be run by init during boot");

  proc_bucket = ports_create_bucket ();
  proc_class = ports_create_class (0, 0);
  generic_port_class = ports_create_class (0, 0);
  exc_class = ports_create_class (exc_clean, 0);
  ports_create_port (generic_port_class, proc_bucket,
		     sizeof (struct port_info), &genport);
  generic_port = ports_get_right (genport);

  /* Create the initial proc object for init (PID 1).  */
  startup_proc = create_startup_proc ();

  /* Create our own proc object (we are PID 0).  */
  self_proc = allocate_proc (mach_task_self ());
  assert (self_proc);

  complete_proc (self_proc, 0);

  startup_port = ports_get_send_right (startup_proc);
  err = startup_procinit (boot, startup_port, &startup_proc->p_task,
			  &authserver, &master_host_port, &master_device_port);
  assert_perror (err);
  mach_port_deallocate (mach_task_self (), startup_port);

  mach_port_mod_refs (mach_task_self (), authserver, MACH_PORT_RIGHT_SEND, 1);
  _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], authserver);
  mach_port_deallocate (mach_task_self (), boot);

  proc_death_notify (startup_proc);
  add_proc_to_hash (startup_proc); /* Now that we have the task port.  */

  /* Set our own argv and envp locations.  */
  self_proc->p_argv = (vm_address_t) argv;
  self_proc->p_envp = (vm_address_t) envp;

  /* Give ourselves good scheduling performance, because we are so
     important. */
  err = thread_get_assignment (mach_thread_self (), &pset);
  assert_perror (err);
  err = host_processor_set_priv (master_host_port, pset, &psetcntl);
  assert_perror (err);
  thread_max_priority (mach_thread_self (), psetcntl, 0);
  assert_perror (err);
  err = task_priority (mach_task_self (), 2, 1);
  assert_perror (err);

  mach_port_deallocate (mach_task_self (), pset);
  mach_port_deallocate (mach_task_self (), psetcntl);

  {
    /* Get our stderr set up to print on the console, in case we have
       to panic or something.  */
    mach_port_t cons;
    error_t err;
    err = device_open (master_device_port, D_READ|D_WRITE, "console", &cons);
    assert_perror (err);
    stdin = mach_open_devstream (cons, "r");
    stdout = stderr = mach_open_devstream (cons, "w");
    mach_port_deallocate (mach_task_self (), cons);
  }

  while (1)
    ports_manage_port_operations_multithread (proc_bucket,
					      message_demuxer,
					      0, 0, 0);
}