lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sun, 17 Jul 2016 09:59:52 +0800 From: wei.guo.simon@...il.com To: Michael Ellerman <mpe@...erman.id.au> Cc: Anshuman Khandual <khandual@...ux.vnet.ibm.com>, Benjamin Herrenschmidt <benh@...nel.crashing.org>, Paul Mackerras <paulus@...ba.org>, Shuah Khan <shuahkh@....samsung.com>, Anton Blanchard <anton@...ba.org>, Cyril Bur <cyrilbur@...il.com>, Simon Guo <wei.guo.simon@...il.com>, Ulrich Weigand <ulrich.weigand@...ibm.com>, Michael Neuling <mikey@...ling.org>, Andrew Morton <akpm@...ux-foundation.org>, Kees Cook <keescook@...omium.org>, Rashmica Gupta <rashmicy@...il.com>, Khem Raj <raj.khem@...il.com>, Jessica Yu <jeyu@...hat.com>, Jiri Kosina <jkosina@...e.cz>, Miroslav Benes <mbenes@...e.cz>, Suraj Jitindar Singh <sjitindarsingh@...il.com>, Chris Smart <chris@...troguy.com>, linuxppc-dev@...ts.ozlabs.org, linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org Subject: [PATCH v11 19/27] selftests/powerpc: Add ptrace tests for TAR, PPR, DSCR registers From: Anshuman Khandual <khandual@...ux.vnet.ibm.com> This patch adds ptrace interface test for TAR, PPR, DSCR registers. This also adds ptrace interface based helper functions related to TAR, PPR, DSCR register access. Cc: Benjamin Herrenschmidt <benh@...nel.crashing.org> Cc: Paul Mackerras <paulus@...ba.org> Cc: Michael Ellerman <mpe@...erman.id.au> Cc: Shuah Khan <shuahkh@....samsung.com> Cc: Anton Blanchard <anton@...ba.org> Cc: Cyril Bur <cyrilbur@...il.com> Cc: Anshuman Khandual <khandual@...ux.vnet.ibm.com> Cc: Simon Guo <wei.guo.simon@...il.com> Cc: Ulrich Weigand <ulrich.weigand@...ibm.com> Cc: Michael Neuling <mikey@...ling.org> Cc: Andrew Morton <akpm@...ux-foundation.org> Cc: Kees Cook <keescook@...omium.org> Cc: Rashmica Gupta <rashmicy@...il.com> Cc: Khem Raj <raj.khem@...il.com> Cc: Jessica Yu <jeyu@...hat.com> Cc: Jiri Kosina <jkosina@...e.cz> Cc: Miroslav Benes <mbenes@...e.cz> Cc: Suraj Jitindar Singh <sjitindarsingh@...il.com> Cc: Chris Smart <chris@...troguy.com> Cc: linuxppc-dev@...ts.ozlabs.org Cc: linux-kernel@...r.kernel.org Cc: linux-kselftest@...r.kernel.org Signed-off-by: Anshuman Khandual <khandual@...ux.vnet.ibm.com> Signed-off-by: Simon Guo <wei.guo.simon@...il.com> --- tools/testing/selftests/powerpc/ptrace/Makefile | 3 +- .../testing/selftests/powerpc/ptrace/ptrace-tar.c | 158 ++++++++++++++++++ .../testing/selftests/powerpc/ptrace/ptrace-tar.h | 50 ++++++ tools/testing/selftests/powerpc/ptrace/ptrace.h | 181 +++++++++++++++++++++ 4 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tar.c create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tar.h diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile b/tools/testing/selftests/powerpc/ptrace/Makefile index d0f000c..c794057 100644 --- a/tools/testing/selftests/powerpc/ptrace/Makefile +++ b/tools/testing/selftests/powerpc/ptrace/Makefile @@ -1,4 +1,5 @@ -TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr +TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \ +ptrace-tar all: $(TEST_PROGS) CFLAGS += -m64 diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tar.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tar.c new file mode 100644 index 0000000..9af3fd7 --- /dev/null +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tar.c @@ -0,0 +1,158 @@ +/* + * Ptrace test for TAR, PPR, DSCR registers + * + * Copyright (C) 2015 Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include "ptrace.h" +#include "ptrace-tar.h" + +/* Tracer and Tracee Shared Data */ +int shm_id; +volatile int *cptr; +volatile int *pptr; + +void tar(void) +{ + unsigned long reg[3]; + int ret; + + cptr = (int *)shmat(shm_id, NULL, 0); + printf("%-30s TAR: %u PPR: %lx DSCR: %u\n", + user_write, TAR_1, PPR_1, DSCR_1); + + mtspr(SPRN_TAR, TAR_1); + mtspr(SPRN_PPR, PPR_1); + mtspr(SPRN_DSCR, DSCR_1); + + cptr[2] = 1; + + /* Wait on parent */ + while (!cptr[0]); + + reg[0] = mfspr(SPRN_TAR); + reg[1] = mfspr(SPRN_PPR); + reg[2] = mfspr(SPRN_DSCR); + + printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", + user_read, reg[0], reg[1], reg[2]); + + /* Unblock the parent now */ + cptr[1] = 1; + shmdt((int *)cptr); + + ret = validate_tar_registers(reg, TAR_2, PPR_2, DSCR_2); + if (ret) + exit(1); + exit(0); +} + +int trace_tar(pid_t child) +{ + unsigned long reg[3]; + int ret; + + ret = start_trace(child); + if (ret) + return TEST_FAIL; + + ret = show_tar_registers(child, reg); + if (ret) + return TEST_FAIL; + + printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", + ptrace_read_running, reg[0], reg[1], reg[2]); + + ret = validate_tar_registers(reg, TAR_1, PPR_1, DSCR_1); + if (ret) + return TEST_FAIL; + + ret = stop_trace(child); + if (ret) + return TEST_FAIL; + + return TEST_PASS; +} + +int trace_tar_write(pid_t child) +{ + int ret; + + ret = start_trace(child); + if (ret) + return TEST_FAIL; + + ret = write_tar_registers(child, TAR_2, PPR_2, DSCR_2); + if (ret) + return TEST_FAIL; + + printf("%-30s TAR: %u PPR: %lx DSCR: %u\n", + ptrace_write_running, TAR_2, PPR_2, DSCR_2); + + ret = stop_trace(child); + if (ret) + return TEST_FAIL; + + return TEST_PASS; +} + +int ptrace_tar(void) +{ + pid_t pid; + int ret, status; + + shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT); + pid = fork(); + if (pid < 0) { + perror("fork() failed"); + return TEST_FAIL; + } + + if (pid == 0) + tar(); + + if (pid) { + pptr = (int *)shmat(shm_id, NULL, 0); + pptr[0] = 0; + pptr[1] = 0; + + while (!pptr[2]); + ret = trace_tar(pid); + if (ret) + return ret; + + ret = trace_tar_write(pid); + if (ret) + return ret; + + /* Unblock the child now */ + pptr[0] = 1; + + /* Wait on child */ + while (!pptr[1]); + + shmdt((int *)pptr); + + ret = wait(&status); + if (ret != pid) { + printf("Child's exit status not captured\n"); + return TEST_PASS; + } + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status)) + return TEST_FAIL; + } + return TEST_PASS; + } + return TEST_PASS; +} + +int main(int argc, char *argv[]) +{ + return test_harness(ptrace_tar, "ptrace_tar"); +} diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tar.h b/tools/testing/selftests/powerpc/ptrace/ptrace-tar.h new file mode 100644 index 0000000..aed0aac --- /dev/null +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tar.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#define TAR_1 10 +#define TAR_2 20 +#define TAR_3 30 +#define TAR_4 40 +#define TAR_5 50 + +#define DSCR_1 100 +#define DSCR_2 200 +#define DSCR_3 300 +#define DSCR_4 400 +#define DSCR_5 500 + +#define PPR_1 0x4000000000000 /* or 31,31,31*/ +#define PPR_2 0x8000000000000 /* or 1,1,1 */ +#define PPR_3 0xc000000000000 /* or 6,6,6 */ +#define PPR_4 0x10000000000000 /* or 2,2,2 */ + +char *user_read = "[User Read (Running)]"; +char *user_write = "[User Write (Running)]"; +char *ptrace_read_running = "[Ptrace Read (Running)]"; +char *ptrace_write_running = "[Ptrace Write (Running)]"; +char *ptrace_read_ckpt = "[Ptrace Read (Checkpointed)]"; +char *ptrace_write_ckpt = "[Ptrace Write (Checkpointed)]"; + +int validate_tar_registers(unsigned long *reg, unsigned long tar, + unsigned long ppr, unsigned long dscr) +{ + int match = 1; + + if (reg[0] != tar) + match = 0; + + if (reg[1] != ppr) + match = 0; + + if (reg[2] != dscr) + match = 0; + + if (!match) + return TEST_FAIL; + return TEST_PASS; +} diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace.h b/tools/testing/selftests/powerpc/ptrace/ptrace.h index b6df47f..b9ab0b1 100644 --- a/tools/testing/selftests/powerpc/ptrace/ptrace.h +++ b/tools/testing/selftests/powerpc/ptrace/ptrace.h @@ -172,6 +172,187 @@ fail: return TEST_FAIL; } +/* TAR, PPR, DSCR */ +int show_tar_registers(pid_t child, unsigned long *out) +{ + struct iovec iov; + unsigned long *reg; + int ret; + + reg = malloc(sizeof(unsigned long)); + if (!reg) { + perror("malloc() failed"); + return TEST_FAIL; + } + iov.iov_base = (u64 *) reg; + iov.iov_len = sizeof(unsigned long); + + ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov); + if (ret) { + perror("ptrace(PTRACE_GETREGSET) failed"); + goto fail; + } + if (out) + out[0] = *reg; + + ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov); + if (ret) { + perror("ptrace(PTRACE_GETREGSET) failed"); + goto fail; + } + if (out) + out[1] = *reg; + + ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov); + if (ret) { + perror("ptrace(PTRACE_GETREGSET) failed"); + goto fail; + } + if (out) + out[2] = *reg; + + free(reg); + return TEST_PASS; +fail: + free(reg); + return TEST_FAIL; +} + +int write_tar_registers(pid_t child, unsigned long tar, + unsigned long ppr, unsigned long dscr) +{ + struct iovec iov; + unsigned long *reg; + int ret; + + reg = malloc(sizeof(unsigned long)); + if (!reg) { + perror("malloc() failed"); + return TEST_FAIL; + } + + iov.iov_base = (u64 *) reg; + iov.iov_len = sizeof(unsigned long); + + *reg = tar; + ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov); + if (ret) { + perror("ptrace(PTRACE_SETREGSET) failed"); + goto fail; + } + + *reg = ppr; + ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov); + if (ret) { + perror("ptrace(PTRACE_SETREGSET) failed"); + goto fail; + } + + *reg = dscr; + ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov); + if (ret) { + perror("ptrace(PTRACE_SETREGSET) failed"); + goto fail; + } + + free(reg); + return TEST_PASS; +fail: + free(reg); + return TEST_FAIL; +} + +int show_tm_checkpointed_state(pid_t child, unsigned long *out) +{ + struct iovec iov; + unsigned long *reg; + int ret; + + reg = malloc(sizeof(unsigned long)); + if (!reg) { + perror("malloc() failed"); + return TEST_FAIL; + } + + iov.iov_base = (u64 *) reg; + iov.iov_len = sizeof(unsigned long); + + ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov); + if (ret) { + perror("ptrace(PTRACE_GETREGSET) failed"); + goto fail; + } + if (out) + out[0] = *reg; + + ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov); + if (ret) { + perror("ptrace(PTRACE_GETREGSET) failed"); + goto fail; + } + if (out) + out[1] = *reg; + + ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov); + if (ret) { + perror("ptrace(PTRACE_GETREGSET) failed"); + goto fail; + } + if (out) + out[2] = *reg; + + free(reg); + return TEST_PASS; + +fail: + free(reg); + return TEST_FAIL; +} + +int write_ckpt_tar_registers(pid_t child, unsigned long tar, + unsigned long ppr, unsigned long dscr) +{ + struct iovec iov; + unsigned long *reg; + int ret; + + reg = malloc(sizeof(unsigned long)); + if (!reg) { + perror("malloc() failed"); + return TEST_FAIL; + } + + iov.iov_base = (u64 *) reg; + iov.iov_len = sizeof(unsigned long); + + *reg = tar; + ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov); + if (ret) { + perror("ptrace(PTRACE_GETREGSET) failed"); + goto fail; + } + + *reg = ppr; + ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov); + if (ret) { + perror("ptrace(PTRACE_GETREGSET) failed"); + goto fail; + } + + *reg = dscr; + ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov); + if (ret) { + perror("ptrace(PTRACE_GETREGSET) failed"); + goto fail; + } + + free(reg); + return TEST_PASS; +fail: + free(reg); + return TEST_FAIL; +} + /* FPR */ int show_fpr(pid_t child, unsigned long *fpr) { -- 1.8.3.1
Powered by blists - more mailing lists