Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

printsiginfo: decode si_pkey field #210

Merged
merged 3 commits into from Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS
Expand Up @@ -10,6 +10,7 @@ Noteworthy changes in release ?.?? (????-??-??)
* Implemented decoding of IFLA_GRO_MAX_SIZE and TCA_ACT_IN_HW_COUNT netlink
attributes.
* Implemented decoding of PR_SET_VMA operation of prctl syscall.
* Implemented decoding of siginfo_t.si_pkey field.
* Updated lists of FAN_*, IORING_*, IOSQE_*, KVM_*, MODULE_INIT_*, TCA_ACT_*,
and *_MAGIC constants.

Expand Down
3 changes: 2 additions & 1 deletion configure.ac
Expand Up @@ -423,7 +423,8 @@ AC_CHECK_MEMBERS([struct utsname.domainname],,, [#include <sys/utsname.h>])
AC_CHECK_MEMBERS(m4_normalize([
siginfo_t.si_syscall,
siginfo_t.si_timerid,
siginfo_t.si_overrun
siginfo_t.si_overrun,
siginfo_t.si_pkey
]),,, [#include <signal.h>])

AC_CHECK_HEADERS(m4_normalize([
Expand Down
17 changes: 15 additions & 2 deletions src/printsiginfo.c
Expand Up @@ -161,10 +161,23 @@ print_si_info(struct tcb *tcp, const siginfo_t *sip)
tprint_struct_next();
PRINT_FIELD_U(*sip, si_stime);
break;
case SIGILL: case SIGFPE:
case SIGSEGV: case SIGBUS:
case SIGILL:
case SIGFPE:
case SIGBUS:
tprint_struct_next();
PRINT_FIELD_PTR(*sip, si_addr);
break;
case SIGSEGV:
tprint_struct_next();
PRINT_FIELD_PTR(*sip, si_addr);
#ifdef HAVE_SIGINFO_T_SI_PKEY
switch (sip->si_code) {
case SEGV_PKUERR:
tprint_struct_next();
PRINT_FIELD_U(*sip, si_pkey);
break;
}
#endif
break;
case SIGPOLL:
switch (sip->si_code) {
Expand Down
2 changes: 2 additions & 0 deletions tests/.gitignore
Expand Up @@ -860,6 +860,8 @@ seccomp_get_action_avail
seccomp_get_notif_sizes
seccomp_get_notif_sizes-success
secontext.am
segv_accerr
segv_pkuerr
select
select-P
semop
Expand Down
2 changes: 2 additions & 0 deletions tests/Makefile.am
Expand Up @@ -335,6 +335,8 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
seccomp-filter-v \
seccomp-strict \
seccomp_get_notif_sizes-success \
segv_accerr \
segv_pkuerr \
select-P \
set_ptracer_any \
set_sigblock \
Expand Down
2 changes: 2 additions & 0 deletions tests/gen_tests.in
Expand Up @@ -840,6 +840,8 @@ seccomp-filter-v -v -e trace=seccomp
seccomp_get_action_avail -e trace=seccomp
seccomp_get_notif_sizes -etrace=seccomp -a42
seccomp_get_notif_sizes-success -einject=seccomp:retval=42 -etrace=seccomp -a42
segv_accerr -qq --trace=none
segv_pkuerr -qq --trace=none
select -a36
select-P -a36 -e trace=select -P /dev/full 9>>/dev/full
semop -a32
Expand Down
16 changes: 16 additions & 0 deletions tests/ptrace.c
Expand Up @@ -1854,6 +1854,22 @@ main(void)
XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
XLAT_ARGS(SIGPROF), sip->si_code, sip->si_errno, errstr);

#ifdef HAVE_SIGINFO_T_SI_PKEY
memset(sip, -1, sizeof(*sip));
sip->si_signo = SIGSEGV;
sip->si_code = SEGV_PKUERR;
sip->si_errno = 0;
sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
sip->si_pkey = 0xbadc0ded;

do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
", si_code=" XLAT_FMT ", si_addr=%p, si_pkey=%u}) = %s\n",
XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
XLAT_ARGS(SIGSEGV), XLAT_ARGS(SEGV_PKUERR),
sip->si_addr, sip->si_pkey, errstr);
#endif

#ifdef HAVE_SIGINFO_T_SI_SYSCALL
memset(sip, -1, sizeof(*sip));
sip->si_signo = SIGSYS;
Expand Down
53 changes: 53 additions & 0 deletions tests/segv_accerr.c
@@ -0,0 +1,53 @@
/*
* Check decoding of SEGV_ACCERR.
*
* Copyright (c) 2022 Dmitry V. Levin <ldv@strace.io>
* All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "tests.h"
#include <signal.h>

#ifdef SEGV_ACCERR

# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/mman.h>

static void
handler(int sig)
{
_exit(0);
}

int
main(void) {
int *p = mmap(NULL, get_page_size(), PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED)
perror_msg_and_fail("mmap");

const struct sigaction act = {
.sa_handler = handler,
.sa_flags = SA_RESETHAND
};
if (sigaction(SIGSEGV, &act, NULL))
perror_msg_and_fail("sigaction");

printf("--- SIGSEGV {si_signo=SIGSEGV"
", si_code=SEGV_ACCERR, si_addr=%p} ---\n", p);
fflush(stdout);

__asm__ volatile("":: "r" (*p));

error_msg_and_skip("PROT_NONE page is readable");
}

#else

SKIP_MAIN_UNDEFINED("SEGV_ACCERR")

#endif
55 changes: 55 additions & 0 deletions tests/segv_pkuerr.c
@@ -0,0 +1,55 @@
/*
* Check decoding of SEGV_PKUERR.
*
* Copyright (c) 2022 Dmitry V. Levin <ldv@strace.io>
* All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "tests.h"
#include <signal.h>

#if defined HAVE_SIGINFO_T_SI_PKEY && defined SEGV_PKUERR

# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/mman.h>

static void
handler(int sig, siginfo_t *info, void *ucontext)
{
if (info->si_code != SEGV_PKUERR)
error_msg_and_skip("SIGSEGV: si_code = %d", info->si_code);

printf("--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_PKUERR"
", si_addr=%p, si_pkey=%u} ---\n",
info->si_addr, info->si_pkey);
exit(0);
}

int
main(void) {
int *p = mmap(NULL, get_page_size(), PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED)
perror_msg_and_fail("mmap");

const struct sigaction act = {
.sa_sigaction = handler,
.sa_flags = SA_SIGINFO | SA_RESETHAND
};
if (sigaction(SIGSEGV, &act, NULL))
perror_msg_and_fail("sigaction");

__asm__ volatile("":: "r" (*p));

error_msg_and_skip("PROT_EXEC page is readable");
}

#else

SKIP_MAIN_UNDEFINED("HAVE_SIGINFO_T_SI_PKEY && SEGV_PKUERR")

#endif