dtrace: add support for SMAP

Add support in dtrace for SMAP, so that actions like copyinstr() work.
It would be better if dtrace could use the SMAP_* hotpatch macros directly,
but the hotpatching code does not currently operate on kernel modules,
so we'll use some tiny functions in the base kernel for now.
This commit is contained in:
chs 2023-11-03 09:07:56 +00:00
parent f52c4ec833
commit feabd72f0c
4 changed files with 70 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: dtrace_asm.S,v 1.8 2018/05/28 21:05:03 chs Exp $ */ /* $NetBSD: dtrace_asm.S,v 1.9 2023/11/03 09:07:56 chs Exp $ */
/* /*
* CDDL HEADER START * CDDL HEADER START
@ -39,6 +39,11 @@
#include "assym.h" #include "assym.h"
#define DTRACE_SMAP_DISABLE \
call dtrace_smap_disable
#define DTRACE_SMAP_ENABLE \
call dtrace_smap_enable
#define INTR_POP \ #define INTR_POP \
MEXITCOUNT; \ MEXITCOUNT; \
movq TF_RDI(%rsp),%rdi; \ movq TF_RDI(%rsp),%rdi; \
@ -217,8 +222,10 @@ dtrace_copy(uintptr_t src, uintptr_t dest, size_t size)
xchgq %rdi, %rsi /* make %rsi source, %rdi dest */ xchgq %rdi, %rsi /* make %rsi source, %rdi dest */
movq %rdx, %rcx /* load count */ movq %rdx, %rcx /* load count */
DTRACE_SMAP_DISABLE
repz /* repeat for count ... */ repz /* repeat for count ... */
smovb /* move from %ds:rsi to %ed:rdi */ smovb /* move from %ds:rsi to %ed:rdi */
DTRACE_SMAP_ENABLE
leave leave
ret ret
END(dtrace_copy) END(dtrace_copy)
@ -231,6 +238,7 @@ dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
ENTRY(dtrace_copystr) ENTRY(dtrace_copystr)
pushq %rbp pushq %rbp
movq %rsp, %rbp movq %rsp, %rbp
DTRACE_SMAP_DISABLE
0: 0:
movb (%rdi), %al /* load from source */ movb (%rdi), %al /* load from source */
@ -248,6 +256,7 @@ dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
cmpq $0, %rdx cmpq $0, %rdx
jne 0b jne 0b
2: 2:
DTRACE_SMAP_ENABLE
leave leave
ret ret
@ -258,7 +267,9 @@ uintptr_t
dtrace_fulword(void *addr) dtrace_fulword(void *addr)
*/ */
ENTRY(dtrace_fulword) ENTRY(dtrace_fulword)
DTRACE_SMAP_DISABLE
movq (%rdi), %rax movq (%rdi), %rax
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fulword) END(dtrace_fulword)
@ -268,7 +279,9 @@ dtrace_fuword8_nocheck(void *addr)
*/ */
ENTRY(dtrace_fuword8_nocheck) ENTRY(dtrace_fuword8_nocheck)
xorq %rax, %rax xorq %rax, %rax
DTRACE_SMAP_DISABLE
movb (%rdi), %al movb (%rdi), %al
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fuword8_nocheck) END(dtrace_fuword8_nocheck)
@ -278,7 +291,9 @@ dtrace_fuword16_nocheck(void *addr)
*/ */
ENTRY(dtrace_fuword16_nocheck) ENTRY(dtrace_fuword16_nocheck)
xorq %rax, %rax xorq %rax, %rax
DTRACE_SMAP_DISABLE
movw (%rdi), %ax movw (%rdi), %ax
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fuword16_nocheck) END(dtrace_fuword16_nocheck)
@ -288,7 +303,9 @@ dtrace_fuword32_nocheck(void *addr)
*/ */
ENTRY(dtrace_fuword32_nocheck) ENTRY(dtrace_fuword32_nocheck)
xorq %rax, %rax xorq %rax, %rax
DTRACE_SMAP_DISABLE
movl (%rdi), %eax movl (%rdi), %eax
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fuword32_nocheck) END(dtrace_fuword32_nocheck)
@ -297,7 +314,9 @@ uint64_t
dtrace_fuword64_nocheck(void *addr) dtrace_fuword64_nocheck(void *addr)
*/ */
ENTRY(dtrace_fuword64_nocheck) ENTRY(dtrace_fuword64_nocheck)
DTRACE_SMAP_DISABLE
movq (%rdi), %rax movq (%rdi), %rax
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fuword64_nocheck) END(dtrace_fuword64_nocheck)

