Skip to content

Commit

Permalink
ptrace06: Refactor the test using new LTP API
Browse files Browse the repository at this point in the history
Link: https://lore.kernel.org/ltp/[email protected]/
Reviewed-by: Cyril Hrubis <[email protected]>
Reviewed-by: Petr Vorel <[email protected]>
Signed-off-by: Wei Gao <[email protected]>
[ pvorel: remove unused ptrace06_child.c ]
Signed-off-by: Petr Vorel <[email protected]>
  • Loading branch information
coolgw authored and pevik committed Jan 20, 2025
1 parent c9a1511 commit 55319ad
Showing 1 changed file with 172 additions and 151 deletions.
323 changes: 172 additions & 151 deletions testcases/kernel/syscalls/ptrace/ptrace06.c
Original file line number Diff line number Diff line change
@@ -1,199 +1,220 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* check out-of-bound/unaligned addresses given to
* Copyright (c) 2008 Analog Devices Inc.
* Copyright (c) Linux Test Project, 2008-2023
* Copyright (c) 2025 Wei Gao <[email protected]>
*/

/*\
* [Description]
*
* Check out-of-bound/unaligned addresses given to
*
* - {PEEK,POKE}{DATA,TEXT,USER}
* - {GET,SET}{,FG}REGS
* - {GET,SET}SIGINFO
*
* Copyright (c) 2008 Analog Devices Inc.
*
* Licensed under the GPL-2 or later
*/

#define _GNU_SOURCE

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ptrace.h>

#include "test.h"
#include "spawn_ptrace_child.h"
#include "tst_test.h"

/* this should be sizeof(struct user), but that info is only found
* in the kernel asm/user.h which is not exported to userspace.
*/

#if defined(__i386__)
#define SIZEOF_USER 284
# define SIZEOF_USER 284
#elif defined(__x86_64__)
#define SIZEOF_USER 928
# define SIZEOF_USER 928
#else
#define SIZEOF_USER 0x1000 /* just pick a big number */
# define SIZEOF_USER 0x1000 /* just pick a big number */
#endif

char *TCID = "ptrace06";

