Home | History | Annotate | Download | only in ptrace
      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