|
|
launchd heap corruption due to unchecked strcpy in init_session MIG ipc | |||||
| Project Member Reported by ianbeer@google.com, Apr 4 2014 | Back to list | |||||
MIG ipc routine:
routine
init_session(
j : job_t;
session : name_t;
asport : mach_port_t
);
Implementation:
core.c:
kern_return_t
job_mig_init_session(job_t j, name_t session_type, mach_port_t asport)
{
...
if (j->mgr->session_initialized) {
job_log(j, LOG_ERR, "Tried to initialize an already setup session!");
kr = BOOTSTRAP_NOT_PRIVILEGED; <-- even if the session is already initialized there's no early return here, it will still hit the strcpy
}
...
jobmgr_log(j->mgr, LOG_DEBUG, "Initializing as %s", session_type);
strcpy(j->mgr->name_init, session_type); <-- unchecked strcpy
The buffer which is being copied into is allocated here:
jobmgr_t
jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name, bool skip_init, mach_port_t asport)
{
job_t bootstrapper = NULL;
jobmgr_t jmr;
...
jmr = calloc(1, sizeof(struct jobmgr_s) + (name ? (strlen(name) + 1) : NAME_MAX + 1)); <-- here
jobmgr_t is typedef'd as a pointer to a struct jobmgr_s, which has a zero-sized array at the end:
struct jobmgr_s {
...
union {
const char name[0];
char name_init[0];
};
};
It's possible to force the allocation of a new jobmgr_t with a partially controlled name field using the subset MIG ipc - this will allocate only enough space for this string in the jobmgr_s struct:
kern_return_t
job_mig_subset(job_t j, mach_port_t requestorport, mach_port_t *subsetportp)
{
int bsdepth = 0;
jobmgr_t jmr;
...
jmr = j->mgr;
...
char name[NAME_MAX];
snprintf(name, sizeof(name), "%s[%i].subset.%i", j->anonymous ? j->prog : j->label, j->p, MACH_PORT_INDEX(requestorport));
if (!job_assumes(j, (jmr = jobmgr_new(j->mgr, requestorport, MACH_PORT_NULL, false, name, true, j->asport)) != NULL)) {
This subset bootstrap port can then be passed to init_session with a longer session_type.
Project Member
Comment 1
by
ianbeer@google.com,
Apr 4 2014
,
May 12 2014
,
May 23 2014
,
Jul 3 2014
,
Jul 3 2014
,
Jul 31 2014
|
||||||
| ► Sign in to add a comment | ||||||