[DTrace-devel] [PATCH] Use highest bit to decide if PC is user space or kernel
Kris Van Hees
kris.van.hees at oracle.com
Tue Feb 28 00:53:37 UTC 2023
On Mon, Feb 27, 2023 at 07:23:29PM -0500, eugene.loh--- via DTrace-devel wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
>
> Currently, we decide if a PC is user space or kernel based on whether
> the BPF helper function probe_read_kernel() can read the address.
> On systems where this BPF helper function does not exist, there is a
> back-up mechanism that simply checks the highest bit of the PC.
>
> Apparently, on some systems, the helper function can read addresses
> even in user space. That is, the mechanism that uses the helper function
> is not reliable.
>
> So, just use the "back-up mechanism" all the time.
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
... even though it is (sadly) a very ugly patch. But necessary and I do agree
that keeping the existing code around makes a lot of sense here because there
ought to be a better way to handle this.
> ---
> libdtrace/dt_cg.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 4791536b..ac99d3dd 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -414,7 +414,6 @@ dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int called)
> void
> dt_cg_tramp_copy_pc_from_regs(dt_pcb_t *pcb)
> {
> - dtrace_hdl_t *dtp = pcb->pcb_hdl;
> dt_regset_t *drp = pcb->pcb_regs;
> dt_irlist_t *dlp = &pcb->pcb_ir;
> uint_t Luser = dt_irlist_label(dlp);
> @@ -429,7 +428,18 @@ dt_cg_tramp_copy_pc_from_regs(dt_pcb_t *pcb)
> emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_3));
>
> /* check if the PC is kernel or user space */
> - if (dtp->dt_bpfhelper[BPF_FUNC_probe_read_kernel] == BPF_FUNC_probe_read_kernel) {
> +#if 0
> + if (pcb->pcb_hdl->dt_bpfhelper[BPF_FUNC_probe_read_kernel]
> + == BPF_FUNC_probe_read_kernel) {
> +#else
> + /*
> + * We do not seem to be guaranteed for some kernels that
> + * probe_read_kernel(), even if it exists, will signal an error
> + * when reading user space addresses. So, do not use the
> + * probe_read_kernel() mechanism for now.
> + */
> + if (0) {
> +#endif
> /*
> * Use probe_read_kernel() if it is really is probe_read_kernel().
> * On older kernels, it does not exist and is aliased to something else.
> @@ -452,7 +462,6 @@ dt_cg_tramp_copy_pc_from_regs(dt_pcb_t *pcb)
> } else {
> /*
> * If no real probe_read_kernel() exists, just test the highest bit.
> - * This is not as robust, but probably works just fine for us.
> */
>
> /* if the highest bit is 0, assume it was user space */
> --
> 2.18.4
>
>
> _______________________________________________
> 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