mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-05 00:41:03 +01:00
regression tests: have ptrace use PTRACE_GETREGSET by default
Merge from trunk revision 3169 Bug: https://bugs.launchpad.net/apparmor/+bug/1470985 The ptrace regression test fails to compile on the arm64 platform, because it uses PTRACE_GETREGS and not the newer PTRACE_GETREGSET interface for getting access to arch-specific register information[0]. However, fixing it is complicated by the fact that the struct name for for the general purpose registers is not named consistently across architectures. This patch attempts to address those issues, and compiles at least on i386, amd64, arm64, arm (armhf), ppc64, and ppc64el. The test is verified to continue to function correctly on i386 and amd64. [0] https://sourceware.org/ml/archer/2010-q3/msg00193.html Signed-off-by: Steve Beattie <steve@nxnw.org> Acked-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
b5a7142652
commit
7a82798f6b
1 changed files with 46 additions and 6 deletions
|
@ -7,7 +7,9 @@
|
|||
#include <sys/ptrace.h>
|
||||
#include <signal.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/uio.h>
|
||||
#include <errno.h>
|
||||
#include <elf.h>
|
||||
|
||||
#define NUM_CHLD_SYSCALLS 10
|
||||
|
||||
|
@ -34,10 +36,50 @@ int interp_status(int status)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifdef PTRACE_GETREGSET
|
||||
# if defined(__x86_64__) || defined(__i386__)
|
||||
# define ARCH_REGS_STRUCT struct user_regs_struct
|
||||
# elif defined(__aarch64__)
|
||||
# define ARCH_REGS_STRUCT struct user_pt_regs
|
||||
# elif defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__)
|
||||
# define ARCH_REGS_STRUCT struct pt_regs
|
||||
# endif
|
||||
|
||||
int read_ptrace_registers(pid_t pid)
|
||||
{
|
||||
ARCH_REGS_STRUCT regs;
|
||||
struct iovec iov;
|
||||
|
||||
iov.iov_base = ®s;
|
||||
iov.iov_len = sizeof(regs);
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_GETREGS) failed - ");
|
||||
return errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* ! PTRACE_GETREGSET so use PTRACE_GETREGS instead */
|
||||
int read_ptrace_registers(pid_t pid)
|
||||
{
|
||||
struct user regs;
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
if (ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_GETREGS) failed - ");
|
||||
return errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* return 0 on success. Child failure -errorno, parent failure errno */
|
||||
int do_parent(pid_t pid, int trace, int num_syscall)
|
||||
{
|
||||
struct user regs;
|
||||
int status, i;
|
||||
unsigned int rc;
|
||||
|
||||
|
@ -88,11 +130,9 @@ int do_parent(pid_t pid, int trace, int num_syscall)
|
|||
if (!WIFSTOPPED(status))
|
||||
return interp_status(status);
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
if (ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_GETREGS) failed - ");
|
||||
return errno;
|
||||
}
|
||||
rc = read_ptrace_registers(pid);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) {
|
||||
|
|
Loading…
Add table
Reference in a new issue