struct test_case_t {
static struct test_case_t {
int request;
long addr;
long data;
} test_cases[] = {
{
PTRACE_PEEKDATA,.addr = 0}, {
PTRACE_PEEKDATA,.addr = 1}, {
PTRACE_PEEKDATA,.addr = 2}, {
PTRACE_PEEKDATA,.addr = 3}, {
PTRACE_PEEKDATA,.addr = -1}, {
PTRACE_PEEKDATA,.addr = -2}, {
PTRACE_PEEKDATA,.addr = -3}, {
PTRACE_PEEKDATA,.addr = -4}, {
PTRACE_PEEKTEXT,.addr = 0}, {
PTRACE_PEEKTEXT,.addr = 1}, {
PTRACE_PEEKTEXT,.addr = 2}, {
PTRACE_PEEKTEXT,.addr = 3}, {
PTRACE_PEEKTEXT,.addr = -1}, {
PTRACE_PEEKTEXT,.addr = -2}, {
PTRACE_PEEKTEXT,.addr = -3}, {
PTRACE_PEEKTEXT,.addr = -4}, {
PTRACE_PEEKUSER,.addr = SIZEOF_USER + 1}, {
PTRACE_PEEKUSER,.addr = SIZEOF_USER + 2}, {
PTRACE_PEEKUSER,.addr = SIZEOF_USER + 3}, {
PTRACE_PEEKUSER,.addr = SIZEOF_USER + 4}, {
PTRACE_PEEKUSER,.addr = -1}, {
PTRACE_PEEKUSER,.addr = -2}, {
PTRACE_PEEKUSER,.addr = -3}, {
PTRACE_PEEKUSER,.addr = -4}, {
PTRACE_POKEDATA,.addr = 0}, {
PTRACE_POKEDATA,.addr = 1}, {
PTRACE_POKEDATA,.addr = 2}, {
PTRACE_POKEDATA,.addr = 3}, {
PTRACE_POKEDATA,.addr = -1}, {
PTRACE_POKEDATA,.addr = -2}, {
PTRACE_POKEDATA,.addr = -3}, {
PTRACE_POKEDATA,.addr = -4}, {
PTRACE_POKETEXT,.addr = 0}, {
PTRACE_POKETEXT,.addr = 1}, {
PTRACE_POKETEXT,.addr = 2}, {
PTRACE_POKETEXT,.addr = 3}, {
PTRACE_POKETEXT,.addr = -1}, {
PTRACE_POKETEXT,.addr = -2}, {
PTRACE_POKETEXT,.addr = -3}, {
PTRACE_POKETEXT,.addr = -4}, {
PTRACE_POKEUSER,.addr = SIZEOF_USER + 1}, {
PTRACE_POKEUSER,.addr = SIZEOF_USER + 2}, {
PTRACE_POKEUSER,.addr = SIZEOF_USER + 3}, {
PTRACE_POKEUSER,.addr = SIZEOF_USER + 4}, {
PTRACE_POKEUSER,.addr = -1}, {
PTRACE_POKEUSER,.addr = -2}, {
PTRACE_POKEUSER,.addr = -3}, {
PTRACE_POKEUSER,.addr = -4},
{PTRACE_PEEKDATA, .addr = 0},
{PTRACE_PEEKDATA, .addr = 1},
{PTRACE_PEEKDATA, .addr = 2},
{PTRACE_PEEKDATA, .addr = 3},
{PTRACE_PEEKDATA, .addr = -1},
{PTRACE_PEEKDATA, .addr = -2},
{PTRACE_PEEKDATA, .addr = -3},
{PTRACE_PEEKDATA, .addr = -4},
{PTRACE_PEEKTEXT, .addr = 0},
{PTRACE_PEEKTEXT, .addr = 1},
{PTRACE_PEEKTEXT, .addr = 2},
{PTRACE_PEEKTEXT, .addr = 3},
{PTRACE_PEEKTEXT, .addr = -1},
{PTRACE_PEEKTEXT, .addr = -2},
{PTRACE_PEEKTEXT, .addr = -3},
{PTRACE_PEEKTEXT, .addr = -4},
{PTRACE_PEEKUSER, .addr = SIZEOF_USER + 1},
{PTRACE_PEEKUSER, .addr = SIZEOF_USER + 2},
{PTRACE_PEEKUSER, .addr = SIZEOF_USER + 3},
{PTRACE_PEEKUSER, .addr = SIZEOF_USER + 4},
{PTRACE_PEEKUSER, .addr = -1},
{PTRACE_PEEKUSER, .addr = -2},
{PTRACE_PEEKUSER, .addr = -3},
{PTRACE_PEEKUSER, .addr = -4},
{PTRACE_POKEDATA, .addr = 0},
{PTRACE_POKEDATA, .addr = 1},
{PTRACE_POKEDATA, .addr = 2},
{PTRACE_POKEDATA, .addr = 3},
{PTRACE_POKEDATA, .addr = -1},
{PTRACE_POKEDATA, .addr = -2},
{PTRACE_POKEDATA, .addr = -3},
{PTRACE_POKEDATA, .addr = -4},
{PTRACE_POKETEXT, .addr = 0},
{PTRACE_POKETEXT, .addr = 1},
{PTRACE_POKETEXT, .addr = 2},
{PTRACE_POKETEXT, .addr = 3},
{PTRACE_POKETEXT, .addr = -1},
{PTRACE_POKETEXT, .addr = -2},
{PTRACE_POKETEXT, .addr = -3},
{PTRACE_POKETEXT, .addr = -4},
{PTRACE_POKEUSER, .addr = SIZEOF_USER + 1},
{PTRACE_POKEUSER, .addr = SIZEOF_USER + 2},
{PTRACE_POKEUSER, .addr = SIZEOF_USER + 3},
{PTRACE_POKEUSER, .addr = SIZEOF_USER + 4},
{PTRACE_POKEUSER, .addr = -1},
{PTRACE_POKEUSER, .addr = -2},
{PTRACE_POKEUSER, .addr = -3},
{PTRACE_POKEUSER, .addr = -4},
#ifdef PTRACE_GETREGS
{
PTRACE_GETREGS,.data = 0}, {
PTRACE_GETREGS,.data = 1}, {
PTRACE_GETREGS,.data = 2}, {
PTRACE_GETREGS,.data = 3}, {
PTRACE_GETREGS,.data = -1}, {
PTRACE_GETREGS,.data = -2}, {
PTRACE_GETREGS,.data = -3}, {
PTRACE_GETREGS,.data = -4},
{PTRACE_GETREGS, .data = 0},
{PTRACE_GETREGS, .data = 1},
{PTRACE_GETREGS, .data = 2},
{PTRACE_GETREGS, .data = 3},
{PTRACE_GETREGS, .data = -1},
{PTRACE_GETREGS, .data = -2},
{PTRACE_GETREGS, .data = -3},
{PTRACE_GETREGS, .data = -4},
#endif
#ifdef PTRACE_GETFGREGS
{
PTRACE_GETFGREGS,.data = 0}, {
PTRACE_GETFGREGS,.data = 1}, {
PTRACE_GETFGREGS,.data = 2}, {
PTRACE_GETFGREGS,.data = 3}, {
PTRACE_GETFGREGS,.data = -1}, {
PTRACE_GETFGREGS,.data = -2}, {
PTRACE_GETFGREGS,.data = -3}, {
PTRACE_GETFGREGS,.data = -4},
{PTRACE_GETFGREGS, .data = 0},
{PTRACE_GETFGREGS, .data = 1},
{PTRACE_GETFGREGS, .data = 2},
{PTRACE_GETFGREGS, .data = 3},
{PTRACE_GETFGREGS, .data = -1},
{PTRACE_GETFGREGS, .data = -2},
{PTRACE_GETFGREGS, .data = -3},
{PTRACE_GETFGREGS, .data = -4},
#endif
#ifdef PTRACE_SETREGS
{
PTRACE_SETREGS,.data = 0}, {
PTRACE_SETREGS,.data = 1}, {
PTRACE_SETREGS,.data = 2}, {
PTRACE_SETREGS,.data = 3}, {
PTRACE_SETREGS,.data = -1}, {
PTRACE_SETREGS,.data = -2}, {
PTRACE_SETREGS,.data = -3}, {
PTRACE_SETREGS,.data = -4},
{PTRACE_SETREGS, .data = 0},
{PTRACE_SETREGS, .data = 1},
{PTRACE_SETREGS, .data = 2},
{PTRACE_SETREGS, .data = 3},
{PTRACE_SETREGS, .data = -1},
{PTRACE_SETREGS, .data = -2},
{PTRACE_SETREGS, .data = -3},
{PTRACE_SETREGS, .data = -4},
#endif
#ifdef PTRACE_SETFGREGS
{
PTRACE_SETFGREGS,.data = 0}, {
PTRACE_SETFGREGS,.data = 1}, {
PTRACE_SETFGREGS,.data = 2}, {
PTRACE_SETFGREGS,.data = 3}, {
PTRACE_SETFGREGS,.data = -1}, {
PTRACE_SETFGREGS,.data = -2}, {
PTRACE_SETFGREGS,.data = -3}, {
PTRACE_SETFGREGS,.data = -4},
{PTRACE_SETFGREGS, .data = 0},
{PTRACE_SETFGREGS, .data = 1},
{PTRACE_SETFGREGS, .data = 2},
{PTRACE_SETFGREGS, .data = 3},
{PTRACE_SETFGREGS, .data = -1},
{PTRACE_SETFGREGS, .data = -2},
{PTRACE_SETFGREGS, .data = -3},
{PTRACE_SETFGREGS, .data = -4},
#endif
#if HAVE_DECL_PTRACE_GETSIGINFO
{
PTRACE_GETSIGINFO,.data = 0}, {
PTRACE_GETSIGINFO,.data = 1}, {
PTRACE_GETSIGINFO,.data = 2}, {
PTRACE_GETSIGINFO,.data = 3}, {
PTRACE_GETSIGINFO,.data = -1}, {
PTRACE_GETSIGINFO,.data = -2}, {
PTRACE_GETSIGINFO,.data = -3}, {
PTRACE_GETSIGINFO,.data = -4},
{PTRACE_GETSIGINFO, .data = 0},
{PTRACE_GETSIGINFO, .data = 1},
{PTRACE_GETSIGINFO, .data = 2},
{PTRACE_GETSIGINFO, .data = 3},
{PTRACE_GETSIGINFO, .data = -1},
{PTRACE_GETSIGINFO, .data = -2},
{PTRACE_GETSIGINFO, .data = -3},
{PTRACE_GETSIGINFO, .data = -4},
#endif
#if HAVE_DECL_PTRACE_SETSIGINFO
{
PTRACE_SETSIGINFO,.data = 0}, {
PTRACE_SETSIGINFO,.data = 1}, {
PTRACE_SETSIGINFO,.data = 2}, {
PTRACE_SETSIGINFO,.data = 3}, {
PTRACE_SETSIGINFO,.data = -1}, {
PTRACE_SETSIGINFO,.data = -2}, {
PTRACE_SETSIGINFO,.data = -3}, {
PTRACE_SETSIGINFO,.data = -4},
{PTRACE_SETSIGINFO, .data = 0},
{PTRACE_SETSIGINFO, .data = 1},
{PTRACE_SETSIGINFO, .data = 2},
{PTRACE_SETSIGINFO, .data = 3},
{PTRACE_SETSIGINFO, .data = -1},
{PTRACE_SETSIGINFO, .data = -2},
{PTRACE_SETSIGINFO, .data = -3},
{PTRACE_SETSIGINFO, .data = -4},
#endif
};

#define SPT(x)[PTRACE_##x] = #x,
static char *strings[] = {
SPT(TRACEME)
SPT(PEEKTEXT)
SPT(PEEKDATA)
SPT(PEEKUSER)
SPT(POKETEXT)
SPT(POKEDATA)
SPT(POKEUSER)
#ifdef PTRACE_GETREGS
SPT(GETREGS)
#endif
#ifdef PTRACE_SETREGS
SPT(SETREGS)
#endif
#ifdef PTRACE_GETSIGINFO
SPT(GETSIGINFO)
#endif
#ifdef PTRACE_SETSIGINFO
SPT(SETSIGINFO)
#endif
#ifdef PTRACE_GETFGREGS
SPT(GETFGREGS)
#endif
#ifdef PTRACE_SETFGREGS
SPT(SETFGREGS)
#endif
SPT(KILL)
SPT(SINGLESTEP)
};

int TST_TOTAL = ARRAY_SIZE(test_cases);
static void child(void)
{
SAFE_PTRACE(PTRACE_TRACEME, 0, NULL, NULL);
raise(SIGSTOP);
exit(0);
}

int main(int argc, char *argv[])
static void run(void)
{
size_t i;
long ret;
int saved_errno;
int pid;
int status;
int exp_errnos[] = {EIO, EFAULT};

pid = SAFE_FORK();

tst_parse_opts(argc, argv, NULL, NULL);
if (!pid)
child();

make_a_baby(argc, argv);
SAFE_WAIT(&status);

if (!WIFSTOPPED(status))
tst_brk(TBROK, "child %d was not stopped", pid);

for (i = 0; i < ARRAY_SIZE(test_cases); ++i) {
struct test_case_t *tc = &test_cases[i];

errno = 0;
ret =
ptrace(tc->request, pid, (void *)tc->addr,
(void *)tc->data);
saved_errno = errno;
if (ret != -1)
tst_resm(TFAIL,
"ptrace(%s, ..., %li, %li) returned %li instead of -1",
strptrace(tc->request), tc->addr, tc->data,
ret);
else if (saved_errno != EIO && saved_errno != EFAULT)
tst_resm(TFAIL,
"ptrace(%s, ..., %li, %li) expected errno EIO or EFAULT; actual: %i (%s)",
strptrace(tc->request), tc->addr, tc->data,
saved_errno, strerror(saved_errno));
else
tst_resm(TPASS,
"ptrace(%s, ..., %li, %li) failed as expected",
strptrace(tc->request), tc->addr, tc->data);
TST_EXP_FAIL_ARR(ptrace(tc->request, pid, (void *)tc->addr,
(void *)tc->data), exp_errnos, ARRAY_SIZE(exp_errnos),
"ptrace(%s, ..., %li, %li) failed as expected",
strings[tc->request], tc->addr, tc->data);
}

/* hopefully this worked */
ptrace(PTRACE_KILL, pid, NULL, NULL);
SAFE_PTRACE(PTRACE_CONT, pid, NULL, NULL);

tst_exit();
}

static struct tst_test test = {
.test_all = run,
.forks_child = 1,
};

0 comments on commit 55319ad

Please sign in to comment.