git: 9480640957ff - stable/13 - linux(4): Make ptrace_peekusr machine dependend
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 29 Jun 2023 08:20:35 UTC
The branch stable/13 has been updated by dchagin:
URL: https://cgit.FreeBSD.org/src/commit/?id=9480640957ff48c6bc7c0ea5d4f3eb5930f417e3
commit 9480640957ff48c6bc7c0ea5d4f3eb5930f417e3
Author: Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2023-05-18 17:00:12 +0000
Commit: Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2023-06-29 08:15:59 +0000
linux(4): Make ptrace_peekusr machine dependend
And partially implement it for x86_64.
Differential Revision: https://reviews.freebsd.org/D40095
MFC after: 1 week
(cherry picked from commit dd2a6cd701aea5a6ced59b9947e087304f7d7238)
---
sys/amd64/linux/linux.h | 2 ++
sys/amd64/linux/linux_machdep.c | 31 ++++++++++++++++++++++++++
sys/amd64/linux32/linux.h | 2 ++
sys/amd64/linux32/linux32_machdep.c | 9 ++++++++
sys/arm64/linux/linux.h | 2 ++
sys/arm64/linux/linux_machdep.c | 8 +++++++
sys/compat/linux/linux_ptrace.c | 43 -------------------------------------
7 files changed, 54 insertions(+), 43 deletions(-)
diff --git a/sys/amd64/linux/linux.h b/sys/amd64/linux/linux.h
index a5682c6a980d..57f1ee0115e6 100644
--- a/sys/amd64/linux/linux.h
+++ b/sys/amd64/linux/linux.h
@@ -322,6 +322,8 @@ void linux_ptrace_get_syscall_info_machdep(const struct reg *reg,
struct syscall_info *si);
int linux_ptrace_getregs_machdep(struct thread *td, pid_t pid,
struct linux_pt_regset *l_regset);
+int linux_ptrace_peekuser(struct thread *td, pid_t pid,
+ void *addr, void *data);
#endif /* _KERNEL */
#endif /* !_AMD64_LINUX_H_ */
diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c
index 6c96dd496fdc..233d66a40899 100644
--- a/sys/amd64/linux/linux_machdep.c
+++ b/sys/amd64/linux/linux_machdep.c
@@ -367,3 +367,34 @@ linux_ptrace_getregs_machdep(struct thread *td, pid_t pid,
return (0);
}
+
+#define LINUX_URO(a,m) ((uintptr_t)a == offsetof(struct linux_pt_regset, m))
+
+int
+linux_ptrace_peekuser(struct thread *td, pid_t pid, void *addr, void *data)
+{
+ struct linux_pt_regset reg;
+ struct reg b_reg;
+ uint64_t val;
+ int error;
+
+ if ((uintptr_t)addr & (sizeof(data) -1) || (uintptr_t)addr < 0)
+ return (EIO);
+ if ((uintptr_t)addr >= sizeof(struct linux_pt_regset)) {
+ LINUX_RATELIMIT_MSG_OPT1("PTRACE_PEEKUSER offset %ld "
+ "not implemented; returning EINVAL", (uintptr_t)addr);
+ return (EINVAL);
+ }
+
+ if (LINUX_URO(addr, fs_base))
+ return (kern_ptrace(td, PT_GETFSBASE, pid, data, 0));
+ if (LINUX_URO(addr, gs_base))
+ return (kern_ptrace(td, PT_GETGSBASE, pid, data, 0));
+ if ((error = kern_ptrace(td, PT_GETREGS, pid, &b_reg, 0)) != 0)
+ return (error);
+ bsd_to_linux_regset(&b_reg, ®);
+ val = *(®.r15 + ((uintptr_t)addr / sizeof(reg.r15)));
+ return (copyout(&val, data, sizeof(val)));
+}
+
+#undef LINUX_URO
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index 32f2f42b0108..a98777adeaf5 100644
--- a/sys/amd64/linux32/linux.h
+++ b/sys/amd64/linux32/linux.h
@@ -465,6 +465,8 @@ struct reg32;
void bsd_to_linux_regset32(const struct reg32 *b_reg,
struct linux_pt_regset32 *l_regset);
+int linux_ptrace_peekuser(struct thread *td, pid_t pid,
+ void *addr, void *data);
extern bool linux32_emulate_i386;
#endif /* _KERNEL */
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index 0bd398042c3f..afc60fb7e822 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -742,3 +742,12 @@ DEFINE_IFUNC(, int, futex_xorl, (int, uint32_t *, int *))
return ((cpu_stdext_feature & CPUID_STDEXT_SMAP) != 0 ?
futex_xorl_smap : futex_xorl_nosmap);
}
+
+int
+linux_ptrace_peekuser(struct thread *td, pid_t pid, void *addr, void *data)
+{
+
+ LINUX_RATELIMIT_MSG_OPT1("PTRACE_PEEKUSER offset %ld not implemented; "
+ "returning EINVAL", (uintptr_t)addr);
+ return (EINVAL);
+}
diff --git a/sys/arm64/linux/linux.h b/sys/arm64/linux/linux.h
index 5a391c3543d3..be6733c81d97 100644
--- a/sys/arm64/linux/linux.h
+++ b/sys/arm64/linux/linux.h
@@ -238,6 +238,8 @@ void linux_ptrace_get_syscall_info_machdep(const struct reg *reg,
struct syscall_info *si);
int linux_ptrace_getregs_machdep(struct thread *td, pid_t pid,
struct linux_pt_regset *l_regset);
+int linux_ptrace_peekuser(struct thread *td, pid_t pid,
+ void *addr, void *data);
#endif /* _KERNEL */
#endif /* _ARM64_LINUX_H_ */
diff --git a/sys/arm64/linux/linux_machdep.c b/sys/arm64/linux/linux_machdep.c
index 4b12476f7865..2e472869eedb 100644
--- a/sys/arm64/linux/linux_machdep.c
+++ b/sys/arm64/linux/linux_machdep.c
@@ -152,3 +152,11 @@ linux_ptrace_getregs_machdep(struct thread *td __unused, pid_t pid __unused,
return (0);
}
+int
+linux_ptrace_peekuser(struct thread *td, pid_t pid, void *addr, void *data)
+{
+
+ LINUX_RATELIMIT_MSG_OPT1("PTRACE_PEEKUSER offset %ld not implemented; "
+ "returning EINVAL", (uintptr_t)addr);
+ return (EINVAL);
+}
diff --git a/sys/compat/linux/linux_ptrace.c b/sys/compat/linux/linux_ptrace.c
index 151355d2bb3f..c1c7abf70a9d 100644
--- a/sys/compat/linux/linux_ptrace.c
+++ b/sys/compat/linux/linux_ptrace.c
@@ -100,11 +100,6 @@ __FBSDID("$FreeBSD$");
#define LINUX_PTRACE_SYSCALL_INFO_ENTRY 1
#define LINUX_PTRACE_SYSCALL_INFO_EXIT 2
-#define LINUX_PTRACE_PEEKUSER_ORIG_RAX 120
-#define LINUX_PTRACE_PEEKUSER_RIP 128
-#define LINUX_PTRACE_PEEKUSER_CS 136
-#define LINUX_PTRACE_PEEKUSER_DS 184
-
static int
map_signum(int lsig, int *bsigp)
{
@@ -179,44 +174,6 @@ linux_ptrace_peek(struct thread *td, pid_t pid, void *addr, void *data)
return (error);
}
-static int
-linux_ptrace_peekuser(struct thread *td, pid_t pid, void *addr, void *data)
-{
- struct reg b_reg;
- uint64_t val;
- int error;
-
- error = kern_ptrace(td, PT_GETREGS, pid, &b_reg, 0);
- if (error != 0)
- return (error);
-
- switch ((uintptr_t)addr) {
-#ifdef __amd64__
- case LINUX_PTRACE_PEEKUSER_ORIG_RAX:
- val = b_reg.r_rax;
- break;
- case LINUX_PTRACE_PEEKUSER_RIP:
- val = b_reg.r_rip;
- break;
- case LINUX_PTRACE_PEEKUSER_CS:
- val = b_reg.r_cs;
- break;
- case LINUX_PTRACE_PEEKUSER_DS:
- val = b_reg.r_ds;
- break;
-#endif /* __amd64__ */
- default:
- linux_msg(td, "PTRACE_PEEKUSER offset %ld not implemented; "
- "returning EINVAL", (uintptr_t)addr);
- return (EINVAL);
- }
-
- error = copyout(&val, data, sizeof(val));
- td->td_retval[0] = error;
-
- return (error);
-}
-
static int
linux_ptrace_pokeuser(struct thread *td, pid_t pid, void *addr, void *data)
{