[PATCH] usdt: enforce provider name size limit
Kris Van Hees <[email protected]> Tue, 17 Feb 2026 11:35:06 -0500
| Newsgroups | dev.linux.lists.dtrace |
|---|---|
| Message-ID | <DS0PR10MB7522C161F2C7C0F342DE99BAC26DA@DS0PR10MB7522.namprd10.prod.outlook.com> |
Since USDT provider names have a PID appended to them, the base provider name cannot be longer than 53 characters (PID can take up to 10 chars). Signed-off-by: Kris Van Hees <[email protected]> --- libdtrace/dt_link.c | 24 ++++++++++++--- test/unittest/usdt/err.prov-too-long.r | 3 ++ test/unittest/usdt/err.prov-too-long.sh | 41 +++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 test/unittest/usdt/err.prov-too-long.r create mode 100755 test/unittest/usdt/err.prov-too-long.sh diff --git a/libdtrace/dt_link.c b/libdtrace/dt_link.c index ffa16d9a..e77f06f7 100644 --- a/libdtrace/dt_link.c +++ b/libdtrace/dt_link.c @@ -148,7 +148,15 @@ note_add_provider(usdt_elf_t *usdt, dt_provider_t *pvp) usdt->base = ALIGN(usdt->base + usdt->size, 4); usdt->size = 0; + /* Ensure there is enough space in the provider name for the PID. */ len = strlen(pvp->desc.dtvd_name); + if (len > DTRACE_PROVNAMELEN - 10 - 1) + return dt_link_error(usdt->dtp, NULL, -1, + "USDT provider name may not exceed %d " + "characters: %s\n", + DTRACE_PROVNAMELEN - 11, + pvp->desc.dtvd_name); + sz = PROV_NOTE_HEADSZ + ALIGN(len + 1, 4) + /* provider name */ 6 * sizeof(uint32_t); /* stability attributes */ @@ -382,12 +390,16 @@ create_elf64(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, int fd, uint_t flags) shdr->sh_addralign = sizeof(char); /* Add the provider definitions. */ - while ((pvp = dt_htab_next(dtp->dt_provs, &it)) != NULL) - note_add_provider(usdt, pvp); + while ((pvp = dt_htab_next(dtp->dt_provs, &it)) != NULL) { + if (note_add_provider(usdt, pvp) == -1) + goto fail; + } if (!(flags & DTRACE_D_STRIP)) { - note_add_version(usdt); - note_add_utsname(usdt); + if (note_add_version(usdt) == -1) + goto fail; + if (note_add_utsname(usdt) == -1) + goto fail; } dt_free(dtp, usdt); @@ -492,7 +504,9 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, if (!dtp->dt_lazyload) unlink(file); - create_elf64(dtp, pgp, fd, dflags | dtp->dt_dflags); + ret = create_elf64(dtp, pgp, fd, dflags | dtp->dt_dflags); + if (ret == -1) + goto done; if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) return dt_link_error(dtp, NULL, -1, diff --git a/test/unittest/usdt/err.prov-too-long.r b/test/unittest/usdt/err.prov-too-long.r new file mode 100644 index 00000000..1305f434 --- /dev/null +++ b/test/unittest/usdt/err.prov-too-long.r @@ -0,0 +1,3 @@ +-- @@stderr -- +dtrace: failed to link script prov: USDT provider name may not exceed 53 characters: test_12345678901234567890123456789012345678901234_prov +failed to create DOF diff --git a/test/unittest/usdt/err.prov-too-long.sh b/test/unittest/usdt/err.prov-too-long.sh new file mode 100755 index 00000000..599e461e --- /dev/null +++ b/test/unittest/usdt/err.prov-too-long.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# +# Oracle Linux DTrace. +# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +# Ensure that provider names longer than 53 chars are rejected at link time. + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + + +dtrace=$1 + +DIRNAME="$tmpdir/prov-too-long.$$.$RANDOM" +mkdir -p $DIRNAME +cd $DIRNAME + +cat > prov.d <<EOF +/* Provider name is 53 chars long */ +provider test_1234567890123456789012345678901234567890123_prov { + probe go(); +}; +/* Provider name is 54 chars long */ +provider test_12345678901234567890123456789012345678901234_prov { + probe go(); +}; +EOF + +$dtrace $dt_flags -G -s prov.d +if [ $? -ne 0 ]; then + echo "failed to create DOF" >& 2 + exit 1 +fi + +echo "DOF creation should have failed" >& 2 +exit 0 -- 2.51.0