Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 May 2023 15:43:57 GMT
From:      Christos Margiolis <christos@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 5c134fba225f - main - kinst: fix memcpy() tracing crash
Message-ID:  <202305261543.34QFhvsM069265@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by christos:

URL: https://cgit.FreeBSD.org/src/commit/?id=5c134fba225fabb2e0f9c763aaca0eeee81d8f9f

commit 5c134fba225fabb2e0f9c763aaca0eeee81d8f9f
Author:     Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2023-05-26 15:43:37 +0000
Commit:     Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2023-05-26 15:43:37 +0000

    kinst: fix memcpy() tracing crash
    
    Tracing memcpy() would crash the kernel, because we'd also trace the
    memcpy() calls from kinst_invop(). To fix this, introduce kinst_memcpy()
    whose arguments are 'volatile', so that we avoid having the compiler
    replace it with a regular memcpy().
    
    Reviewed by:    markj
    Approved by:    markj (mentor)
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D40284
---
 .../cmd/dtrace/test/tst/amd64/kinst/tst.basic.ksh   |  1 +
 sys/cddl/dev/kinst/amd64/kinst_isa.c                |  6 +++---
 sys/cddl/dev/kinst/kinst.c                          | 21 +++++++++++++++++++++
 sys/cddl/dev/kinst/kinst.h                          |  1 +
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/amd64/kinst/tst.basic.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/amd64/kinst/tst.basic.ksh
index e3585ca70793..3005da74c895 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/amd64/kinst/tst.basic.ksh
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/amd64/kinst/tst.basic.ksh
@@ -21,6 +21,7 @@ kinst::vm_fault: {}
 kinst::amd64_syscall: {}
 kinst::exit1: {}
 kinst::spinlock_enter: {}
+kinst::memcpy: {}
 
 tick-10s {exit(0);}
 __EOF__
diff --git a/sys/cddl/dev/kinst/amd64/kinst_isa.c b/sys/cddl/dev/kinst/amd64/kinst_isa.c
index 7aba79c1d481..d29f1cd4181f 100644
--- a/sys/cddl/dev/kinst/amd64/kinst_isa.c
+++ b/sys/cddl/dev/kinst/amd64/kinst_isa.c
@@ -107,10 +107,10 @@ kinst_trampoline_populate(struct kinst_probe *kp, uint8_t *tramp)
 
 	ilen = kp->kp_md.tinstlen;
 
-	memcpy(tramp, kp->kp_md.template, ilen);
+	kinst_memcpy(tramp, kp->kp_md.template, ilen);
 	if ((kp->kp_md.flags & KINST_F_RIPREL) != 0) {
 		disp = kinst_riprel_disp(kp, tramp);
-		memcpy(&tramp[kp->kp_md.dispoff], &disp, sizeof(uint32_t));
+		kinst_memcpy(&tramp[kp->kp_md.dispoff], &disp, sizeof(uint32_t));
 	}
 
 	/*
@@ -126,7 +126,7 @@ kinst_trampoline_populate(struct kinst_probe *kp, uint8_t *tramp)
 	tramp[ilen + 4] = 0x00;
 	tramp[ilen + 5] = 0x00;
 	instr = kp->kp_patchpoint + kp->kp_md.instlen;
-	memcpy(&tramp[ilen + 6], &instr, sizeof(uintptr_t));
+	kinst_memcpy(&tramp[ilen + 6], &instr, sizeof(uintptr_t));
 }
 
 int
diff --git a/sys/cddl/dev/kinst/kinst.c b/sys/cddl/dev/kinst/kinst.c
index 46b9bf2f41e8..e30b813e0400 100644
--- a/sys/cddl/dev/kinst/kinst.c
+++ b/sys/cddl/dev/kinst/kinst.c
@@ -65,6 +65,27 @@ static dtrace_provider_id_t	kinst_id;
 struct kinst_probe_list	*kinst_probetab;
 static struct cdev	*kinst_cdev;
 
+/*
+ * Tracing memcpy() will crash the kernel when kinst tries to trace an instance
+ * of the memcpy() calls in kinst_invop(). To fix this, we can use
+ * kinst_memcpy() in those cases, with its arguments marked as 'volatile' to
+ * "outsmart" the compiler and avoid having it replaced by a regular memcpy().
+ */
+volatile void *
+kinst_memcpy(volatile void *dst, volatile const void *src, size_t len)
+{
+	volatile const unsigned char *src0;
+	volatile unsigned char *dst0;
+
+	src0 = src;
+	dst0 = dst;
+
+	while (len--)
+		*dst0++ = *src0++;
+
+	return (dst);
+}
+
 int
 kinst_excluded(const char *name)
 {
diff --git a/sys/cddl/dev/kinst/kinst.h b/sys/cddl/dev/kinst/kinst.h
index ee756dc87d09..1107a274333f 100644
--- a/sys/cddl/dev/kinst/kinst.h
+++ b/sys/cddl/dev/kinst/kinst.h
@@ -46,6 +46,7 @@ extern struct kinst_probe_list	*kinst_probetab;
 struct linker_file;
 struct linker_symval;
 
+volatile void	*kinst_memcpy(volatile void *, volatile const void *, size_t);
 int	kinst_excluded(const char *);
 int	kinst_md_excluded(const char *);
 int	kinst_invop(uintptr_t, struct trapframe *, uintptr_t);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202305261543.34QFhvsM069265>