Skip to content

Commit

Permalink
cg: lift restriction of 1st arg to bcopy() not being alloca
Browse files Browse the repository at this point in the history
The documentation states that the source address is not allowed to be
within the scratch memory region, but the legacy implementation does
not actually enforce that restriction, nor does it seem necessary.

This patch also moves bcopy tests into their own directory.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Reviewed-by: Eugene Loh <eugene.loh@oracle.com>
  • Loading branch information
kvanhees committed Jan 18, 2023
1 parent 7c655ca commit d090056
Show file tree
Hide file tree
Showing 25 changed files with 78 additions and 56 deletions.
64 changes: 30 additions & 34 deletions libdtrace/dt_cg.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2023, 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.
*/
Expand Down Expand Up @@ -1040,14 +1040,20 @@ dt_cg_alloca_ptr(dt_irlist_t *dlp, dt_regset_t *drp, int dreg, int sreg)
* alloca pointer value into a real pointer.
*/
static void
dt_cg_check_ptr_arg(dt_irlist_t *dlp, dt_regset_t *drp, dt_node_t *dnp)
dt_cg_check_ptr_arg(dt_irlist_t *dlp, dt_regset_t *drp, dt_node_t *dnp,
dt_node_t *size)
{
if (dnp->dn_flags & DT_NF_ALLOCA) {
dtrace_diftype_t vtype;
if (size == NULL) {
dtrace_diftype_t vtype;

dt_node_diftype(yypcb->pcb_hdl, dnp, &vtype);
dt_cg_alloca_access_check(dlp, drp, dnp->dn_reg,
DT_ISIMM, vtype.dtdt_size);
} else
dt_cg_alloca_access_check(dlp, drp, dnp->dn_reg,
DT_ISREG, size->dn_reg);

dt_node_diftype(yypcb->pcb_hdl, dnp, &vtype);
dt_cg_alloca_access_check(dlp, drp, dnp->dn_reg,
DT_ISIMM, vtype.dtdt_size);
dt_cg_alloca_ptr(dlp, drp, dnp->dn_reg, dnp->dn_reg);
} else
dt_cg_check_notnull(dlp, drp, dnp->dn_reg);
Expand Down Expand Up @@ -3892,7 +3898,7 @@ dt_cg_subr_arg_to_tstring(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
/* (its type matters only as to whether we check it is null */
dt_cg_node(arg, dlp, drp);
if (dt_node_is_pointer(arg) || dt_node_is_string(arg))
dt_cg_check_ptr_arg(dlp, drp, arg);
dt_cg_check_ptr_arg(dlp, drp, arg, NULL);

/* allocate the temporary string */
dnp->dn_reg = dt_regset_alloc(drp);
Expand Down Expand Up @@ -3950,9 +3956,9 @@ dt_cg_subr_index(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
TRACE_REGSET(" subr-index:Begin");

dt_cg_node(s, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, s);
dt_cg_check_ptr_arg(dlp, drp, s, NULL);
dt_cg_node(t, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, t);
dt_cg_check_ptr_arg(dlp, drp, t, NULL);
if (start != NULL)
dt_cg_node(start, dlp, drp);

Expand Down Expand Up @@ -4167,9 +4173,9 @@ dt_cg_subr_rindex(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)

/* evaluate arguments to D subroutine rindex() */
dt_cg_node(s, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, s);
dt_cg_check_ptr_arg(dlp, drp, s, NULL);
dt_cg_node(t, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, t);
dt_cg_check_ptr_arg(dlp, drp, t, NULL);
if (start != NULL)
dt_cg_node(start, dlp, drp);

Expand Down Expand Up @@ -4394,13 +4400,7 @@ dt_cg_subr_bcopy_impl(dt_node_t *dnp, dt_node_t *dst, dt_node_t *src,

/* Validate the source pointer. */
dt_cg_node(src, dlp, drp);
if (src->dn_flags & DT_NF_ALLOCA)
dnerror(src, D_PROTO_ARG,
"%s( ) argument #1 is incompatible with prototype:\n"
"\tprototype: non-alloca pointer\n"
"\t argument: alloca pointer\n",
is_bcopy ? "bcopy" : "copyinto");
dt_cg_check_notnull(dlp, drp, src->dn_reg);
dt_cg_check_ptr_arg(dlp, drp, src, size);

/* Validate the destination pointer. */
dt_cg_node(dst, dlp, drp);
Expand All @@ -4410,11 +4410,7 @@ dt_cg_subr_bcopy_impl(dt_node_t *dnp, dt_node_t *dst, dt_node_t *src,
"\tprototype: alloca pointer\n"
"\t argument: non-alloca pointer\n",
is_bcopy ? "bcopy" : "copyinto", is_bcopy ? 2 : 3);
/* The dst will be NULL-checked in the alloca access check below. */

dt_cg_alloca_access_check(dlp, drp, dst->dn_reg,
DT_ISREG, size->dn_reg);
dt_cg_alloca_ptr(dlp, drp, dst->dn_reg, dst->dn_reg);
dt_cg_check_ptr_arg(dlp, drp, dst, size);

if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
Expand Down Expand Up @@ -4594,7 +4590,7 @@ dt_cg_subr_strchr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)

TRACE_REGSET(" subr-strchr:Begin");
dt_cg_node(str, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, str);
dt_cg_check_ptr_arg(dlp, drp, str, NULL);
dt_cg_node(chr, dlp, drp);

if (dt_regset_xalloc_args(drp) == -1)
Expand Down Expand Up @@ -4650,7 +4646,7 @@ dt_cg_subr_strrchr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)

TRACE_REGSET(" subr-strrchr:Begin");
dt_cg_node(str, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, str);
dt_cg_check_ptr_arg(dlp, drp, str, NULL);
dt_cg_node(chr, dlp, drp);

if (dt_regset_xalloc_args(drp) == -1)
Expand Down Expand Up @@ -4701,7 +4697,7 @@ dt_cg_subr_strlen(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
TRACE_REGSET(" subr-strlen:Begin");

dt_cg_node(str, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, str);
dt_cg_check_ptr_arg(dlp, drp, str, NULL);

if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
Expand Down Expand Up @@ -4735,9 +4731,9 @@ dt_cg_subr_strjoin(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
TRACE_REGSET(" subr-strjoin:Begin");

dt_cg_node(s1, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, s1);
dt_cg_check_ptr_arg(dlp, drp, s1, NULL);
dt_cg_node(s2, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, s2);
dt_cg_check_ptr_arg(dlp, drp, s2, NULL);

/*
* The result needs to be a temporary string, so we request one.
Expand Down Expand Up @@ -4782,9 +4778,9 @@ dt_cg_subr_strstr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)

/* get args */
dt_cg_node(s, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, s);
dt_cg_check_ptr_arg(dlp, drp, s, NULL);
dt_cg_node(t, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, t);
dt_cg_check_ptr_arg(dlp, drp, t, NULL);

/* call dt_index() call */
if (dt_regset_xalloc_args(drp) == -1)
Expand Down Expand Up @@ -4885,7 +4881,7 @@ dt_cg_subr_strtok(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
if (str->dn_op != DT_TOK_INT || str->dn_value != 0) {
/* string is present: copy it to internal state */
dt_cg_node(str, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, str);
dt_cg_check_ptr_arg(dlp, drp, str, NULL);

if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
Expand Down Expand Up @@ -4914,7 +4910,7 @@ dt_cg_subr_strtok(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)

/* get delimiters */
dt_cg_node(del, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, del);
dt_cg_check_ptr_arg(dlp, drp, del, NULL);

/* allocate temporary string for result */
dnp->dn_reg = dt_regset_alloc(drp);
Expand Down Expand Up @@ -4965,7 +4961,7 @@ dt_cg_subr_substr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
TRACE_REGSET(" subr-substr:Begin");

dt_cg_node(str, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, str);
dt_cg_check_ptr_arg(dlp, drp, str, NULL);
dt_cg_node(idx, dlp, drp);
if (cnt != NULL)
dt_cg_node(cnt, dlp, drp);
Expand Down Expand Up @@ -5415,7 +5411,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)

case DT_TOK_STRINGOF:
dt_cg_node(dnp->dn_child, dlp, drp);
dt_cg_check_ptr_arg(dlp, drp, dnp->dn_child);
dt_cg_check_ptr_arg(dlp, drp, dnp->dn_child, NULL);
dnp->dn_reg = dnp->dn_child->dn_reg;
break;

Expand Down
File renamed without changes.
4 changes: 4 additions & 0 deletions test/unittest/funcs/bcopy/err.badbcopy.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- @@stderr --
dtrace: failed to compile script test/unittest/funcs/bcopy/err.badbcopy.d: line 26: bcopy( ) argument #2 is incompatible with prototype:
prototype: alloca pointer
argument: non-alloca pointer
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions test/unittest/funcs/bcopy/err.badbcopy2.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- @@stderr --
dtrace: failed to compile script test/unittest/funcs/bcopy/err.badbcopy2.d: line 25: bcopy( ) argument #2 is incompatible with prototype:
prototype: alloca pointer
argument: non-alloca pointer
File renamed without changes.
4 changes: 4 additions & 0 deletions test/unittest/funcs/bcopy/err.badbcopy3.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- @@stderr --
dtrace: failed to compile script test/unittest/funcs/bcopy/err.badbcopy3.d: line 22: bcopy( ) argument #2 is incompatible with prototype:
prototype: alloca pointer
argument: non-alloca pointer
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
28 changes: 28 additions & 0 deletions test/unittest/funcs/bcopy/err.badbcopy7.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2023, 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.
*/

/*
* ASSERTION: bcopy from an alloca pointer is subject to size checks
*
* SECTION: Actions and Subroutines/alloca();
* Actions and Subroutines/bcopy()
*/

#pragma D option quiet

BEGIN
{
d = alloca(20);
s = alloca(10);
bcopy(s, d, 20);
exit(0);
}

ERROR
{
exit(1);
}
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions test/unittest/funcs/bcopy/err.badbcopy8.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

-- @@stderr --
dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid size ({ptr}) in action #1 at BPF pc NNN
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/

/*
* ASSERTION:
* bcopy should not copy when the source is scratch space
* ASSERTION: bcopy to scratch space is allowed (even though documentation
* claims that it is not)
*
* SECTION: Actions and Subroutines/alloca();
* Actions and Subroutines/bcopy()
Expand All @@ -16,14 +16,13 @@

#pragma D option quiet


BEGIN
{
ptr = alloca(sizeof(unsigned long));
ptr = (unsigned long *)alloca(sizeof(unsigned long));
bcopy((void *)&`max_pfn, ptr, sizeof(unsigned long));
ptr2 = alloca(sizeof(unsigned long));
ptr2 = (unsigned long *)alloca(sizeof(unsigned long));
bcopy(ptr, ptr2, sizeof(unsigned long));
exit(0);
exit(*ptr == *ptr2 ? 0 : 1);
}

ERROR
Expand Down
4 changes: 0 additions & 4 deletions test/unittest/funcs/err.badbcopy.r

This file was deleted.

4 changes: 0 additions & 4 deletions test/unittest/funcs/err.badbcopy2.r

This file was deleted.

4 changes: 0 additions & 4 deletions test/unittest/funcs/err.badbcopy3.r

This file was deleted.

4 changes: 0 additions & 4 deletions test/unittest/funcs/err.badbcopy7.r

This file was deleted.

0 comments on commit d090056

Please sign in to comment.