1 /* 2 * check out-of-bound/unaligned addresses given to 3 * - {PEEK,POKE}{DATA,TEXT,USER} 4 * - {GET,SET}{,FG}REGS 5 * - {GET,SET}SIGINFO 6 * 7 * Copyright (c) 2008 Analog Devices Inc. 8 * 9 * Licensed under the GPL-2 or later 10 */ 11 12 #define _GNU_SOURCE 13 14 #include <errno.h> 15 #include <stdbool.h> 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <unistd.h> 19 20 #include <config.h> 21 #include "ptrace.h" 22 23 #include "test.h" 24 #include "spawn_ptrace_child.h" 25 #include "config.h" 26 27 /* this should be sizeof(struct user), but that info is only found 28 * in the kernel asm/user.h which is not exported to userspace. 29 */ 30 #if defined(__i386__) 31 #define SIZEOF_USER 284 32 #elif defined(__x86_64__) 33 #define SIZEOF_USER 928 34 #else 35 #define SIZEOF_USER 0x1000 /* just pick a big number */ 36 #endif 37 38 char *TCID = "ptrace06"; 39 40 struct test_case_t { 41 enum __ptrace_request request; 42 long addr; 43 long data; 44 } test_cases[] = { 45 { 46 PTRACE_PEEKDATA,.addr = 0}, { 47 PTRACE_PEEKDATA,.addr = 1}, { 48 PTRACE_PEEKDATA,.addr = 2}, { 49 PTRACE_PEEKDATA,.addr = 3}, { 50 PTRACE_PEEKDATA,.addr = -1}, { 51 PTRACE_PEEKDATA,.addr = -2}, { 52 PTRACE_PEEKDATA,.addr = -3}, { 53 PTRACE_PEEKDATA,.addr = -4}, { 54 PTRACE_PEEKTEXT,.addr = 0}, { 55 PTRACE_PEEKTEXT,.addr = 1}, { 56 PTRACE_PEEKTEXT,.addr = 2}, { 57 PTRACE_PEEKTEXT,.addr = 3}, { 58 PTRACE_PEEKTEXT,.addr = -1}, { 59 PTRACE_PEEKTEXT,.addr = -2}, { 60 PTRACE_PEEKTEXT,.addr = -3}, { 61 PTRACE_PEEKTEXT,.addr = -4}, { 62 PTRACE_PEEKUSER,.addr = SIZEOF_USER + 1}, { 63 PTRACE_PEEKUSER,.addr = SIZEOF_USER + 2}, { 64 PTRACE_PEEKUSER,.addr = SIZEOF_USER + 3}, { 65 PTRACE_PEEKUSER,.addr = SIZEOF_USER + 4}, { 66 PTRACE_PEEKUSER,.addr = -1}, { 67 PTRACE_PEEKUSER,.addr = -2}, { 68 PTRACE_PEEKUSER,.addr = -3}, { 69 PTRACE_PEEKUSER,.addr = -4}, { 70 PTRACE_POKEDATA,.addr = 0}, { 71 PTRACE_POKEDATA,.addr = 1}, { 72 PTRACE_POKEDATA,.addr = 2}, { 73 PTRACE_POKEDATA,.addr = 3}, { 74 PTRACE_POKEDATA,.addr = -1}, { 75 PTRACE_POKEDATA,.addr = -2}, { 76 PTRACE_POKEDATA,.addr = -3}, { 77 PTRACE_POKEDATA,.addr = -4}, { 78 PTRACE_POKETEXT,.addr = 0}, { 79 PTRACE_POKETEXT,.addr = 1}, { 80 PTRACE_POKETEXT,.addr = 2}, { 81 PTRACE_POKETEXT,.addr = 3}, { 82 PTRACE_POKETEXT,.addr = -1}, { 83 PTRACE_POKETEXT,.addr = -2}, { 84 PTRACE_POKETEXT,.addr = -3}, { 85 PTRACE_POKETEXT,.addr = -4}, { 86 PTRACE_POKEUSER,.addr = SIZEOF_USER + 1}, { 87 PTRACE_POKEUSER,.addr = SIZEOF_USER + 2}, { 88 PTRACE_POKEUSER,.addr = SIZEOF_USER + 3}, { 89 PTRACE_POKEUSER,.addr = SIZEOF_USER + 4}, { 90 PTRACE_POKEUSER,.addr = -1}, { 91 PTRACE_POKEUSER,.addr = -2}, { 92 PTRACE_POKEUSER,.addr = -3}, { 93 PTRACE_POKEUSER,.addr = -4}, 94 #ifdef PTRACE_GETREGS 95 { 96 PTRACE_GETREGS,.data = 0}, { 97 PTRACE_GETREGS,.data = 1}, { 98 PTRACE_GETREGS,.data = 2}, { 99 PTRACE_GETREGS,.data = 3}, { 100 PTRACE_GETREGS,.data = -1}, { 101 PTRACE_GETREGS,.data = -2}, { 102 PTRACE_GETREGS,.data = -3}, { 103 PTRACE_GETREGS,.data = -4}, 104 #endif 105 #ifdef PTRACE_GETFGREGS 106 { 107 PTRACE_GETFGREGS,.data = 0}, { 108 PTRACE_GETFGREGS,.data = 1}, { 109 PTRACE_GETFGREGS,.data = 2}, { 110 PTRACE_GETFGREGS,.data = 3}, { 111 PTRACE_GETFGREGS,.data = -1}, { 112 PTRACE_GETFGREGS,.data = -2}, { 113 PTRACE_GETFGREGS,.data = -3}, { 114 PTRACE_GETFGREGS,.data = -4}, 115 #endif 116 #ifdef PTRACE_SETREGS 117 { 118 PTRACE_SETREGS,.data = 0}, { 119 PTRACE_SETREGS,.data = 1}, { 120 PTRACE_SETREGS,.data = 2}, { 121 PTRACE_SETREGS,.data = 3}, { 122 PTRACE_SETREGS,.data = -1}, { 123 PTRACE_SETREGS,.data = -2}, { 124 PTRACE_SETREGS,.data = -3}, { 125 PTRACE_SETREGS,.data = -4}, 126 #endif 127 #ifdef PTRACE_SETFGREGS 128 { 129 PTRACE_SETFGREGS,.data = 0}, { 130 PTRACE_SETFGREGS,.data = 1}, { 131 PTRACE_SETFGREGS,.data = 2}, { 132 PTRACE_SETFGREGS,.data = 3}, { 133 PTRACE_SETFGREGS,.data = -1}, { 134 PTRACE_SETFGREGS,.data = -2}, { 135 PTRACE_SETFGREGS,.data = -3}, { 136 PTRACE_SETFGREGS,.data = -4}, 137 #endif 138 #if HAVE_DECL_PTRACE_GETSIGINFO 139 { 140 PTRACE_GETSIGINFO,.data = 0}, { 141 PTRACE_GETSIGINFO,.data = 1}, { 142 PTRACE_GETSIGINFO,.data = 2}, { 143 PTRACE_GETSIGINFO,.data = 3}, { 144 PTRACE_GETSIGINFO,.data = -1}, { 145 PTRACE_GETSIGINFO,.data = -2}, { 146 PTRACE_GETSIGINFO,.data = -3}, { 147 PTRACE_GETSIGINFO,.data = -4}, 148 #endif 149 #if HAVE_DECL_PTRACE_SETSIGINFO 150 { 151 PTRACE_SETSIGINFO,.data = 0}, { 152 PTRACE_SETSIGINFO,.data = 1}, { 153 PTRACE_SETSIGINFO,.data = 2}, { 154 PTRACE_SETSIGINFO,.data = 3}, { 155 PTRACE_SETSIGINFO,.data = -1}, { 156 PTRACE_SETSIGINFO,.data = -2}, { 157 PTRACE_SETSIGINFO,.data = -3}, { 158 PTRACE_SETSIGINFO,.data = -4}, 159 #endif 160 }; 161 162 int TST_TOTAL = ARRAY_SIZE(test_cases); 163 164 int main(int argc, char *argv[]) 165 { 166 size_t i; 167 long ret; 168 int saved_errno; 169 170 tst_parse_opts(argc, argv, NULL, NULL); 171 172 make_a_baby(argc, argv); 173 174 for (i = 0; i < ARRAY_SIZE(test_cases); ++i) { 175 struct test_case_t *tc = &test_cases[i]; 176 177 errno = 0; 178 ret = 179 ptrace(tc->request, pid, (void *)tc->addr, 180 (void *)tc->data); 181 saved_errno = errno; 182 if (ret != -1) 183 tst_resm(TFAIL, 184 "ptrace(%s, ..., %li, %li) returned %li instead of -1", 185 strptrace(tc->request), tc->addr, tc->data, 186 ret); 187 else if (saved_errno != EIO && saved_errno != EFAULT) 188 tst_resm(TFAIL, 189 "ptrace(%s, ..., %li, %li) expected errno EIO or EFAULT; actual: %i (%s)", 190 strptrace(tc->request), tc->addr, tc->data, 191 saved_errno, strerror(saved_errno)); 192 else 193 tst_resm(TPASS, 194 "ptrace(%s, ..., %li, %li) failed as expected", 195 strptrace(tc->request), tc->addr, tc->data); 196 } 197 198 /* hopefully this worked */ 199 ptrace(PTRACE_KILL, pid, NULL, NULL); 200 201 tst_exit(); 202 } 203