View File

@ -1,4 +1,4 @@
/* $NetBSD: dtrace_asm.S,v 1.7 2018/05/28 21:05:03 chs Exp $ */ /* $NetBSD: dtrace_asm.S,v 1.8 2023/11/03 09:07:57 chs Exp $ */
/* /*
* CDDL HEADER START * CDDL HEADER START
@ -38,6 +38,11 @@
#include <machine/frameasm.h> #include <machine/frameasm.h>
#include <machine/trap.h> #include <machine/trap.h>
#define DTRACE_SMAP_DISABLE \
call dtrace_smap_disable
#define DTRACE_SMAP_ENABLE \
call dtrace_smap_enable
#define INTR_POP \ #define INTR_POP \
addl $16, %esp; \ addl $16, %esp; \
popl %edi; \ popl %edi; \
@ -225,8 +230,10 @@ void dtrace_copy(uintptr_t src, uintptr_t dest, size_t size)
movl 8(%ebp), %esi /* Load source address */ movl 8(%ebp), %esi /* Load source address */
movl 12(%ebp), %edi /* Load destination address */ movl 12(%ebp), %edi /* Load destination address */
movl 16(%ebp), %ecx /* Load count */ movl 16(%ebp), %ecx /* Load count */
DTRACE_SMAP_DISABLE
repz /* Repeat for count... */ repz /* Repeat for count... */
smovb /* move from %ds:si to %es:di */ smovb /* move from %ds:si to %es:di */
DTRACE_SMAP_ENABLE
popl %edi popl %edi
popl %esi popl %esi
@ -248,6 +255,7 @@ void dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size)
movl 8(%ebp), %ebx /* Load source address */ movl 8(%ebp), %ebx /* Load source address */
movl 12(%ebp), %edx /* Load destination address */ movl 12(%ebp), %edx /* Load destination address */
movl 16(%ebp), %ecx /* Load count */ movl 16(%ebp), %ecx /* Load count */
DTRACE_SMAP_DISABLE
0: 0:
movb (%ebx), %al /* Load from source */ movb (%ebx), %al /* Load from source */
@ -261,6 +269,7 @@ void dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size)
jne 0b jne 0b
1: 1:
DTRACE_SMAP_ENABLE
popl %ebx popl %ebx
movl %ebp, %esp movl %ebp, %esp
popl %ebp popl %ebp
@ -275,7 +284,9 @@ uintptr_t dtrace_fulword(void *addr)
ENTRY(dtrace_fulword) ENTRY(dtrace_fulword)
movl 4(%esp), %ecx movl 4(%esp), %ecx
xorl %eax, %eax xorl %eax, %eax
DTRACE_SMAP_DISABLE
movl (%ecx), %eax movl (%ecx), %eax
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fulword) END(dtrace_fulword)
@ -286,7 +297,9 @@ uint8_t dtrace_fuword8_nocheck(void *addr)
ENTRY(dtrace_fuword8_nocheck) ENTRY(dtrace_fuword8_nocheck)
movl 4(%esp), %ecx movl 4(%esp), %ecx
xorl %eax, %eax xorl %eax, %eax
DTRACE_SMAP_DISABLE
movzbl (%ecx), %eax movzbl (%ecx), %eax
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fuword8_nocheck) END(dtrace_fuword8_nocheck)
@ -297,7 +310,9 @@ uint16_t dtrace_fuword16_nocheck(void *addr)
ENTRY(dtrace_fuword16_nocheck) ENTRY(dtrace_fuword16_nocheck)
movl 4(%esp), %ecx movl 4(%esp), %ecx
xorl %eax, %eax xorl %eax, %eax
DTRACE_SMAP_DISABLE
movzwl (%ecx), %eax movzwl (%ecx), %eax
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fuword16_nocheck) END(dtrace_fuword16_nocheck)
@ -308,7 +323,9 @@ uint32_t dtrace_fuword32_nocheck(void *addr)
ENTRY(dtrace_fuword32_nocheck) ENTRY(dtrace_fuword32_nocheck)
movl 4(%esp), %ecx movl 4(%esp), %ecx
xorl %eax, %eax xorl %eax, %eax
DTRACE_SMAP_DISABLE
movl (%ecx), %eax movl (%ecx), %eax
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fuword32_nocheck) END(dtrace_fuword32_nocheck)
@ -320,8 +337,10 @@ uint64_t dtrace_fuword64_nocheck(void *addr)
movl 4(%esp), %ecx movl 4(%esp), %ecx
xorl %eax, %eax xorl %eax, %eax
xorl %edx, %edx xorl %edx, %edx
DTRACE_SMAP_DISABLE
movl (%ecx), %eax movl (%ecx), %eax
movl 4(%ecx), %edx movl 4(%ecx), %edx
DTRACE_SMAP_ENABLE
ret ret
END(dtrace_fuword64_nocheck) END(dtrace_fuword64_nocheck)

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpufunc.S,v 1.66 2023/10/04 20:28:05 ad Exp $ */ /* $NetBSD: cpufunc.S,v 1.67 2023/11/03 09:07:56 chs Exp $ */
/* /*
* Copyright (c) 1998, 2007, 2008, 2020, 2023 The NetBSD Foundation, Inc. * Copyright (c) 1998, 2007, 2008, 2020, 2023 The NetBSD Foundation, Inc.
@ -36,6 +36,7 @@
#include <machine/specialreg.h> #include <machine/specialreg.h>
#include <machine/segments.h> #include <machine/segments.h>
#include "opt_dtrace.h"
#include "opt_xen.h" #include "opt_xen.h"
#include "opt_svs.h" #include "opt_svs.h"
@ -177,6 +178,18 @@ ENTRY(smap_disable)
ret ret
END(smap_disable) END(smap_disable)
#ifdef KDTRACE_HOOKS
ENTRY(dtrace_smap_enable)
SMAP_ENABLE
ret
END(dtrace_smap_enable)
ENTRY(dtrace_smap_disable)
SMAP_DISABLE
ret
END(dtrace_smap_disable)
#endif
/* /*
* %rdi = name * %rdi = name
* %rsi = sel * %rsi = sel

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpufunc.S,v 1.50 2023/10/04 20:28:05 ad Exp $ */ /* $NetBSD: cpufunc.S,v 1.51 2023/11/03 09:07:56 chs Exp $ */
/*- /*-
* Copyright (c) 1998, 2007, 2020, 2023 The NetBSD Foundation, Inc. * Copyright (c) 1998, 2007, 2020, 2023 The NetBSD Foundation, Inc.
@ -38,8 +38,10 @@
#include <sys/errno.h> #include <sys/errno.h>
#include <machine/asm.h> #include <machine/asm.h>
__KERNEL_RCSID(0, "$NetBSD: cpufunc.S,v 1.50 2023/10/04 20:28:05 ad Exp $"); #include <machine/frameasm.h>
__KERNEL_RCSID(0, "$NetBSD: cpufunc.S,v 1.51 2023/11/03 09:07:56 chs Exp $");
#include "opt_dtrace.h"
#include "opt_xen.h" #include "opt_xen.h"
#include <machine/specialreg.h> #include <machine/specialreg.h>
@ -72,6 +74,18 @@ ENTRY(lidt)
ret ret
END(lidt) END(lidt)
#ifdef KDTRACE_HOOKS
ENTRY(dtrace_smap_enable)
SMAP_ENABLE
ret
END(dtrace_smap_enable)
ENTRY(dtrace_smap_disable)
SMAP_DISABLE
ret
END(dtrace_smap_disable)
#endif
ENTRY(x86_hotpatch) ENTRY(x86_hotpatch)
/* save EFLAGS, and disable intrs */ /* save EFLAGS, and disable intrs */
pushfl pushfl