usdt_parser: harden DOF and note bounds checks
PATCH 2/6 usdt_parser: harden DOF and note bounds checks
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 <[email protected]>
--- 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(-)
include/dtrace/pid.h +1 -1
@@ -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 */
libcommon/usdt_parser.h +9 -1
@@ -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.
libcommon/usdt_parser_dof.c +11 -14
@@ -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) {
libcommon/usdt_parser_notes.c +84 -22
218 lines not on this page · raw message
libdtrace/dt_pid.c +128 -14
247 lines not on this page · raw message
Signature · 1 line
2.47.3