[DTrace-devel] [PATCH v5 00/10] alloca and bcopy

Kris Van Hees kris.van.hees at oracle.com
Wed Apr 20 01:52:07 UTC 2022


Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>

... for the entire patch series, with the following modifications:

- fix copyright years where needed
- remove incorrect comment block in dt_cg_subr_alloca()

On Thu, Apr 14, 2022 at 02:25:56PM +0100, Nick Alcock wrote:
> This pile of commits implements alloca and bcopy.  It's a joint effort, with
> Kris doing massive revamps of the alloca/deref work.
> 
> alloca is simpler than it used to be in past revisions. It still stores
> everything in a new percpu scratchmem array, but much of the rest has
> changed.
> 
> 1) mark all pointers emitted from alloca(), all variables such values
>    are stored in, and all values retrieved from those variables with
>    special parser/ident flags (unchanged from previous revisions)
> 
> 2) propagate these flags to and from identifiers.  There is no bounds
>    checking at this point: the pointers are still just scalar offsets from
>    scratchmem.  (Offset zero is NULL: non-null offsets start at 8.)  A
>    couple of prohibitions are injected at this point, but nothing more.
> 
> 2) at deref time, bounds-check the pointers and raise them to map_values
>    relative to the scratchmem array , taking the size of the access into
>    account.  Some derefs are in somewhat unexpected places, and some sizes
>    are hard to dig out, but they are all basically the same.
> 
> Rather than three bounds checkers as in days of yore there is only one,
> dt_cg_alloca_access_check, whicdh always checks an offset-from-scratchmem,
> not an address. Calls to this should be followed by calls to
> dt_cg_alloca_ptr, which raises the resulting offset into a pointer, and
> optionally returns it in a new reg.
> 
> The alloca-tainting stuff above has some slightly unfortunate implications,
> since alloca status attaches to identifiers, not to specific uses of them.
> You cannot reuse the same variable to store both alloca pointers and other
> sorts of pointer in a single D program (not clause!).  You *can* have
> ternary conditionals whose branches are sometimes alloca and sometimes not,
> but you can't assign the result of such ternaries to variables at all.
> 
> The above restructions do *not* apply to null pointers: you can assign NULL
> to pointers that previously held allocaed pointers, and stick alloca
> pointers back on them, freely.  But that's not a get-out clause: you still
> can't do this:
> 
> foo = 42;
> foo = NULL;
> foo = alloca(10);
> 
> Tainting does have some nice effects: we don't need extra bounds checks for
> "not in scratch space" for bcopy, since we can just use alloca taint to
> prove it; and we can use alloca taint to figure out whether to bounds-check
> things like subr args that might or might not be alloca.
> 
> The non-alloca-related parts of this have mostly been pushed into a later
> series. The only bit left in this series is actually used by it, the
> fault-handling improvements; dt_cg_probe_error can now emit an illegal value
> found in a register, and avoids using the regset machinery because that can
> try to spill to the stack, which can cause verifier failures if some regs
> are still uninitialized -- which is quite likely in a fault situation.
> 
> Kris Van Hees (1):
>   alloca: deref
> 
> Nick Alcock (9):
>   alloca: track alloca()ed allocations
>   cg: fault improvements
>   alloca: new bad-size fault
>   alloca: add alloca() itself
>   alloca: bcopy
>   cg: support casts of pointers to integers
>   cg: support null pointers in ternary conditionals
>   cg: move dt_regset_xalloc for consistency
>   alloca: allow passing alloca pointers to actions and subrs
> 
>  include/dtrace/faults_defines.h               |   1 +
>  include/dtrace/options_defines.h              |   3 +-
>  libdtrace/dt_bpf.c                            |  13 +
>  libdtrace/dt_cg.c                             | 501 +++++++++++++++---
>  libdtrace/dt_dctx.h                           |  24 +-
>  libdtrace/dt_dlibs.c                          |   1 +
>  libdtrace/dt_error.c                          |   1 +
>  libdtrace/dt_errtags.h                        |   2 +
>  libdtrace/dt_handle.c                         |   1 +
>  libdtrace/dt_ident.c                          |  18 +-
>  libdtrace/dt_ident.h                          |   2 +
>  libdtrace/dt_open.c                           |  10 +-
>  libdtrace/dt_options.c                        |  16 +
>  libdtrace/dt_parser.c                         | 228 +++++++-
>  libdtrace/dt_parser.h                         |   5 +-
>  libdtrace/dt_pcb.h                            |   1 +
>  test/unittest/dif/alloca.d                    |   3 +-
>  .../alloca/err.D_ALLOCA_INCOMPAT.ternary.d    |  26 +
>  .../alloca/err.D_ALLOCA_INCOMPAT.ternary.r    |   2 +
>  ...rr.D_ALLOCA_INCOMPAT.var-clash-non-first.d |  28 +
>  ...rr.D_ALLOCA_INCOMPAT.var-clash-non-first.r |   2 +
>  .../alloca/err.D_ALLOCA_INCOMPAT.var-clash.d  |  30 ++
>  .../alloca/err.D_ALLOCA_INCOMPAT.var-clash.r  |   2 +
>  .../alloca/err.alloca-bcopy-before-beyond.d   |  27 +
>  .../alloca/err.alloca-bcopy-before-beyond.r   |   3 +
>  .../alloca/err.alloca-bcopy-before-bottom.d   |  27 +
>  .../alloca/err.alloca-bcopy-before-bottom.r   |   3 +
>  .../alloca/err.alloca-bcopy-beyond-top.d      |  27 +
>  .../alloca/err.alloca-bcopy-beyond-top.r      |   3 +
>  .../alloca/err.alloca-bcopy-crossing-bottom.d |  27 +
>  .../alloca/err.alloca-bcopy-crossing-bottom.r |   3 +
>  .../alloca/err.alloca-bcopy-crossing-top.d    |  27 +
>  .../alloca/err.alloca-bcopy-crossing-top.r    |   3 +
>  .../alloca/err.alloca-crossing-clauses.d      |  31 ++
>  .../alloca/err.alloca-crossing-clauses.r      |   3 +
>  .../alloca/err.alloca-load-before-bottom.d    |  26 +
>  .../alloca/err.alloca-load-before-bottom.r    |   3 +
>  .../funcs/alloca/err.alloca-load-beyond-top.d |  28 +
>  .../funcs/alloca/err.alloca-load-beyond-top.r |   3 +
>  .../alloca/err.alloca-load-crossing-bottom.d  |  25 +
>  .../alloca/err.alloca-load-crossing-bottom.r  |   3 +
>  .../alloca/err.alloca-null-deref-lvalue.d     |  29 +
>  .../alloca/err.alloca-null-deref-lvalue.r     |   3 +
>  .../funcs/alloca/err.alloca-null-deref.d      |  27 +
>  .../funcs/alloca/err.alloca-null-deref.r      |   3 +
>  .../err.alloca-scratch-exceeding-bcopy.d      |  36 ++
>  .../err.alloca-scratch-exceeding-bcopy.r      |   3 +
>  .../alloca/err.alloca-store-before-bottom.d   |  26 +
>  .../alloca/err.alloca-store-before-bottom.r   |   3 +
>  .../alloca/err.alloca-store-beyond-top.d      |  28 +
>  .../alloca/err.alloca-store-beyond-top.r      |   3 +
>  .../alloca/err.alloca-store-crossing-bottom.d |  26 +
>  .../alloca/err.alloca-store-crossing-bottom.r |   3 +
>  .../funcs/alloca/tst.alloca-alignment.d       |  34 ++
>  .../funcs/alloca/tst.alloca-bcopy-top.d       |  28 +
>  .../funcs/alloca/tst.alloca-bcopy-top.r       |   2 +
>  .../alloca/tst.alloca-crossing-clauses.d      |  33 ++
>  test/unittest/funcs/alloca/tst.alloca-funcs.d | 164 ++++++
>  test/unittest/funcs/alloca/tst.alloca-funcs.r |   2 +
>  .../funcs/alloca/tst.alloca-overtainting.sh   |  35 ++
>  .../alloca/tst.alloca-scratch-filling-bcopy.d |  31 ++
>  ....alloca-store-load-aliasing-arith-bottom.d |  29 +
>  ....alloca-store-load-aliasing-arith-bottom.r |   1 +
>  .../tst.alloca-store-load-aliasing-arith.d    |  29 +
>  .../alloca/tst.alloca-store-load-bottom.d     |  27 +
>  .../alloca/tst.alloca-store-load-idx-1.d      |  27 +
>  .../funcs/alloca/tst.alloca-store-load-top.d  |  27 +
>  .../alloca/tst.alloca0-after-alloca-load.d    |  28 +
>  .../funcs/alloca/tst.alloca0-after-alloca.d   |  26 +
>  test/unittest/funcs/alloca/tst.alloca0-load.d |  27 +
>  .../funcs/alloca/tst.alloca0-values.sh        |  34 ++
>  test/unittest/funcs/alloca/tst.alloca0.d      |  25 +
>  .../unittest/funcs/alloca/tst.string-alloca.d |  29 +
>  .../unittest/funcs/alloca/tst.string-alloca.r |   1 +
>  test/unittest/funcs/alloca/tst.ternary.d      |  27 +
>  .../funcs/err.D_ALLOCA_SIZE.big_alloca.d      |  24 +
>  .../funcs/err.D_ALLOCA_SIZE.big_alloca.r      |   2 +
>  test/unittest/funcs/err.badalloca.r           |   3 +
>  test/unittest/funcs/err.badalloca.r.p         |   3 +
>  test/unittest/funcs/err.badalloca2.d          |   3 +-
>  test/unittest/funcs/err.badalloca2.r          |   6 +-
>  test/unittest/funcs/err.badbcopy.r            |   4 +
>  test/unittest/funcs/err.badbcopy1.r           |   3 +
>  test/unittest/funcs/err.badbcopy2.r           |   4 +
>  test/unittest/funcs/err.badbcopy3.r           |   4 +
>  test/unittest/funcs/err.badbcopy4.d           |   1 -
>  test/unittest/funcs/err.badbcopy4.r           |   2 +-
>  test/unittest/funcs/err.badbcopy5.d           |   1 -
>  test/unittest/funcs/err.badbcopy5.r           |   2 +-
>  test/unittest/funcs/err.badbcopy6.d           |   1 -
>  test/unittest/funcs/err.badbcopy6.r           |   2 +-
>  .../funcs/{tst.bcopy.d => err.badbcopy7.d}    |  17 +-
>  test/unittest/funcs/err.badbcopy7.r           |   4 +
>  .../{err.badbcopy5.d => err.badbcopy8.d}      |  13 +-
>  test/unittest/funcs/err.badbcopy8.r           |   3 +
>  test/unittest/funcs/tst.bcopy.d               |  12 +-
>  ...st.ValidPointer2.d => err.AllocaOverrun.d} |  11 +-
>  test/unittest/pointers/err.AllocaOverrun.r    |   3 +
>  test/unittest/pointers/tst.ValidPointer1.d    |   1 -
>  ...CA_INCOMPAT.alloca-postinc-instantiation.d |  21 +
>  ...CA_INCOMPAT.alloca-postinc-instantiation.r |   2 +
>  .../tst.alloca-postinc-instantiation.d        |  46 ++
>  102 files changed, 2123 insertions(+), 123 deletions(-)
>  create mode 100644 test/unittest/funcs/alloca/err.D_ALLOCA_INCOMPAT.ternary.d
>  create mode 100644 test/unittest/funcs/alloca/err.D_ALLOCA_INCOMPAT.ternary.r
>  create mode 100644 test/unittest/funcs/alloca/err.D_ALLOCA_INCOMPAT.var-clash-non-first.d
>  create mode 100644 test/unittest/funcs/alloca/err.D_ALLOCA_INCOMPAT.var-clash-non-first.r
>  create mode 100644 test/unittest/funcs/alloca/err.D_ALLOCA_INCOMPAT.var-clash.d
>  create mode 100644 test/unittest/funcs/alloca/err.D_ALLOCA_INCOMPAT.var-clash.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-before-beyond.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-before-beyond.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-before-bottom.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-before-bottom.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-beyond-top.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-beyond-top.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-crossing-bottom.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-crossing-bottom.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-crossing-top.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-bcopy-crossing-top.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-crossing-clauses.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-crossing-clauses.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-load-before-bottom.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-load-before-bottom.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-load-beyond-top.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-load-beyond-top.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-load-crossing-bottom.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-load-crossing-bottom.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-null-deref-lvalue.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-null-deref-lvalue.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-null-deref.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-null-deref.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-scratch-exceeding-bcopy.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-scratch-exceeding-bcopy.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-store-before-bottom.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-store-before-bottom.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-store-beyond-top.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-store-beyond-top.r
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-store-crossing-bottom.d
>  create mode 100644 test/unittest/funcs/alloca/err.alloca-store-crossing-bottom.r
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-alignment.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-bcopy-top.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-bcopy-top.r
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-crossing-clauses.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-funcs.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-funcs.r
>  create mode 100755 test/unittest/funcs/alloca/tst.alloca-overtainting.sh
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-scratch-filling-bcopy.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-store-load-aliasing-arith-bottom.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-store-load-aliasing-arith-bottom.r
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-store-load-aliasing-arith.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-store-load-bottom.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-store-load-idx-1.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca-store-load-top.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca0-after-alloca-load.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca0-after-alloca.d
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca0-load.d
>  create mode 100755 test/unittest/funcs/alloca/tst.alloca0-values.sh
>  create mode 100644 test/unittest/funcs/alloca/tst.alloca0.d
>  create mode 100644 test/unittest/funcs/alloca/tst.string-alloca.d
>  create mode 100644 test/unittest/funcs/alloca/tst.string-alloca.r
>  create mode 100644 test/unittest/funcs/alloca/tst.ternary.d
>  create mode 100644 test/unittest/funcs/err.D_ALLOCA_SIZE.big_alloca.d
>  create mode 100644 test/unittest/funcs/err.D_ALLOCA_SIZE.big_alloca.r
>  create mode 100644 test/unittest/funcs/err.badalloca.r
>  create mode 100755 test/unittest/funcs/err.badalloca.r.p
>  create mode 100644 test/unittest/funcs/err.badbcopy.r
>  create mode 100644 test/unittest/funcs/err.badbcopy1.r
>  create mode 100644 test/unittest/funcs/err.badbcopy2.r
>  create mode 100644 test/unittest/funcs/err.badbcopy3.r
>  copy test/unittest/funcs/{tst.bcopy.d => err.badbcopy7.d} (64%)
>  create mode 100644 test/unittest/funcs/err.badbcopy7.r
>  copy test/unittest/funcs/{err.badbcopy5.d => err.badbcopy8.d} (63%)
>  create mode 100644 test/unittest/funcs/err.badbcopy8.r
>  rename test/unittest/pointers/{tst.ValidPointer2.d => err.AllocaOverrun.d} (62%)
>  create mode 100644 test/unittest/pointers/err.AllocaOverrun.r
>  create mode 100644 test/unittest/predicates/err.D_ALLOCA_INCOMPAT.alloca-postinc-instantiation.d
>  create mode 100644 test/unittest/predicates/err.D_ALLOCA_INCOMPAT.alloca-postinc-instantiation.r
>  create mode 100644 test/unittest/predicates/tst.alloca-postinc-instantiation.d
> 
> -- 
> 2.35.1



More information about the DTrace-devel mailing list