Enable ptrace intercept on powerpc.

Tested on ppc64 and ppc64le.
This commit is contained in:
Todd C. Miller
2022-05-11 20:07:59 -06:00
parent 040e75a07b
commit 31e8506c82
3 changed files with 72 additions and 22 deletions

View File

@@ -58,9 +58,9 @@ static inline void
set_sc_retval(struct sudo_ptrace_regs *regs, int retval)
{
if (regs->compat) {
compat_reg_retval(regs->u.compat) = retval;
compat_reg_set_retval(regs->u.compat, retval);
} else {
reg_retval(regs->u.native) = retval;
reg_set_retval(regs->u.native, retval);
}
}
@@ -175,7 +175,7 @@ get_stack_pointer(struct sudo_ptrace_regs *regs)
static inline void
set_sc_retval(struct sudo_ptrace_regs *regs, int retval)
{
reg_retval(regs->u.native) = retval;
reg_set_retval(regs->u.native, retval);
}
static inline int

View File

@@ -107,32 +107,37 @@
# define reg_arg2(x) (x).ecx
# define reg_arg3(x) (x).edx
# define reg_arg4(x) (x).esi
#elif defined(__powerpc64__)
/* Untested */
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_PPC64LE
#elif defined(__powerpc__)
# if defined(__powerpc64__)
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_PPC64LE
# else
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_PPC64
# endif
# else
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_PPC64
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_PPC
# endif
# define user_pt_regs pt_regs
# define reg_syscall(x) (x).gpr[0] /* r0 */
# define reg_retval(x) (x).gpr[3] /* r3 */
# define reg_sp(x) (x).gpr[1] /* r1 */
# define reg_arg1(x) (x).gpr[3] /* r3 */
# define reg_arg2(x) (x).gpr[4] /* r4 */
# define reg_arg3(x) (x).gpr[5] /* r5 */
# define reg_arg4(x) (x).gpr[6] /* r6 */
#elif defined(__powerpc__)
/* Untested */
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_PPC
# define user_pt_regs pt_regs
# define reg_syscall(x) (x).gpr[0] /* r0 */
# define reg_retval(x) (x).gpr[3] /* r3 */
# define reg_sp(x) (x).gpr[1] /* r1 */
# define reg_arg1(x) (x).gpr[3] /* r3 */
# define reg_arg1(x) (x).orig_gpr3 /* r3 */
# define reg_arg2(x) (x).gpr[4] /* r4 */
# define reg_arg3(x) (x).gpr[5] /* r5 */
# define reg_arg4(x) (x).gpr[6] /* r6 */
# define reg_set_retval(_r, _v) do { \
if (((_r).trap & 0xfff0) == 0x3000) { \
/* scv 0 system call, uses negative error code for result. */ \
reg_retval(_r) = (_v); \
} else { \
/* \
* Set CR0 SO bit to indicate a syscall error, which is stored \
* as a positive error code. \
*/ \
reg_retval(_r) = -(_v); \
(_r).ccr |= 0x10000000; \
} \
} while (0)
#elif defined(__riscv) && __riscv_xlen == 64
/* Untested */
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_RISCV64
@@ -208,7 +213,7 @@ struct i386_user_regs_struct {
# define compat_reg_arg2(x) (x).ecx
# define compat_reg_arg3(x) (x).edx
# define compat_reg_arg4(x) (x).esi
#elif defined(__arm__)
#elif defined(__aarch64__)
struct arm_pt_regs {
unsigned int uregs[18];
};
@@ -223,6 +228,51 @@ struct arm_pt_regs {
# define compat_reg_arg2(x) (x).uregs[1] /* r1 */
# define compat_reg_arg3(x) (x).uregs[2] /* r2 */
# define compat_reg_arg4(x) (x).uregs[3] /* r3 */
#elif defined(__powerpc64__)
struct ppc_pt_regs {
unsigned int gpr[32];
unsigned int nip;
unsigned int msr;
unsigned int orig_gpr3;
unsigned int ctr;
unsigned int link;
unsigned int xer;
unsigned int ccr;
unsigned int mq;
unsigned int trap;
unsigned int dar;
unsigned int dsisr;
unsigned int result;
};
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
/* There is no AUDIT_ARCH_PPCLE define. */
# define SECCOMP_AUDIT_ARCH_COMPAT (AUDIT_ARCH_PPC|__AUDIT_ARCH_LE)
# else
# define SECCOMP_AUDIT_ARCH_COMPAT AUDIT_ARCH_PPC
# endif
# define COMPAT_execve __NR_execve
# define COMPAT_execveat __NR_execveat
# define compat_user_pt_regs ppc_pt_regs
# define compat_reg_syscall(x) (x).gpr[0] /* r0 */
# define compat_reg_retval(x) (x).gpr[3] /* r3 */
# define compat_reg_sp(x) (x).gpr[1] /* r1 */
# define compat_reg_arg1(x) (x).orig_gpr3 /* r3 */
# define compat_reg_arg2(x) (x).gpr[4] /* r4 */
# define compat_reg_arg3(x) (x).gpr[5] /* r5 */
# define compat_reg_arg4(x) (x).gpr[6] /* r6 */
# define compat_reg_set_retval(_r, _v) reg_set_retval(_r, _v)
#endif
/* Set the syscall return value the "normal" way by default. */
#ifndef reg_set_retval
# define reg_set_retval(_r, _v) do { \
reg_retval(_r) = (_v); \
} while (0)
#endif
#ifndef compat_reg_set_retval
# define compat_reg_set_retval(_r, _v) do { \
compat_reg_retval(_r) = (_v); \
} while (0)
#endif
struct sudo_ptrace_regs {

View File

@@ -96,7 +96,7 @@ union sudo_token_un {
*/
#if defined(_PATH_SUDO_INTERCEPT) && defined(__linux__)
# if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER
# if defined(__amd64__) || defined(__i386__) || defined(__aarch64__)
# if defined(__amd64__) || defined(__i386__) || defined(__aarch64__) || defined(__powerpc__)
# ifndef HAVE_PTRACE_INTERCEPT
# define HAVE_PTRACE_INTERCEPT 1
# endif /* HAVE_PTRACE_INTERCEPT */