Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Improve PT_SET_SIGMASK and PT_GET_SIGMASK API in ptrace(2)
details: https://anonhg.NetBSD.org/src/rev/982bf5e99929
branches: trunk
changeset: 351697:982bf5e99929
user: kamil <kamil%NetBSD.org@localhost>
date: Thu Feb 23 00:50:09 2017 +0000
description:
Improve PT_SET_SIGMASK and PT_GET_SIGMASK API in ptrace(2)
Use proper check for LW_SYSTEM, don't depend on PT_GETREGS/PT_SETREGS.
Don't allow to mask SA_CANTMASK signals with PT_SET_SIGMASK (this covers
SIGSTOP and SIGKILL).
Add new ATF tests:
- setsigmask5
Verify that sigmask cannot be set to SIGKILL
- setsigmask6
Verify that sigmask cannot be set to SIGSTOP
Sponsored by <The NetBSD Foundation>
diffstat:
sys/kern/sys_ptrace_common.c | 11 ++-
tests/kernel/t_ptrace_wait.c | 128 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 132 insertions(+), 7 deletions(-)
diffs (190 lines):
diff -r 96d6fc564698 -r 982bf5e99929 sys/kern/sys_ptrace_common.c
--- a/sys/kern/sys_ptrace_common.c Wed Feb 22 23:43:43 2017 +0000
+++ b/sys/kern/sys_ptrace_common.c Thu Feb 23 00:50:09 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_ptrace_common.c,v 1.15 2017/02/22 23:43:43 kamil Exp $ */
+/* $NetBSD: sys_ptrace_common.c,v 1.16 2017/02/23 00:50:09 kamil Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -118,7 +118,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.15 2017/02/22 23:43:43 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.16 2017/02/23 00:50:09 kamil Exp $");
#ifdef _KERNEL_OPT
#include "opt_ptrace.h"
@@ -1098,11 +1098,12 @@
mutex_exit(t->p_lock);
}
- if (!process_validregs(lt))
+ if (lt->l_flag & LW_SYSTEM)
error = EINVAL;
- else if (write == 1)
+ else if (write == 1) {
error = copyin(addr, <->l_sigmask, sizeof(sigset_t));
- else
+ sigminusset(&sigcantmask, <->l_sigmask);
+ } else
error = copyout(<->l_sigmask, addr, sizeof(sigset_t));
break;
diff -r 96d6fc564698 -r 982bf5e99929 tests/kernel/t_ptrace_wait.c
--- a/tests/kernel/t_ptrace_wait.c Wed Feb 22 23:43:43 2017 +0000
+++ b/tests/kernel/t_ptrace_wait.c Thu Feb 23 00:50:09 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_ptrace_wait.c,v 1.71 2017/02/22 23:43:43 kamil Exp $ */
+/* $NetBSD: t_ptrace_wait.c,v 1.72 2017/02/23 00:50:09 kamil Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_ptrace_wait.c,v 1.71 2017/02/22 23:43:43 kamil Exp $");
+__RCSID("$NetBSD: t_ptrace_wait.c,v 1.72 2017/02/23 00:50:09 kamil Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -6947,6 +6947,128 @@
TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
}
+ATF_TC(setsigmask5);
+ATF_TC_HEAD(setsigmask5, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify that sigmask cannot be set to SIGKILL");
+}
+
+ATF_TC_BODY(setsigmask5, tc)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ sigset_t new_mask;
+ sigset_t mask;
+ ATF_REQUIRE(sigemptyset(&new_mask) == 0);
+ ATF_REQUIRE(sigemptyset(&mask) == 0);
+ ATF_REQUIRE(sigaddset(&mask, SIGKILL) == 0);
+
+ printf("Before forking process PID=%d\n", getpid());
+ ATF_REQUIRE((child = fork()) != -1);
+ if (child == 0) {
+ printf("Before calling PT_TRACE_ME from child %d\n", getpid());
+ FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
+
+ printf("Before raising %s from child\n", strsignal(sigval));
+ FORKEE_ASSERT(raise(sigval) == 0);
+
+ printf("Before exiting of the child process\n");
+ _exit(exitval);
+ }
+ printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
+
+ printf("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_stopped(status, sigval);
+
+ printf("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
+ ATF_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
+
+ printf("Before calling PT_GET_SIGMASK to store it in new_mask\n");
+ ATF_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
+
+ ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) != 0);
+
+ printf("Before resuming the child process where it left off and "
+ "without signal to be sent\n");
+ ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
+
+ printf("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_exited(status, exitval);
+
+ printf("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+
+ATF_TC(setsigmask6);
+ATF_TC_HEAD(setsigmask6, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify that sigmask cannot be set to SIGSTOP");
+}
+
+ATF_TC_BODY(setsigmask6, tc)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ sigset_t new_mask;
+ sigset_t mask;
+ ATF_REQUIRE(sigemptyset(&new_mask) == 0);
+ ATF_REQUIRE(sigemptyset(&mask) == 0);
+ ATF_REQUIRE(sigaddset(&mask, SIGSTOP) == 0);
+
+ printf("Before forking process PID=%d\n", getpid());
+ ATF_REQUIRE((child = fork()) != -1);
+ if (child == 0) {
+ printf("Before calling PT_TRACE_ME from child %d\n", getpid());
+ FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
+
+ printf("Before raising %s from child\n", strsignal(sigval));
+ FORKEE_ASSERT(raise(sigval) == 0);
+
+ printf("Before exiting of the child process\n");
+ _exit(exitval);
+ }
+ printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
+
+ printf("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_stopped(status, sigval);
+
+ printf("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
+ ATF_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
+
+ printf("Before calling PT_GET_SIGMASK to store it in new_mask\n");
+ ATF_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
+
+ ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) != 0);
+
+ printf("Before resuming the child process where it left off and "
+ "without signal to be sent\n");
+ ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
+
+ printf("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_exited(status, exitval);
+
+ printf("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+
static void
lwp_main_stop(void *arg)
{
@@ -7404,6 +7526,8 @@
ATF_TP_ADD_TC(tp, setsigmask2);
ATF_TP_ADD_TC(tp, setsigmask3);
ATF_TP_ADD_TC(tp, setsigmask4);
+ ATF_TP_ADD_TC(tp, setsigmask5);
+ ATF_TP_ADD_TC(tp, setsigmask6);
return atf_no_error();
}
Home |
Main Index |
Thread Index |
Old Index