From 975bbe7c48a3c855825d6e87052055d200071fc7 Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Mon, 12 Aug 2013 05:27:40 -0400 Subject: [PATCH] Ensure memory allocation results are checked throughout the code. Signed-off-by: Kris Van Hees --- dtrace/dtrace_actdesc.c | 9 ++- dtrace/dtrace_dev.c | 36 +++++++---- dtrace/dtrace_dif.c | 27 ++++----- dtrace/dtrace_dof.c | 93 ++++++++++++++++++++++++----- dtrace/dtrace_ecb.c | 27 ++++++--- dtrace/dtrace_enable.c | 19 +++--- dtrace/dtrace_fmt.c | 16 +++-- dtrace/dtrace_hash.c | 39 ++++++++---- dtrace/dtrace_predicate.c | 7 ++- dtrace/dtrace_ptofapi.c | 24 ++++++-- dtrace/dtrace_state.c | 60 ++++++++++++------- dtrace/fasttrap_dev.c | 93 ++++++++++++++++++++++------- dtrace/include/dtrace/dtrace_impl.h | 2 +- dtrace/profile_dev.c | 10 +++- dtrace/sdt_dev.c | 27 +++++++-- 15 files changed, 358 insertions(+), 131 deletions(-) diff --git a/dtrace/dtrace_actdesc.c b/dtrace/dtrace_actdesc.c index 8ef54e33b0a8..86f66a2131de 100644 --- a/dtrace/dtrace_actdesc.c +++ b/dtrace/dtrace_actdesc.c @@ -44,7 +44,10 @@ dtrace_actdesc_t *dtrace_actdesc_create(dtrace_actkind_t kind, uint32_t ntuple, (arg == 0 && kind == DTRACEACT_PRINTA)); #endif - act = kzalloc(sizeof (dtrace_actdesc_t), GFP_KERNEL); + act = vzalloc(sizeof (dtrace_actdesc_t)); + if (act == NULL) + return NULL; + act->dtad_kind = kind; act->dtad_ntuple = ntuple; act->dtad_uarg = uarg; @@ -86,8 +89,8 @@ void dtrace_actdesc_release(dtrace_actdesc_t *act, dtrace_vstate_t *vstate) #endif if (str != NULL) - kfree(str); + vfree(str); } - kfree(act); + vfree(act); } diff --git a/dtrace/dtrace_dev.c b/dtrace/dtrace_dev.c index 127f17520060..46f026979fe4 100644 --- a/dtrace/dtrace_dev.c +++ b/dtrace/dtrace_dev.c @@ -254,9 +254,11 @@ static long dtrace_ioctl(struct file *file, size = sizeof(dtrace_eprobedesc_t) + (epdesc.dtepd_nrecs * sizeof(dtrace_recdesc_t)); - buf = kmalloc(size, GFP_KERNEL); - dest = buf; + buf = vmalloc(size); + if (buf == NULL) + return -ENOMEM; + dest = buf; memcpy(dest, &epdesc, sizeof(epdesc)); dest += offsetof(dtrace_eprobedesc_t, dtepd_rec[0]); @@ -275,11 +277,11 @@ static long dtrace_ioctl(struct file *file, if (copy_to_user(argp, buf, (uintptr_t)(dest - (uint8_t *)buf)) != 0) { - kfree(buf); + vfree(buf); return -EFAULT; } - kfree(buf); + vfree(buf); return 0; } @@ -348,9 +350,11 @@ static long dtrace_ioctl(struct file *file, size = sizeof(dtrace_aggdesc_t) + (aggdesc.dtagd_nrecs * sizeof(dtrace_recdesc_t)); - buf = kmalloc(size, GFP_KERNEL); - dest = buf; + buf = vmalloc(size); + if (buf == NULL) + return -ENOMEM; + dest = buf; memcpy(dest, &aggdesc, sizeof(aggdesc)); dest += offsetof(dtrace_aggdesc_t, dtagd_rec[0]); @@ -381,11 +385,11 @@ static long dtrace_ioctl(struct file *file, if (copy_to_user(argp, buf, (uintptr_t)(dest - (uint8_t *)buf)) != 0) { - kfree(buf); + vfree(buf); return -EFAULT; } - kfree(buf); + vfree(buf); return 0; } @@ -665,6 +669,8 @@ static long dtrace_ioctl(struct file *file, mutex_lock(&dtrace_lock); dof = dtrace_dof_create(state); mutex_unlock(&dtrace_lock); + if (dof == NULL) + return -ENOMEM; len = min(hdr.dofh_loadsz, dof->dofh_loadsz); rval = copy_to_user(argp, dof, len); @@ -1286,13 +1292,17 @@ static void dtrace_toxrange_add(uintptr_t base, uintptr_t limit) dtrace_toxranges_max <<= 1; nsize = dtrace_toxranges_max * sizeof(dtrace_toxrange_t); - range = kzalloc(nsize, GFP_KERNEL); + range = vzalloc(nsize); + if (range == NULL) { + pr_warn("Failed to add toxic range: out of memory\n"); + return; + } if (dtrace_toxrange != NULL) { ASSERT(osize != 0); memcpy(range, dtrace_toxrange, osize); - kfree(dtrace_toxrange); + vfree(dtrace_toxrange); } dtrace_toxrange = range; @@ -1470,6 +1480,12 @@ int dtrace_dev_init(void) dtrace_helptrace_buffer = vzalloc(dtrace_helptrace_bufsize); dtrace_helptrace_next = 0; + + if (dtrace_helptrace_buffer == NULL) { + pr_warn("Cannot allocate helptrace buffer; " + "disabling dtrace_helptrace\n"); + dtrace_helptrace_enabled = 0; + } } #ifdef FIXME diff --git a/dtrace/dtrace_dif.c b/dtrace/dtrace_dif.c index ee8f97b03ddb..c1d56a2b154b 100644 --- a/dtrace/dtrace_dif.c +++ b/dtrace/dtrace_dif.c @@ -858,12 +858,12 @@ void dtrace_difo_init(dtrace_difo_t *dp, dtrace_vstate_t *vstate) osz = otlocals * sizeof(dtrace_difv_t); nsz = ntlocals * sizeof(dtrace_difv_t); - tlocals = kzalloc(nsz, GFP_KERNEL); + tlocals = vzalloc(nsz); if (osz != 0) { memcpy(tlocals, vstate->dtvs_tlocals, osz); - kfree(vstate->dtvs_tlocals); + vfree(vstate->dtvs_tlocals); } vstate->dtvs_tlocals = tlocals; @@ -911,11 +911,11 @@ void dtrace_difo_init(dtrace_difo_t *dp, dtrace_vstate_t *vstate) oldsize = oldsvars * sizeof(dtrace_statvar_t *); newsize = newsvars * sizeof(dtrace_statvar_t *); - statics = kzalloc(newsize, GFP_KERNEL); + statics = vzalloc(newsize); if (oldsize != 0) { memcpy(statics, *svarp, oldsize); - kfree(*svarp); + vfree(*svarp); } *svarp = statics; @@ -923,13 +923,12 @@ void dtrace_difo_init(dtrace_difo_t *dp, dtrace_vstate_t *vstate) } if ((svar = (*svarp)[id]) == NULL) { - svar = kzalloc(sizeof(dtrace_statvar_t), GFP_KERNEL); + svar = vzalloc(sizeof(dtrace_statvar_t)); svar->dtsv_var = *v; if ((svar->dtsv_size = dsize) != 0) { svar->dtsv_data = - (uint64_t)(uintptr_t)kzalloc( - dsize, GFP_KERNEL); + (uint64_t)(uintptr_t)vzalloc(dsize); } (*svarp)[id] = svar; @@ -988,18 +987,18 @@ void dtrace_difo_destroy(dtrace_difo_t *dp, dtrace_vstate_t *vstate) if (svar->dtsv_size != 0) { ASSERT((void *)(uintptr_t)svar->dtsv_data != NULL); - kfree((void *)(uintptr_t)svar->dtsv_data); + vfree((void *)(uintptr_t)svar->dtsv_data); } - kfree(svar); + vfree(svar); svarp[id] = NULL; } - kfree(dp->dtdo_buf); - kfree(dp->dtdo_inttab); - kfree(dp->dtdo_strtab); - kfree(dp->dtdo_vartab); - kfree(dp); + vfree(dp->dtdo_buf); + vfree(dp->dtdo_inttab); + vfree(dp->dtdo_strtab); + vfree(dp->dtdo_vartab); + vfree(dp); } void dtrace_difo_release(dtrace_difo_t *dp, dtrace_vstate_t *vstate) diff --git a/dtrace/dtrace_dof.c b/dtrace/dtrace_dof.c index 58c67a0523e8..f9723aeda486 100644 --- a/dtrace/dtrace_dof.c +++ b/dtrace/dtrace_dof.c @@ -78,7 +78,10 @@ dof_hdr_t *dtrace_dof_create(dtrace_state_t *state) ASSERT(MUTEX_HELD(&dtrace_lock)); - dof = kmalloc(len, GFP_KERNEL); + dof = vmalloc(len); + if (dof == NULL) + return NULL; + dof->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0; dof->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1; dof->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2; @@ -155,11 +158,15 @@ dof_hdr_t *dtrace_dof_copyin(void __user *argp, int *errp) return NULL; } - dof = kmalloc(hdr.dofh_loadsz, GFP_KERNEL); + dof = vmalloc(hdr.dofh_loadsz); + if (dof == NULL) { + *errp = -ENOMEM; + return NULL; + } if (copy_from_user(dof, argp, hdr.dofh_loadsz) != 0 || dof->dofh_loadsz != hdr.dofh_loadsz) { - kfree(dof); + vfree(dof); *errp = -EFAULT; return NULL; } @@ -215,7 +222,11 @@ dof_hdr_t *dtrace_dof_property(const char *name) return NULL; } - dof = kmalloc(loadsz, GFP_KERNEL); + dof = vmalloc(loadsz); + if (dof == NULL) { + dtrace_dof_error(NULL, "out-of-memory"); + return NULL; + } memcpy(dof, buf, loadsz); #ifdef FIXME ddi_prop_free(buf); @@ -226,7 +237,7 @@ dof_hdr_t *dtrace_dof_property(const char *name) void dtrace_dof_destroy(dof_hdr_t *dof) { - kfree(dof); + vfree(dof); } /* @@ -413,7 +424,11 @@ static dtrace_difo_t *dtrace_dof_difo(dof_hdr_t *dof, dof_sec_t *sec, dofd = (dof_difohdr_t *)(uintptr_t)(daddr + sec->dofs_offset); n = (sec->dofs_size - sizeof(*dofd)) / sizeof(dof_secidx_t) + 1; - dp = kzalloc(sizeof(dtrace_difo_t), GFP_KERNEL); + dp = vzalloc(sizeof(dtrace_difo_t)); + if (dp == NULL) { + dtrace_dof_error(dof, "out-of-memory"); + return NULL; + } dp->dtdo_rtype = dofd->dofd_rtype; for (l = 0; l < n; l++) { @@ -471,7 +486,11 @@ static dtrace_difo_t *dtrace_dof_difo(dof_hdr_t *dof, dof_sec_t *sec, } *lenp = subsec->dofs_size; - *bufp = kmalloc(subsec->dofs_size, GFP_KERNEL); + *bufp = vmalloc(subsec->dofs_size); + if (*bufp == NULL) { + dtrace_dof_error(dof, "out-of-memory"); + goto err; + } memcpy(*bufp, (char *)(uintptr_t)(daddr + subsec->dofs_offset), subsec->dofs_size); @@ -527,12 +546,17 @@ static dtrace_difo_t *dtrace_dof_difo(dof_hdr_t *dof, dof_sec_t *sec, return dp; err: - kfree(dp->dtdo_buf); - kfree(dp->dtdo_inttab); - kfree(dp->dtdo_strtab); - kfree(dp->dtdo_vartab); + if (dp->dtdo_buf != NULL) + vfree(dp->dtdo_buf); + if (dp->dtdo_inttab != NULL) + vfree(dp->dtdo_inttab); + if (dp->dtdo_strtab != NULL) + vfree(dp->dtdo_strtab); + if (dp->dtdo_vartab != NULL) + vfree(dp->dtdo_vartab); + + vfree(dp); - kfree(dp); return NULL; } @@ -634,7 +658,11 @@ static dtrace_actdesc_t *dtrace_dof_actdesc(dof_hdr_t *dof, dof_sec_t *sec, } i -= desc->dofa_arg; - fmt = kmalloc(i + 1, GFP_KERNEL); + fmt = vmalloc(i + 1); + if (fmt == NULL) { + dtrace_dof_error(dof, "out-of-memory"); + goto err; + } memcpy(fmt, &str[desc->dofa_arg], i + 1); arg = (uint64_t)(uintptr_t)fmt; } else { @@ -647,6 +675,8 @@ static dtrace_actdesc_t *dtrace_dof_actdesc(dof_hdr_t *dof, dof_sec_t *sec, act = dtrace_actdesc_create(kind, desc->dofa_ntuple, desc->dofa_uarg, arg); + if (act == NULL) + goto err; if (last != NULL) last->dtad_next = act; @@ -705,7 +735,9 @@ static dtrace_ecbdesc_t *dtrace_dof_ecbdesc(dof_hdr_t *dof, dof_sec_t *sec, if (sec == NULL) return NULL; - ep = kzalloc(sizeof(dtrace_ecbdesc_t), GFP_KERNEL); + ep = vzalloc(sizeof(dtrace_ecbdesc_t)); + if (ep == NULL) + return NULL; ep->dted_uarg = ecb->dofe_uarg; desc = &ep->dted_probe; @@ -739,7 +771,7 @@ static dtrace_ecbdesc_t *dtrace_dof_ecbdesc(dof_hdr_t *dof, dof_sec_t *sec, err: if (pred != NULL) dtrace_predicate_release(pred, vstate); - kfree(ep); + vfree(ep); return NULL; } @@ -1016,6 +1048,9 @@ int dtrace_dof_slurp(dof_hdr_t *dof, dtrace_vstate_t *vstate, const cred_t *cr, if ((enab = *enabp) == NULL) enab = *enabp = dtrace_enabling_create(vstate); + if (enab == NULL) + return -1; + for (i = 0; i < dof->dofh_secnum; i++) { dof_sec_t *sec = (dof_sec_t *)(daddr + @@ -1108,8 +1143,15 @@ static dtrace_helpers_t *dtrace_helpers_create(struct task_struct *curr) ASSERT(curr->dtrace_helpers == NULL); dth = vzalloc(sizeof(dtrace_helpers_t)); + if (dth == NULL) + return NULL; + dth->dthps_actions = vzalloc(sizeof(dtrace_helper_action_t *) * DTRACE_NHELPER_ACTIONS); + if (dth->dthps_actions == NULL) { + vfree(dth); + return NULL; + } curr->dtrace_helpers = dth; dtrace_helpers++; @@ -1403,6 +1445,9 @@ static int dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep) return -ENOSPC; helper = vzalloc(sizeof(dtrace_helper_action_t)); + if (helper == NULL) + return -ENOMEM; + helper->dtha_generation = dth->dthps_generation; if ((pred = ep->dted_pred.dtpdd_predicate) != NULL) { @@ -1423,6 +1468,8 @@ static int dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep) helper->dtha_actions = vzalloc(sizeof(dtrace_difo_t *) * (helper->dtha_nactions = nactions)); + if (helper->dtha_actions == NULL) + goto err; for (act = ep->dted_action, i = 0; act != NULL; act = act->dtad_next) { dtrace_difo_hold(act->dtad_difo); @@ -1446,6 +1493,11 @@ static int dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep) err: dtrace_helper_action_destroy(helper, vstate); + if (helper->dtha_actions != NULL) + vfree(helper->dtha_actions); + else + return -ENOMEM; + return -EINVAL; } @@ -1477,6 +1529,8 @@ static int dtrace_helper_provider_add(dof_helper_t *dofhp, int gen) } hprov = vzalloc(sizeof(dtrace_helper_provider_t)); + if (hprov == NULL) + return -ENOMEM; hprov->dthp_prov = *dofhp; hprov->dthp_ref = 1; hprov->dthp_generation = gen; @@ -1500,6 +1554,10 @@ static int dtrace_helper_provider_add(dof_helper_t *dofhp, int gen) dth->dthps_provs = vzalloc(dth->dthps_maxprovs * sizeof(dtrace_helper_provider_t *)); + if (dth->dthps_provs == NULL) { + vfree(hprov); + return -ENOMEM; + } if (tmp_provs != NULL) { memcpy(dth->dthps_provs, tmp_provs, @@ -1809,6 +1867,11 @@ int dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp) if ((dth = current->dtrace_helpers) == NULL) dth = dtrace_helpers_create(current); + if (dth == NULL) { + dtrace_dof_destroy(dof); + return -1; + } + vstate = &dth->dthps_vstate; if ((rv = dtrace_dof_slurp(dof, vstate, NULL, &enab, diff --git a/dtrace/dtrace_ecb.c b/dtrace/dtrace_ecb.c index 596477c7e0af..f146d9ba851f 100644 --- a/dtrace/dtrace_ecb.c +++ b/dtrace/dtrace_ecb.c @@ -43,7 +43,10 @@ static dtrace_action_t *dtrace_ecb_aggregation_create(dtrace_ecb_t *ecb, dtrace_state_t *state = ecb->dte_state; int err; - agg = kzalloc(sizeof(dtrace_aggregation_t), GFP_KERNEL); + agg = vzalloc(sizeof(dtrace_aggregation_t)); + if (agg == NULL) + return NULL; + agg->dtag_ecb = ecb; ASSERT(DTRACEACT_ISAGG(desc->dtad_kind)); @@ -119,7 +122,7 @@ static dtrace_action_t *dtrace_ecb_aggregation_create(dtrace_ecb_t *ecb, ASSERT(ntuple != 0); err: - kfree(agg); + vfree(agg); return NULL; success: @@ -173,7 +176,7 @@ void dtrace_ecb_aggregation_destroy(dtrace_ecb_t *ecb, dtrace_action_t *act) idr_remove(&state->dts_agg_idr, agg->dtag_id); state->dts_naggs--; - kfree(agg); + vfree(agg); } static int dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc) @@ -364,7 +367,10 @@ static int dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc) } } - action = kzalloc(sizeof(dtrace_action_t), GFP_KERNEL); + action = vzalloc(sizeof(dtrace_action_t)); + if (action == NULL) + return -ENOMEM; + action->dta_rec.dtrd_size = size; } @@ -433,7 +439,7 @@ static void dtrace_ecb_action_remove(dtrace_ecb_t *ecb) if (DTRACEACT_ISAGG(act->dta_kind)) dtrace_ecb_aggregation_destroy(ecb, act); else - kfree(act); + vfree(act); } } @@ -527,7 +533,10 @@ static dtrace_ecb_t *dtrace_ecb_add(dtrace_state_t *state, ASSERT(MUTEX_HELD(&dtrace_lock)); - ecb = kzalloc(sizeof(dtrace_ecb_t), GFP_KERNEL); + ecb = vzalloc(sizeof(dtrace_ecb_t)); + if (ecb == NULL) + return NULL; + ecb->dte_predicate = NULL; ecb->dte_probe = probe; ecb->dte_size = ecb->dte_needed = sizeof(dtrace_epid_t); @@ -547,7 +556,7 @@ static dtrace_ecb_t *dtrace_ecb_add(dtrace_state_t *state, necbs = 1; } - ecbs = kcalloc(necbs, sizeof(*ecbs), GFP_KERNEL); + ecbs = vzalloc(necbs * sizeof(*ecbs)); if (oecbs != NULL) memcpy(ecbs, oecbs, state->dts_necbs * sizeof(*ecbs)); @@ -559,7 +568,7 @@ static dtrace_ecb_t *dtrace_ecb_add(dtrace_state_t *state, if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE) dtrace_sync(); - kfree(oecbs); + vfree(oecbs); } dtrace_membar_producer(); @@ -680,7 +689,7 @@ void dtrace_ecb_destroy(dtrace_ecb_t *ecb) ASSERT(state->dts_ecbs[epid - 1] == ecb); state->dts_ecbs[epid - 1] = NULL; - kfree(ecb); + vfree(ecb); } void dtrace_ecb_resize(dtrace_ecb_t *ecb) diff --git a/dtrace/dtrace_enable.c b/dtrace/dtrace_enable.c index 33e35ec92b53..fecfe9531620 100644 --- a/dtrace/dtrace_enable.c +++ b/dtrace/dtrace_enable.c @@ -39,7 +39,10 @@ dtrace_enabling_t *dtrace_enabling_create(dtrace_vstate_t *vstate) { dtrace_enabling_t *enab; - enab = kzalloc(sizeof (dtrace_enabling_t), GFP_KERNEL); + enab = vzalloc(sizeof (dtrace_enabling_t)); + if (enab == NULL) + return NULL; + enab->dten_vstate = vstate; return enab; @@ -72,9 +75,9 @@ void dtrace_enabling_add(dtrace_enabling_t *enab, dtrace_ecbdesc_t *ecb) ASSERT(enab->dten_ndesc < enab->dten_maxdesc); nsize = enab->dten_maxdesc * sizeof (dtrace_enabling_t *); - ndesc = kzalloc(nsize, GFP_KERNEL); + ndesc = vzalloc(nsize); memcpy(ndesc, enab->dten_desc, osize); - kfree(enab->dten_desc); + vfree(enab->dten_desc); enab->dten_desc = ndesc; enab->dten_desc[enab->dten_ndesc++] = ecb; @@ -92,7 +95,7 @@ static void dtrace_enabling_addlike(dtrace_enabling_t *enab, * We're going to create a new ECB description that matches the * specified ECB in every way, but has the specified probe description. */ - new = kzalloc(sizeof (dtrace_ecbdesc_t), GFP_KERNEL); + new = vzalloc(sizeof (dtrace_ecbdesc_t)); if ((pred = ecb->dted_pred.dtpdd_predicate) != NULL) dtrace_predicate_hold(pred); @@ -144,10 +147,10 @@ void dtrace_enabling_destroy(dtrace_enabling_t *enab) dtrace_actdesc_release(act, vstate); } - kfree(ep); + vfree(ep); } - kfree(enab->dten_desc); + vfree(enab->dten_desc); /* * If this was a retained enabling, decrement the dts_nretained count @@ -179,7 +182,7 @@ void dtrace_enabling_destroy(dtrace_enabling_t *enab) enab->dten_next->dten_prev = enab->dten_prev; } - kfree(enab); + vfree(enab); } int dtrace_enabling_retain(dtrace_enabling_t *enab) @@ -227,6 +230,8 @@ int dtrace_enabling_replicate(dtrace_state_t *state, dtrace_probedesc_t *match, ASSERT(strlen(match->dtpd_name) < DTRACE_NAMELEN); new = dtrace_enabling_create(&state->dts_vstate); + if (new == NULL) + return -ENOMEM; /* * Iterate over all retained enablings, looking for enablings that diff --git a/dtrace/dtrace_fmt.c b/dtrace/dtrace_fmt.c index e68562ca5cc5..408a5ab59f3e 100644 --- a/dtrace/dtrace_fmt.c +++ b/dtrace/dtrace_fmt.c @@ -35,6 +35,8 @@ uint16_t dtrace_format_add(dtrace_state_t *state, char *str) uint16_t ndx; fmt = dtrace_strdup(str); + if (fmt == NULL) + return 0; for (ndx = 0; ndx < state->dts_nformats; ndx++) { if (state->dts_formats[ndx] == NULL) { @@ -50,13 +52,19 @@ uint16_t dtrace_format_add(dtrace_state_t *state, char *str) return 0; } - ndx = state->dts_nformats++; - new = kmalloc((ndx + 1) * sizeof (char *), GFP_KERNEL); + ndx = state->dts_nformats; + new = vmalloc((ndx + 1) * sizeof (char *)); + if (new == NULL) { + kfree(fmt); + return 0; + } + + state->dts_nformats++; if (state->dts_formats != NULL) { ASSERT(ndx != 0); memcpy(new, state->dts_formats, ndx * sizeof (char *)); - kfree(state->dts_formats); + vfree(state->dts_formats); } state->dts_formats = new; @@ -98,7 +106,7 @@ void dtrace_format_destroy(dtrace_state_t *state) kfree(fmt); } - kfree(state->dts_formats); + vfree(state->dts_formats); state->dts_nformats = 0; state->dts_formats = NULL; } diff --git a/dtrace/dtrace_hash.c b/dtrace/dtrace_hash.c index d0c31ab2755a..1d6a278725a7 100644 --- a/dtrace/dtrace_hash.c +++ b/dtrace/dtrace_hash.c @@ -54,7 +54,10 @@ static uint_t dtrace_hash_str(char *p) dtrace_hash_t *dtrace_hash_create(uintptr_t stroffs, uintptr_t nextoffs, uintptr_t prevoffs) { - dtrace_hash_t *hash = kzalloc(sizeof (dtrace_hash_t), GFP_KERNEL); + dtrace_hash_t *hash = vzalloc(sizeof(dtrace_hash_t)); + + if (hash == NULL) + return NULL; hash->dth_stroffs = stroffs; hash->dth_nextoffs = nextoffs; @@ -63,13 +66,18 @@ dtrace_hash_t *dtrace_hash_create(uintptr_t stroffs, uintptr_t nextoffs, hash->dth_size = 1; hash->dth_mask = hash->dth_size - 1; - hash->dth_tab = kzalloc(hash->dth_size * - sizeof (dtrace_hashbucket_t *), GFP_KERNEL); + hash->dth_tab = vzalloc(hash->dth_size * + sizeof(dtrace_hashbucket_t *)); + + if (hash->dth_tab == NULL) { + vfree(hash); + return NULL; + } return hash; } -static void dtrace_hash_resize(dtrace_hash_t *hash) +static int dtrace_hash_resize(dtrace_hash_t *hash) { int size = hash->dth_size, i, ndx; int new_size = hash->dth_size << 1; @@ -78,7 +86,9 @@ static void dtrace_hash_resize(dtrace_hash_t *hash) ASSERT((new_size & new_mask) == 0); - new_tab = kzalloc(new_size * sizeof (void *), GFP_KERNEL); + new_tab = vzalloc(new_size * sizeof(void *)); + if (new_tab == NULL) + return -ENOMEM; for (i = 0; i < size; i++) { for (bucket = hash->dth_tab[i]; bucket != NULL; @@ -94,13 +104,15 @@ static void dtrace_hash_resize(dtrace_hash_t *hash) } } - kfree(hash->dth_tab); + vfree(hash->dth_tab); hash->dth_tab = new_tab; hash->dth_size = new_size; hash->dth_mask = new_mask; + + return 0; } -void dtrace_hash_add(dtrace_hash_t *hash, dtrace_probe_t *new) +int dtrace_hash_add(dtrace_hash_t *hash, dtrace_probe_t *new) { int hashval = DTRACE_HASHSTR(hash, new); int ndx = hashval & hash->dth_mask; @@ -113,12 +125,19 @@ void dtrace_hash_add(dtrace_hash_t *hash, dtrace_probe_t *new) } if ((hash->dth_nbuckets >> 1) > hash->dth_size) { - dtrace_hash_resize(hash); + int err = 0; + + if ((err = dtrace_hash_resize(hash)) != 0) + return err; + dtrace_hash_add(hash, new); return; } - bucket = kzalloc(sizeof (dtrace_hashbucket_t), GFP_KERNEL); + bucket = vzalloc(sizeof(dtrace_hashbucket_t)); + if (bucket == NULL) + return -ENOMEM; + bucket->dthb_next = hash->dth_tab[ndx]; hash->dth_tab[ndx] = bucket; hash->dth_nbuckets++; @@ -209,7 +228,7 @@ void dtrace_hash_remove(dtrace_hash_t *hash, dtrace_probe_t *probe) ASSERT(hash->dth_nbuckets > 0); hash->dth_nbuckets--; - kfree(bucket); + vfree(bucket); return; } diff --git a/dtrace/dtrace_predicate.c b/dtrace/dtrace_predicate.c index dc2b2ad3ae1d..01d21ab32409 100644 --- a/dtrace/dtrace_predicate.c +++ b/dtrace/dtrace_predicate.c @@ -38,7 +38,10 @@ dtrace_predicate_t *dtrace_predicate_create(dtrace_difo_t *dp) ASSERT(MUTEX_HELD(&dtrace_lock)); ASSERT(dp->dtdo_refcnt != 0); - pred = kzalloc(sizeof (dtrace_predicate_t), GFP_KERNEL); + pred = vzalloc(sizeof (dtrace_predicate_t)); + if (pred == NULL) + return NULL; + pred->dtp_difo = dp; pred->dtp_refcnt = 1; @@ -81,6 +84,6 @@ void dtrace_predicate_release(dtrace_predicate_t *pred, if (--pred->dtp_refcnt == 0) { dtrace_difo_release(dp, vstate); - kfree(pred); + vfree(pred); } } diff --git a/dtrace/dtrace_ptofapi.c b/dtrace/dtrace_ptofapi.c index 869cdfa244ae..70b30dfe1225 100644 --- a/dtrace/dtrace_ptofapi.c +++ b/dtrace/dtrace_ptofapi.c @@ -192,8 +192,14 @@ int dtrace_register(const char *name, const dtrace_pattr_t *pap, uint32_t priv, return -EINVAL; } - provider = kzalloc(sizeof (dtrace_provider_t), GFP_KERNEL); + provider = vzalloc(sizeof (dtrace_provider_t)); + if (provider == NULL) + return -ENOMEM; provider->dtpv_name = dtrace_strdup(name); + if (provider->dtpv_name == NULL) { + vfree(provider); + return -ENOMEM; + } provider->dtpv_attr = *pap; provider->dtpv_priv.dtpp_flags = priv; @@ -492,7 +498,7 @@ int dtrace_unregister(dtrace_provider_id_t id) } kfree(old->dtpv_name); - kfree(old); + vfree(old); return 0; } @@ -620,9 +626,15 @@ int dtrace_meta_register(const char *name, const dtrace_mops_t *mops, return -EINVAL; } - meta = kzalloc(sizeof(dtrace_meta_t), GFP_KERNEL); + meta = vzalloc(sizeof(dtrace_meta_t)); + if (meta == NULL) + return -ENOMEM; meta->dtm_mops = *mops; - meta->dtm_name = kmalloc(strlen(name) + 1, GFP_KERNEL); + meta->dtm_name = vmalloc(strlen(name) + 1); + if (meta->dtm_name == NULL) { + vfree(meta); + return -ENOMEM; + } strcpy(meta->dtm_name, name); meta->dtm_arg = arg; @@ -696,8 +708,8 @@ int dtrace_meta_unregister(dtrace_meta_provider_id_t id) mutex_unlock(&dtrace_lock); mutex_unlock(&dtrace_meta_lock); - kfree(old->dtm_name); - kfree(old); + vfree(old->dtm_name); + vfree(old); return 0; } diff --git a/dtrace/dtrace_state.c b/dtrace/dtrace_state.c index f79008ed4efa..1f1377edd90e 100644 --- a/dtrace/dtrace_state.c +++ b/dtrace/dtrace_state.c @@ -159,7 +159,7 @@ int dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) { size_t hashsize, maxper, min, chunksize = dstate->dtds_chunksize; - void *base; + void *base, *percpu; uintptr_t limit; dtrace_dynvar_t *dvar, *next, *start; int i; @@ -175,12 +175,18 @@ int dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) if (size < (min = dstate->dtds_chunksize + sizeof (dtrace_dynhash_t))) size = min; - if ((base = dtrace_vzalloc_try(size)) == NULL) + base = dtrace_vzalloc_try(size); + if (base == NULL) return -ENOMEM; + percpu = kmem_cache_alloc(dtrace_state_cache, GFP_KERNEL); + if (percpu == NULL) { + vfree(base); + return -ENOMEM; + } dstate->dtds_size = size; dstate->dtds_base = base; - dstate->dtds_percpu = kmem_cache_alloc(dtrace_state_cache, GFP_KERNEL); + dstate->dtds_percpu = percpu; memset(dstate->dtds_percpu, 0, NR_CPUS * sizeof (dtrace_dstate_percpu_t)); @@ -273,15 +279,15 @@ void dtrace_vstate_fini(dtrace_vstate_t *vstate) ASSERT((vstate->dtvs_nglobals == 0) ^ (vstate->dtvs_globals != NULL)); if (vstate->dtvs_nglobals > 0) - kfree(vstate->dtvs_globals); + vfree(vstate->dtvs_globals); if (vstate->dtvs_ntlocals > 0) - kfree(vstate->dtvs_tlocals); + vfree(vstate->dtvs_tlocals); ASSERT((vstate->dtvs_nlocals == 0) ^ (vstate->dtvs_locals != NULL)); if (vstate->dtvs_nlocals > 0) - kfree(vstate->dtvs_locals); + vfree(vstate->dtvs_locals); } static void dtrace_state_clean(dtrace_state_t *state) @@ -330,7 +336,9 @@ dtrace_state_t *dtrace_state_create(struct file *file) dtrace_state_t *state; dtrace_optval_t *opt; int bufsize = NR_CPUS * sizeof (dtrace_buffer_t), i; +#ifdef FIXME const cred_t *cr = file->f_cred; +#endif int err; dtrace_aggid_t aggid; @@ -338,12 +346,23 @@ dtrace_state_t *dtrace_state_create(struct file *file) ASSERT(MUTEX_HELD(&cpu_lock)); state = kzalloc(sizeof (dtrace_state_t), GFP_KERNEL); + if (state == NULL) + return NULL; + state->dts_epid = DTRACE_EPIDNONE + 1; - /* state->dts_dev = NULL; -- FIXME: Do we even need this? */ - state->dts_buffer = kzalloc(NR_CPUS * sizeof (dtrace_buffer_t), - GFP_KERNEL); - state->dts_buffer = kzalloc(bufsize, GFP_KERNEL); - state->dts_aggbuffer = kzalloc(bufsize, GFP_KERNEL); + state->dts_buffer = vzalloc(bufsize); + if (state->dts_buffer == NULL) { + vfree(state); + return NULL; + } + + state->dts_aggbuffer = vzalloc(bufsize); + if (state->dts_aggbuffer == NULL) { + vfree(state->dts_buffer); + vfree(state); + return NULL; + } + idr_init(&state->dts_agg_idr); state->dts_naggs = 0; state->dts_cleaner = 0; @@ -529,7 +548,6 @@ static int dtrace_state_buffer(dtrace_state_t *state, dtrace_buffer_t *buf, } rval = dtrace_buffer_alloc(buf, size, flags, cpu); - if (rval != -ENOMEM) { opt[which] = size; return rval; @@ -634,7 +652,7 @@ int dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) goto out; } - spec = kzalloc(nspec * sizeof(dtrace_speculation_t), GFP_KERNEL); + spec = vzalloc(nspec * sizeof(dtrace_speculation_t)); if (spec == NULL) { rval = -ENOMEM; goto out; @@ -644,7 +662,7 @@ int dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) state->dts_nspeculations = (int)nspec; for (i = 0; i < nspec; i++) { - if ((buf = kzalloc(bufsize, GFP_KERNEL)) == NULL) { + if ((buf = vzalloc(bufsize)) == NULL) { rval = -ENOMEM; goto err; } @@ -845,10 +863,10 @@ err: break; dtrace_buffer_free(buf); - kfree(buf); + vfree(buf); } - kfree(spec); + vfree(spec); state->dts_nspeculations = 0; state->dts_speculations = NULL; @@ -1051,7 +1069,7 @@ void dtrace_state_destroy(dtrace_state_t *state) dtrace_dstate_fini(&vstate->dtvs_dynvars); dtrace_vstate_fini(vstate); - kfree(state->dts_ecbs); + vfree(state->dts_ecbs); /* * If there were aggregations allocated, they should have been cleaned @@ -1060,13 +1078,13 @@ void dtrace_state_destroy(dtrace_state_t *state) idr_remove_all(&state->dts_agg_idr); idr_destroy(&state->dts_agg_idr); - kfree(state->dts_buffer); - kfree(state->dts_aggbuffer); + vfree(state->dts_buffer); + vfree(state->dts_aggbuffer); for (i = 0; i < nspec; i++) - kfree(spec[i].dtsp_buffer); + vfree(spec[i].dtsp_buffer); - kfree(spec); + vfree(spec); dtrace_format_destroy(state); } diff --git a/dtrace/fasttrap_dev.c b/dtrace/fasttrap_dev.c index e5a1d4271dd4..a1030e79c986 100644 --- a/dtrace/fasttrap_dev.c +++ b/dtrace/fasttrap_dev.c @@ -824,16 +824,22 @@ void fasttrap_meta_create_probe(void *arg, void *parg, ntps = dhpb->dthpb_noffs + dhpb->dthpb_nenoffs; ASSERT(ntps > 0); - atomic_add(ntps, &fasttrap_total); + pp = vzalloc(offsetof(fasttrap_probe_t, ftp_tps[ntps])); + if (pp == NULL) { + pr_warn("Unable to create probe %s: out-of-memory\n", + dhpb->dthpb_name); + mutex_unlock(&provider->ftp_cmtx); + return; + } + atomic_add(ntps, &fasttrap_total); if (atomic_read(&fasttrap_total) > fasttrap_max) { + vfree(pp); atomic_add(-ntps, &fasttrap_total); mutex_unlock(&provider->ftp_cmtx); return; } - pp = kzalloc(offsetof(fasttrap_probe_t, ftp_tps[ntps]), GFP_KERNEL); - pp->ftp_prov = provider; pp->ftp_pid = provider->ftp_pid; pp->ftp_ntps = ntps; @@ -845,7 +851,9 @@ void fasttrap_meta_create_probe(void *arg, void *parg, * First create a tracepoint for each actual point of interest. */ for (i = 0; i < dhpb->dthpb_noffs; i++) { - tp = kzalloc(sizeof(fasttrap_tracepoint_t), GFP_KERNEL); + tp = vzalloc(sizeof(fasttrap_tracepoint_t)); + if (tp == NULL) + goto fail; tp->ftt_proc = provider->ftp_proc; tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_offs[i]; @@ -864,7 +872,9 @@ void fasttrap_meta_create_probe(void *arg, void *parg, * Then create a tracepoint for each is-enabled point. */ for (j = 0; i < ntps; i++, j++) { - tp = kzalloc(sizeof(fasttrap_tracepoint_t), GFP_KERNEL); + tp = vzalloc(sizeof(fasttrap_tracepoint_t)); + if (tp == NULL) + goto fail; tp->ftt_proc = provider->ftp_proc; tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_enoffs[j]; @@ -895,6 +905,18 @@ void fasttrap_meta_create_probe(void *arg, void *parg, FASTTRAP_OFFSET_AFRAMES, pp); mutex_unlock(&provider->ftp_cmtx); + return; + +fail: + pr_warn("Unable to create probe %s: out-of-memory\n", + dhpb->dthpb_name); + + for (i = 0; i < ntps; i++) + vfree(pp->ftp_tps[i].fit_tp); + + vfree(pp); + atomic_add(-ntps, &fasttrap_total); + mutex_unlock(&provider->ftp_cmtx); } static void fasttrap_proc_release(fasttrap_proc_t *proc) @@ -941,7 +963,7 @@ static void fasttrap_proc_release(fasttrap_proc_t *proc) mutex_unlock(&bucket->ftb_mtx); - kfree(fprc); + vfree(fprc); } static void fasttrap_provider_free(fasttrap_provider_t *provider) @@ -968,7 +990,7 @@ static void fasttrap_provider_free(fasttrap_provider_t *provider) fasttrap_proc_release(provider->ftp_proc); - kfree(provider); + vfree(provider); unregister_pid_provider(pid); } @@ -1002,7 +1024,10 @@ static fasttrap_proc_t *fasttrap_proc_lookup(pid_t pid) */ mutex_unlock(&bucket->ftb_mtx); - new_fprc = kzalloc(sizeof(fasttrap_proc_t), GFP_KERNEL); + new_fprc = vzalloc(sizeof(fasttrap_proc_t)); + if (new_fprc == NULL) + return NULL; + new_fprc->ftpc_pid = pid; new_fprc->ftpc_rcount = 1; atomic64_set(&new_fprc->ftpc_acount, 1); @@ -1025,7 +1050,7 @@ static fasttrap_proc_t *fasttrap_proc_lookup(pid_t pid) fprc->ftpc_rcount); mutex_unlock(&fprc->ftpc_mtx); - kfree(new_fprc); + vfree(new_fprc); return fprc; } @@ -1050,6 +1075,7 @@ static fasttrap_provider_t *fasttrap_provider_lookup(pid_t pid, const dtrace_pattr_t *pa) { fasttrap_provider_t *fp, *new_fp = NULL; + fasttrap_proc_t *proc; fasttrap_bucket_t *bucket; char provname[DTRACE_PROVNAMELEN]; struct task_struct *p; @@ -1080,7 +1106,7 @@ static fasttrap_provider_t *fasttrap_provider_lookup(pid_t pid, mutex_unlock(&bucket->ftb_mtx); if ((p = register_pid_provider(pid)) == NULL) - return NULL; + goto fail; /* * Grab the credentials for this process so we have @@ -1088,9 +1114,14 @@ static fasttrap_provider_t *fasttrap_provider_lookup(pid_t pid, */ cred = get_cred(p->cred); - new_fp = kzalloc(sizeof(fasttrap_provider_t), GFP_KERNEL); + if ((proc = fasttrap_proc_lookup(pid)) == NULL) + goto fail; + + if ((new_fp = vzalloc(sizeof(fasttrap_provider_t))) == NULL) + goto fail; + new_fp->ftp_pid = pid; - new_fp->ftp_proc = fasttrap_proc_lookup(pid); + new_fp->ftp_proc = proc; mutex_init(&new_fp->ftp_mtx); mutex_init(&new_fp->ftp_cmtx); @@ -1142,6 +1173,16 @@ static fasttrap_provider_t *fasttrap_provider_lookup(pid_t pid, put_cred(cred); return new_fp; + +fail: + put_cred(cred); + + if (proc) + fasttrap_proc_release(proc); + if (p) + unregister_pid_provider(pid); + + return NULL; } void *fasttrap_meta_provide(void *arg, dtrace_helper_provdesc_t *dhpv, @@ -1448,7 +1489,7 @@ static struct miscdevice fasttrap_dev = { .fops = &fasttrap_fops, }; -static void fasttrap_init_htable(fasttrap_hash_t *fth, ulong_t nent) +static int fasttrap_init_htable(fasttrap_hash_t *fth, ulong_t nent) { ulong_t i; @@ -1460,11 +1501,15 @@ static void fasttrap_init_htable(fasttrap_hash_t *fth, ulong_t nent) ASSERT(fth->fth_nent > 0); fth->fth_mask = fth->fth_nent - 1; - fth->fth_table = kzalloc(fth->fth_nent * sizeof(fasttrap_bucket_t), - GFP_KERNEL); + fth->fth_table = vzalloc(fth->fth_nent * sizeof(fasttrap_bucket_t)); + + if (fth->fth_table == NULL) + return -ENOMEM; for (i = 0; i < fth->fth_nent; i++) mutex_init(&fth->fth_table[i].ftb_mtx); + + return 0; } int fasttrap_dev_init(void) @@ -1496,19 +1541,22 @@ int fasttrap_dev_init(void) if (nent == 0 || nent > 0x1000000) nent = FASTTRAP_TPOINTS_DEFAULT_SIZE; - fasttrap_init_htable(&fasttrap_tpoints, nent); + if (fasttrap_init_htable(&fasttrap_tpoints, nent) != 0) + return -ENOMEM; /* * ... and the providers hash table... */ nent = FASTTRAP_PROVIDERS_DEFAULT_SIZE; - fasttrap_init_htable(&fasttrap_provs, nent); + if (fasttrap_init_htable(&fasttrap_provs, nent) != 0) + return -ENOMEM; /* * ... and the procs hash table. */ nent = FASTTRAP_PROCS_DEFAULT_SIZE; - fasttrap_init_htable(&fasttrap_procs, nent); + if (fasttrap_init_htable(&fasttrap_procs, nent) != 0) + return -ENOMEM; fail: return ret; @@ -1613,13 +1661,16 @@ void fasttrap_dev_exit(void) mutex_unlock(&fasttrap_count_mtx); #endif - kfree(fasttrap_tpoints.fth_table); + if (fasttrap_tpoints.fth_table) + vfree(fasttrap_tpoints.fth_table); fasttrap_tpoints.fth_nent = 0; - kfree(fasttrap_provs.fth_table); + if (fasttrap_provs.fth_table) + vfree(fasttrap_provs.fth_table); fasttrap_provs.fth_nent = 0; - kfree(fasttrap_procs.fth_table); + if (fasttrap_procs.fth_table) + vfree(fasttrap_procs.fth_table); fasttrap_procs.fth_nent = 0; /* diff --git a/dtrace/include/dtrace/dtrace_impl.h b/dtrace/include/dtrace/dtrace_impl.h index 45902de51adb..73c27c18ed07 100644 --- a/dtrace/include/dtrace/dtrace_impl.h +++ b/dtrace/include/dtrace/dtrace_impl.h @@ -453,7 +453,7 @@ extern void dtrace_aggregate(dtrace_aggregation_t *, dtrace_buffer_t *, */ extern dtrace_hash_t *dtrace_hash_create(uintptr_t, uintptr_t, uintptr_t); -extern void dtrace_hash_add(dtrace_hash_t *, dtrace_probe_t *); +extern int dtrace_hash_add(dtrace_hash_t *, dtrace_probe_t *); extern dtrace_probe_t *dtrace_hash_lookup(dtrace_hash_t *, dtrace_probe_t *); extern int dtrace_hash_collisions(dtrace_hash_t *, dtrace_probe_t *); extern void dtrace_hash_remove(dtrace_hash_t *, dtrace_probe_t *); diff --git a/dtrace/profile_dev.c b/dtrace/profile_dev.c index 9136564bd070..e4bdde99d52a 100644 --- a/dtrace/profile_dev.c +++ b/dtrace/profile_dev.c @@ -172,13 +172,19 @@ static void profile_create(ktime_t interval, const char *name, int kind) if (dtrace_probe_lookup(profile_id, NULL, NULL, name) != 0) return; + prof = vzalloc(sizeof(profile_probe_t)); + if (prof == NULL) { + pr_warn("Unable to create probe %s: out-of-memory\n", name); + return; + } + atomic_inc(&profile_total); if (atomic_read(&profile_total) > profile_max) { + vfree(prof); atomic_dec(&profile_total); return; } - prof = kzalloc(sizeof(profile_probe_t), GFP_KERNEL); strcpy(prof->prof_name, name); prof->prof_interval = interval; prof->prof_cyclic = CYCLIC_NONE; @@ -388,7 +394,7 @@ void profile_destroy(void *arg, dtrace_id_t id, void *parg) profile_probe_t *prof = parg; ASSERT(prof->prof_cyclic == CYCLIC_NONE); - kfree(prof); + vfree(prof); ASSERT(atomic_read(&profile_total) >= 1); atomic_dec(&profile_total); diff --git a/dtrace/sdt_dev.c b/dtrace/sdt_dev.c index d3abd26631e6..44684b42e475 100644 --- a/dtrace/sdt_dev.c +++ b/dtrace/sdt_dev.c @@ -156,7 +156,12 @@ void sdt_provide_module(void *arg, struct module *mp) } } - nname = kmalloc(len = strlen(name) + 1, GFP_KERNEL); + nname = vmalloc(len = strlen(name) + 1); + if (nname == NULL) { + pr_warn("Unable to create probe%s: out-of-memory\n", + name); + continue; + } for (i = j = 0; name[j] != '\0'; i++) { if (name[j] == '_' && name[j + 1] == '_') { @@ -168,7 +173,13 @@ void sdt_provide_module(void *arg, struct module *mp) nname[i] = '\0'; - sdp = kzalloc(sizeof(sdt_probe_t), GFP_KERNEL); + sdp = vzalloc(sizeof(sdt_probe_t)); + if (sdp == NULL) { + pr_warn("Unable to create probe %s: out-of-memory\n", + nname); + continue; + } + sdp->sdp_loadcnt = 1; /* FIXME */ sdp->sdp_module = mp; sdp->sdp_name = nname; @@ -284,9 +295,9 @@ void sdt_destroy(void *arg, dtrace_id_t id, void *parg) else sdt_probetab[ndx] = sdp->sdp_hashnext; - kfree(sdp->sdp_name); + vfree(sdp->sdp_name); sdp = sdp->sdp_next; - kfree(old); + vfree(old); } } @@ -325,17 +336,21 @@ int sdt_dev_init(void) int ret = 0; ret = misc_register(&sdt_dev); - if (ret) + if (ret) { pr_err("%s: Can't register misc device %d\n", sdt_dev.name, sdt_dev.minor); + return ret; + } if (sdt_probetab_size == 0) sdt_probetab_size = SDT_PROBETAB_SIZE; sdt_probetab_mask = sdt_probetab_size - 1; sdt_probetab = vzalloc(sdt_probetab_size * sizeof(sdt_probe_t *)); + if (sdt_probetab == NULL) + return -ENOMEM; - dtrace_invop_add(sdt_invop); + ret = dtrace_invop_add(sdt_invop); return ret; } -- 2.50.1