[DTrace-devel] [PATCH 2/6] usdt_parser: harden DOF and note bounds checks
Alan Maguire
alan.maguire at oracle.com
Sun Aug 30 10:57:22 UTC 2026
On 28/08/2026 20:09, Kris Van Hees via DTrace-devel wrote:
> Validate DOF section metadata before use, require ELF note strings to
> terminate within their declared payloads, and check parsed DOF record
> sizes before DTrace consumes them. This keeps malformed parser input
> or stash data from driving out-of-bounds reads in either the parser or
> the host.
>
> Orabug: 39352038
> Orabug: 39352051
> Orabug: 39351967
> CVE: CVE-2026-46831
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
LGTM,
Reviewed-by: Alan Maguire <alan.maguire at oracle.com>
> ---
> include/dtrace/pid.h | 2 +-
> libcommon/usdt_parser.h | 10 ++-
> libcommon/usdt_parser_dof.c | 25 +++---
> libcommon/usdt_parser_notes.c | 106 +++++++++++++++++++------
> libdtrace/dt_pid.c | 142 ++++++++++++++++++++++++++++++----
> 5 files changed, 233 insertions(+), 52 deletions(-)
>
> diff --git a/include/dtrace/pid.h b/include/dtrace/pid.h
> index 4a239b07..88f9366c 100644
> --- a/include/dtrace/pid.h
> +++ b/include/dtrace/pid.h
> @@ -45,7 +45,7 @@ typedef struct pid_probespec {
> size_t pps_nargvlen; /* (high estimate of) length of array */
> char *pps_xargv; /* array of xlated args */
> size_t pps_xargvlen; /* (high estimate of) length of array */
> - int8_t *pps_argmap; /* mapped arg indexes */
> + uint8_t *pps_argmap; /* mapped arg indexes */
> char *pps_sargv; /* list of arg sources */
> int pps_flags; /* flags */
>
> diff --git a/libcommon/usdt_parser.h b/libcommon/usdt_parser.h
> index b11207d1..99fc3033 100644
> --- a/libcommon/usdt_parser.h
> +++ b/libcommon/usdt_parser.h
> @@ -136,7 +136,7 @@ typedef struct dof_parsed {
> * Mapping from native arg index to xlated arg index.
> * xargc in length.
> */
> - int8_t argmap[1];
> + uint8_t argmap[1];
> } argmap;
>
> struct dpi_tracepoint_info {
> @@ -171,6 +171,14 @@ typedef struct dof_parsed {
> };
> } dof_parsed_t;
>
> +#define DIT_PROVIDER_HEADSZ offsetof(dof_parsed_t, provider.name)
> +#define DIT_PROBE_HEADSZ offsetof(dof_parsed_t, probe.name)
> +#define DIT_TRACEPOINT_HEADSZ offsetof(dof_parsed_t, tracepoint.args)
> +#define DIT_ERR_HEADSZ offsetof(dof_parsed_t, err.err)
> +#define DIT_ARGS_NATIVE_HEADSZ offsetof(dof_parsed_t, nargs.args)
> +#define DIT_ARGS_XLAT_HEADSZ offsetof(dof_parsed_t, xargs.args)
> +#define DIT_ARGS_MAP_HEADSZ offsetof(dof_parsed_t, argmap.argmap)
> +
> /*
> * Host-side: in usdt_parser_host.c.
> * The host is the non-jailed process that talks to the jailed parser.
> diff --git a/libcommon/usdt_parser_dof.c b/libcommon/usdt_parser_dof.c
> index bc8e185a..e2166985 100644
> --- a/libcommon/usdt_parser_dof.c
> +++ b/libcommon/usdt_parser_dof.c
> @@ -275,8 +275,8 @@ dof_slurp(int out, dof_hdr_t *dof, uint64_t ubase)
> return -1;
> }
>
> - if (dof->dofh_secsize == 0) {
> - usdt_error(out, EINVAL, "zero section header size");
> + if (dof->dofh_secsize != sizeof(dof_sec_t)) {
> + usdt_error(out, EINVAL, "incorrect section header size");
> return -1;
> }
>
> @@ -462,7 +462,7 @@ validate_provider(int out, dof_hdr_t *dof, dof_sec_t *sec)
> return -1;
> }
>
> - if (prb_sec->dofs_entsize == 0 ||
> + if (prb_sec->dofs_entsize < sizeof(dof_probe_t) ||
> prb_sec->dofs_entsize > prb_sec->dofs_size) {
> usdt_error(out, EINVAL, "invalid entry size %x, max %lx",
> prb_sec->dofs_entsize, prb_sec->dofs_size);
> @@ -615,11 +615,11 @@ validate_provider(int out, dof_hdr_t *dof, dof_sec_t *sec)
> typeidx = prb->dofpr_xargv;
> typestr = strtab + prb->dofpr_xargv;
> for (k = 0; k < prb->dofpr_xargc; k++) {
> - if (arg[prb->dofpr_argidx + k] > prb->dofpr_nargc) {
> + if (arg[prb->dofpr_argidx + k] >= prb->dofpr_nargc) {
> usdt_error(out, EINVAL, "bad native argument index "
> "for arg %i: %i (max %i)", k,
> arg[prb->dofpr_argidx + k],
> - prb->dofpr_nargc);
> + prb->dofpr_nargc - 1);
> return -1;
> }
>
> @@ -748,7 +748,7 @@ emit_probe(int out, dtrace_helper_probedesc_t *dhpb)
> * flags.
> */
>
> - msg_size = offsetof(dof_parsed_t, probe.name) +
> + msg_size = DIT_PROBE_HEADSZ +
> strlen(dhpb->dthpb_mod) + 1 +
> strlen(dhpb->dthpb_func) + 1 +
> strlen(dhpb->dthpb_name) + 1;
> @@ -786,7 +786,7 @@ emit_probe(int out, dtrace_helper_probedesc_t *dhpb)
> size_t nargs_size;
>
> nargs_size = strings_len(dhpb->dthpb_ntypes, dhpb->dthpb_nargc);
> - msg_size = offsetof(dof_parsed_t, nargs.args) + nargs_size;
> + msg_size = DIT_ARGS_NATIVE_HEADSZ + nargs_size;
>
> msg = malloc(msg_size);
> if (!msg)
> @@ -808,8 +808,7 @@ emit_probe(int out, dtrace_helper_probedesc_t *dhpb)
>
> xargs_size = strings_len(dhpb->dthpb_xtypes,
> dhpb->dthpb_xargc);
> - msg_size = offsetof(dof_parsed_t, xargs.args) +
> - xargs_size;
> + msg_size = DIT_ARGS_XLAT_HEADSZ + xargs_size;
>
> msg = malloc(msg_size);
> if (!msg)
> @@ -826,9 +825,8 @@ emit_probe(int out, dtrace_helper_probedesc_t *dhpb)
>
> /* Then the mapping table. */
>
> - map_size = dhpb->dthpb_xargc * sizeof(int8_t);
> - msg_size = offsetof(dof_parsed_t, argmap.argmap) +
> - map_size;
> + map_size = dhpb->dthpb_xargc * sizeof(uint8_t);
> + msg_size = DIT_ARGS_MAP_HEADSZ + map_size;
>
> msg = malloc(msg_size);
> if (!msg)
> @@ -922,8 +920,7 @@ emit_provider(int out, dof_helper_t *dhp,
> }
>
> dhpb.dthpb_prov = strtab + prov->dofpv_name;
> - provider_msg_size = offsetof(dof_parsed_t, provider.name) +
> - strlen(dhpb.dthpb_prov) + 1;
> + provider_msg_size = DIT_PROVIDER_HEADSZ + strlen(dhpb.dthpb_prov) + 1;
>
> provider_msg = malloc(provider_msg_size);
> if (!provider_msg) {
> diff --git a/libcommon/usdt_parser_notes.c b/libcommon/usdt_parser_notes.c
> index c98c9fb0..7742024e 100644
> --- a/libcommon/usdt_parser_notes.c
> +++ b/libcommon/usdt_parser_notes.c
> @@ -73,6 +73,10 @@ get_note(int out, usdt_data_t *data, ssize_t off, usdt_note_t *note)
> }
>
> note->name = (char *)data->buf + off;
> + if (memchr(note->name, '\0', sz) == NULL) {
> + usdt_error(out, EINVAL, "Unterminated name");
> + return -1;
> + }
> off += ALIGN(sz, 4);
>
> dt_dbg_usdt("ELF note '%s' (%d bytes)\n",
> @@ -272,6 +276,25 @@ static dt_htab_ops_t pmap_htab_ops = {
> .next = (htab_next_fn)prb_next
> };
>
> +/*
> + * Return the length of string 'str' (excluding the terminating NUL, if it
> + * terminates before the supplied 'end', and -1 otherwise.
> + */
> +static ssize_t
> +cstrlen(const char *str, const char *end)
> +{
> + const char *p;
> +
> + if (str >= end)
> + return -1;
> +
> + p = memchr(str, '\0', end - str);
> + if (p == NULL)
> + return -1;
> +
> + return p - str;
> +}
> +
> /*
> * Return the cummulative string length of 'cnt' consecutive 0-terminated
> * strings. If skip > 0, it indicates how many extra bytes are to be skipped
> @@ -284,10 +307,12 @@ strarray_size(uint8_t cnt, const char *str, const char *end, size_t skip)
> const char *p = str;
>
> while (cnt-- > 0) {
> - if (p >= end)
> + ssize_t len = cstrlen(p, end);
> +
> + if (len < 0 || skip > (size_t)(end - (p + len + 1)))
> return -1;
>
> - p += strlen(p) + 1 + skip;
> + p += len + 1 + skip;
> }
>
> return p - str;
> @@ -298,14 +323,21 @@ parse_prov_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> usdt_note_t *note)
> {
> const char *p = note->desc;
> + const char *end = p + note->hdr->n_descsz;
> dt_provider_t prvt, *pvp;
> const uint32_t *vals;
> uint32_t probec;
> + ssize_t len;
> int i;
>
> + len = cstrlen(p, end);
> + if (len == -1) {
> + usdt_error(out, EINVAL, "Unterminated provider name");
> + return -1;
> + }
> prvt.name = p;
> - p += ALIGN(strlen(p) + 1, 4);
> - if (p + 6 * sizeof(uint32_t) - note->desc > note->hdr->n_descsz) {
> + p += ALIGN(len + 1, 4);
> + if (p + 6 * sizeof(uint32_t) > end) {
> usdt_error(out, EINVAL, "Incomplete note data");
> return -1;
> }
> @@ -342,13 +374,18 @@ parse_prov_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> ssize_t len;
>
> p = (const char *)ALIGN((uintptr_t)p, 4);
> + len = cstrlen(p, end);
> + if (len == -1) {
> + usdt_error(out, EINVAL, "Unterminated probe name");
> + return -1;
> + }
> prbt.prv = pvp->name;
> prbt.mod = dhp->dofhp_mod;
> prbt.fun = NULL;
> prbt.prb = p;
> prbt.off = 0;
> - p += strlen(p) + 1;
> - if (p + 2 * sizeof(uint8_t) - note->desc > note->hdr->n_descsz) {
> + p += len + 1;
> + if (p + 2 * sizeof(uint8_t) > end) {
> usdt_error(out, EINVAL, "Incomplete note data");
> return -1;
> }
> @@ -374,8 +411,7 @@ parse_prov_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> prp->ntp = 0;
> prp->is_enabled = 0;
> prp->nargc = argc = *(uint8_t *)p++;
> - len = strarray_size(argc, p, note->desc + note->hdr->n_descsz,
> - 0);
> + len = strarray_size(argc, p, end, 0);
> if (len == -1) {
> usdt_error(out, EINVAL, "Incomplete note data");
> return -1;
> @@ -384,7 +420,7 @@ parse_prov_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> prp->nargs = p;
>
> p += len;
> - if (p - note->desc > note->hdr->n_descsz) {
> + if (p >= end) {
> usdt_error(out, EINVAL, "Incomplete note data");
> return -1;
> }
> @@ -411,6 +447,11 @@ parse_prov_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> q = stpcpy(q, p);
> q++;
> p += strlen(p) + 1;
> + if (*(uint8_t *)p >= prp->nargc) {
> + usdt_error(out, EINVAL,
> + "bad native argument index");
> + return -1;
> + }
> prp->xmap[j] = *p;
> p++;
> }
> @@ -432,7 +473,9 @@ parse_usdt_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> usdt_note_t *note)
> {
> const char *p = note->desc;
> + const char *end = p + note->hdr->n_descsz;
> uint64_t off, fno;
> + ssize_t len;
> dt_probe_t prbt, *prp;
>
> data = data->next;
> @@ -441,7 +484,7 @@ parse_usdt_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> return -1;
> }
>
> - if (p + 2 * sizeof(uint64_t) - note->desc > note->hdr->n_descsz) {
> + if (p + 2 * sizeof(uint64_t) >= end) {
> usdt_error(out, EINVAL, "Incomplete note data");
> return -1;
> }
> @@ -450,10 +493,15 @@ parse_usdt_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> p += sizeof(uint64_t);
> fno = *(uint64_t *)p;
> p += sizeof(uint64_t);
> + len = cstrlen(p, end);
> + if (len == -1) {
> + usdt_error(out, EINVAL, "Unterminated provider name");
> + return -1;
> + }
>
> prbt.prv = p;
> - p += strlen(p) + 1;
> - if (p - note->desc > note->hdr->n_descsz) {
> + p += len + 1;
> + if (p >= end) {
> usdt_error(out, EINVAL, "Incomplete note data");
> return -1;
> }
> @@ -463,9 +511,18 @@ parse_usdt_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> return -1;
> }
> prbt.fun = (char *)data->buf + fno;
> + if (cstrlen(prbt.fun, (char *)data->buf + data->size) == -1) {
> + usdt_error(out, EINVAL, "Unterminated function name");
> + return -1;
> + }
> + len = cstrlen(p, end);
> + if (len == -1) {
> + usdt_error(out, EINVAL, "Unterminated probe name");
> + return -1;
> + }
> prbt.prb = p;
> - p += strlen(p) + 1;
> - if (p - note->desc > note->hdr->n_descsz) {
> + p += len + 1;
> + if (p >= end) {
> usdt_error(out, EINVAL, "Incomplete note data");
> return -1;
> }
> @@ -510,9 +567,14 @@ parse_usdt_note(int out, dof_helper_t *dhp, usdt_data_t *data,
> prp->is_enabled = (note->hdr->n_type == _USDT_EN_NOTE_TYPE ? 1 : 0);
> prp->ntp = 0;
> prp->sargc = *p++;
> + len = cstrlen(p, end);
> + if (len == -1) {
> + usdt_error(out, EINVAL, "Unterminated argument string");
> + return -1;
> + }
> prp->sargs = p;
> - p += strlen(p) + 1;
> - if (p - note->desc > note->hdr->n_descsz) {
> + p += len + 1;
> + if (p > end) {
> usdt_error(out, EINVAL, "Incomplete note data");
> return -1;
> }
> @@ -537,22 +599,22 @@ alloc_msg(int out, dof_parsed_info_t type, size_t len)
>
> switch (type) {
> case DIT_PROVIDER:
> - len += offsetof(dof_parsed_t, provider.name);
> + len += DIT_PROVIDER_HEADSZ;
> break;
> case DIT_PROBE:
> - len += offsetof(dof_parsed_t, probe.name);
> + len += DIT_PROBE_HEADSZ;
> break;
> case DIT_ARGS_NATIVE:
> - len += offsetof(dof_parsed_t, nargs.args);
> + len += DIT_ARGS_NATIVE_HEADSZ;
> break;
> case DIT_ARGS_XLAT:
> - len += offsetof(dof_parsed_t, xargs.args);
> + len += DIT_ARGS_XLAT_HEADSZ;
> break;
> case DIT_ARGS_MAP:
> - len += offsetof(dof_parsed_t, argmap.argmap);
> + len += DIT_ARGS_MAP_HEADSZ;
> break;
> case DIT_TRACEPOINT:
> - len += offsetof(dof_parsed_t, tracepoint.args);
> + len += DIT_TRACEPOINT_HEADSZ;
> break;
> default:
> usdt_error(out, EINVAL, "Unknown dof_parsed_t type: %d", type);
> diff --git a/libdtrace/dt_pid.c b/libdtrace/dt_pid.c
> index 7e6e5d90..e20bc82b 100644
> --- a/libdtrace/dt_pid.c
> +++ b/libdtrace/dt_pid.c
> @@ -782,25 +782,93 @@ err:
> }
>
> /*
> - * A quick check that a parsed DOF record read hasn't incurred a buffer overrun
> - * and is of the type expected.
> + * Ensure that the buffer has enough data to read the record of the expected
> + * type. Ensure that all records have at least 1 byte of payload data.
> */
> static int
> validate_dof_record(const char *path, const dof_parsed_t *parsed,
> - dof_parsed_info_t expected, size_t buf_size,
> + dof_parsed_info_t type, size_t headsz, size_t buf_size,
> size_t seen_size)
> {
> - if (buf_size < seen_size) {
> + size_t data_size;
> +
> + /* If we have read more than there is, we must always fail. */
> + if (buf_size < seen_size)
> + data_size = 0;
> + else
> + data_size = buf_size - seen_size;
> +
> + if (data_size < headsz || data_size < parsed->size) {
> dt_dprintf("DOF too small when adding probes (seen %zi bytes)\n",
> seen_size);
> return 0;
> }
>
> - if (parsed->type != expected) {
> + if (parsed->size < headsz + 1) {
> + dt_dprintf("DOF record too small: expected %zi, got %zi\n",
> + headsz, parsed->size);
> + return 0;
> + }
> +
> + if (parsed->type != type) {
> dt_dprintf("%s format invalid: expected %i, got %i\n", path,
> - expected, parsed->type);
> + type, parsed->type);
> return 0;
> }
> +
> + return 1;
> +}
> +
> +/*
> + * Validate a payload containing CNT consecutive NUL-terminated strings.
> + */
> +static int
> +validate_string_payload(const char *path, const char *payload,
> + size_t payload_size, size_t cnt)
> +{
> + const char *p = payload;
> + const char *end = payload + payload_size;
> + size_t i;
> +
> + for (i = 0; i < cnt; i++) {
> + const char *nul;
> +
> + if (p >= end) {
> + dt_dprintf("%s string payload too small\n", path);
> + return 0;
> + }
> +
> + nul = memchr(p, '\0', end - p);
> + if (nul == NULL) {
> + dt_dprintf("%s string payload unterminated\n", path);
> + return 0;
> + }
> +
> + p = nul + 1;
> + }
> +
> + return 1;
> +}
> +
> +static int
> +validate_argmap_payload(const char *path, const uint8_t *argmap,
> + size_t payload_size, size_t nargc, size_t xargc)
> +{
> + size_t i;
> +
> + if (payload_size < xargc * sizeof(uint8_t)) {
> + dt_dprintf("%s argmap payload too small\n", path);
> + return 0;
> + }
> +
> + for (i = 0; i < xargc; i++) {
> + if (argmap[i] >= nargc) {
> + dt_dprintf("%s argmap entry %zi invalid: %u >= %zi\n",
> + path, i, argmap[i], nargc);
> + return 0;
> + }
> + }
> +
> return 1;
> }
>
> @@ -908,13 +976,13 @@ dt_pid_create_usdt_probes_proc(dtrace_hdl_t *dtp, pid_t pid, dt_proc_t *dpr,
> char *dof_buf = NULL, *p;
> struct stat s;
> char *path;
> - size_t dof_buf_size, seen_size = 0;
> + size_t dof_buf_size, seen_size = 0, payload_size;
> uint64_t *dof_version;
> char *prv, *mod, *fun, *prb;
> dof_parsed_t *provider, *probe;
> ssize_t nargvlen = 0, xargvlen = 0;
> char *nargv = NULL, *xargv = NULL;
> - int8_t *argmap = NULL;
> + uint8_t *argmap = NULL;
>
> /*
> * Regular files only: in particular, skip . and ..,
> @@ -929,7 +997,7 @@ dt_pid_create_usdt_probes_proc(dtrace_hdl_t *dtp, pid_t pid, dt_proc_t *dpr,
> goto per_mapping_err;
>
> dof_buf = read_file(path, &dof_buf_size);
> - if (dof_buf == NULL)
> + if (dof_buf == NULL || dof_buf_size < sizeof(uint64_t))
> goto per_mapping_err;
> dof_version = (uint64_t *) dof_buf;
> if (*dof_version != DOF_PARSED_VERSION) {
> @@ -945,27 +1013,50 @@ dt_pid_create_usdt_probes_proc(dtrace_hdl_t *dtp, pid_t pid, dt_proc_t *dpr,
> * probe.
> */
> provider = (dof_parsed_t *) p;
> - if (!validate_dof_record(path, provider, DIT_PROVIDER, dof_buf_size,
> + if (!validate_dof_record(path, provider, DIT_PROVIDER,
> + DIT_PROVIDER_HEADSZ, dof_buf_size,
> seen_size))
> goto parse_err;
>
> + /*
> + * Ensure that a validly terminated string follows the record
> + * header.
> + */
> prv = provider->provider.name;
> + payload_size = provider->size - DIT_PROVIDER_HEADSZ;
> + if (memchr(prv, '\0', payload_size) == NULL)
> + goto parse_err;
>
> p += provider->size;
> seen_size += provider->size;
>
> probe = (dof_parsed_t *) p;
> - if (!validate_dof_record(path, probe, DIT_PROBE, dof_buf_size,
> + if (!validate_dof_record(path, probe, DIT_PROBE,
> + DIT_PROBE_HEADSZ, dof_buf_size,
> seen_size))
> goto parse_err;
>
> mod = probe->probe.name;
> + payload_size = probe->size - DIT_PROBE_HEADSZ;
> + if (memchr(mod, '\0', payload_size) == NULL)
> + goto parse_err;
> +
> fun = mod + strlen(mod) + 1;
> + payload_size -= strlen(mod) + 1;
> + if (memchr(fun, '\0', payload_size) == NULL)
> + goto parse_err;
> prb = fun + strlen(fun) + 1;
> + payload_size -= strlen(fun) + 1;
> + if (memchr(prb, '\0', payload_size) == NULL)
> + goto parse_err;
>
> p += probe->size;
> seen_size += probe->size;
>
> + if (probe->probe.nargc > UINT8_MAX ||
> + probe->probe.xargc > UINT8_MAX)
> + goto parse_err;
> +
> /*
> * Assume the order given in dof_parser.h, for simplicity.
> */
> @@ -973,11 +1064,16 @@ dt_pid_create_usdt_probes_proc(dtrace_hdl_t *dtp, pid_t pid, dt_proc_t *dpr,
> dof_parsed_t *args = (dof_parsed_t *) p;
>
> if (!validate_dof_record(path, args, DIT_ARGS_NATIVE,
> + DIT_ARGS_NATIVE_HEADSZ,
> dof_buf_size, seen_size))
> goto parse_err;
>
> nargv = args->nargs.args;
> - nargvlen = args->size - offsetof(dof_parsed_t, nargs.args);
> + payload_size = args->size - DIT_ARGS_NATIVE_HEADSZ;
> + if (!validate_string_payload(path, nargv, payload_size,
> + probe->probe.nargc))
> + goto parse_err;
> + nargvlen = payload_size;
> assert(nargvlen >= 0);
>
> p += args->size;
> @@ -987,11 +1083,16 @@ dt_pid_create_usdt_probes_proc(dtrace_hdl_t *dtp, pid_t pid, dt_proc_t *dpr,
> dof_parsed_t *args = (dof_parsed_t *) p;
>
> if (!validate_dof_record(path, args, DIT_ARGS_XLAT,
> + DIT_ARGS_XLAT_HEADSZ,
> dof_buf_size, seen_size))
> goto parse_err;
>
> xargv = args->xargs.args;
> - xargvlen = args->size - offsetof(dof_parsed_t, xargs.args);
> + payload_size = args->size - DIT_ARGS_XLAT_HEADSZ;
> + if (!validate_string_payload(path, xargv, payload_size,
> + probe->probe.xargc))
> + goto parse_err;
> + xargvlen = payload_size;
> assert(xargvlen >= 0);
>
> p += args->size;
> @@ -999,10 +1100,16 @@ dt_pid_create_usdt_probes_proc(dtrace_hdl_t *dtp, pid_t pid, dt_proc_t *dpr,
> args = (dof_parsed_t *) p;
>
> if (!validate_dof_record(path, args, DIT_ARGS_MAP,
> + DIT_ARGS_MAP_HEADSZ,
> dof_buf_size, seen_size))
> goto parse_err;
>
> argmap = args->argmap.argmap;
> + payload_size = args->size - DIT_ARGS_MAP_HEADSZ;
> + if (!validate_argmap_payload(path, argmap, payload_size,
> + probe->probe.nargc,
> + probe->probe.xargc))
> + goto parse_err;
>
> p += args->size;
> seen_size += args->size;
> @@ -1017,6 +1124,7 @@ dt_pid_create_usdt_probes_proc(dtrace_hdl_t *dtp, pid_t pid, dt_proc_t *dpr,
> const prmap_t *pmp;
>
> if (!validate_dof_record(path, tp, DIT_TRACEPOINT,
> + DIT_TRACEPOINT_HEADSZ,
> dof_buf_size, seen_size))
> goto parse_err;
>
> @@ -1073,9 +1181,15 @@ dt_pid_create_usdt_probes_proc(dtrace_hdl_t *dtp, pid_t pid, dt_proc_t *dpr,
> if (argmap)
> psp.pps_argmap = argmap;
>
> - if (tp->tracepoint.args[0] != 0)
> + if (tp->tracepoint.args[0] != 0) {
> psp.pps_sargv = tp->tracepoint.args;
>
> + payload_size = tp->size - DIT_TRACEPOINT_HEADSZ;
> + if (memchr(psp.pps_sargv, '\0',
> + payload_size) == NULL)
> + goto parse_err;
> + }
> +
> dt_dprintf("providing %s:%s:%s:%s for pid %d @ %lx\n",
> psp.pps_prv, psp.pps_mod, psp.pps_fun,
> psp.pps_prb, psp.pps_pid, psp.pps_off);
> --
> 2.52.0
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
>
More information about the DTrace-devel
mailing list