mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
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
This commit is contained in:
parent
38a137f416
commit
dd2a6cd701
7 changed files with 54 additions and 43 deletions
|
|
@ -277,6 +277,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_ */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -431,6 +431,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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,6 +204,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_ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue