Commit 71c87fbe authored by Kees Cook's avatar Kees Cook
Browse files

selftests/seccomp: Record syscall during ptrace entry



In preparation for performing actions during ptrace syscall exit, save
the syscall number during ptrace syscall entry. Some architectures do
no have the syscall number available during ptrace syscall exit.

Suggested-by: default avatarThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Link: https://lore.kernel.org/linux-kselftest/20200911181012.171027-1-cascardo@canonical.com/


Acked-by: default avatarChristian Brauner <christian.brauner@ubuntu.com>
Link: https://lore.kernel.org/lkml/20200921074354.6shkt2e5yhzhj3sn@wittgenstein/


Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent 46138329
Loading
Loading
Loading
Loading
+27 −13
Original line number Diff line number Diff line
@@ -1949,12 +1949,19 @@ void tracer_seccomp(struct __test_metadata *_metadata, pid_t tracee,

}

FIXTURE(TRACE_syscall) {
	struct sock_fprog prog;
	pid_t tracer, mytid, mypid, parent;
	long syscall_nr;
};

void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
		   int status, void *args)
{
	int ret, nr;
	int ret;
	unsigned long msg;
	static bool entry;
	FIXTURE_DATA(TRACE_syscall) *self = args;

	/*
	 * The traditional way to tell PTRACE_SYSCALL entry/exit
@@ -1968,23 +1975,30 @@ void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
	EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY
			: PTRACE_EVENTMSG_SYSCALL_EXIT, msg);

	if (!entry)
	/*
	 * Some architectures only support setting return values during
	 * syscall exit under ptrace, and on exit the syscall number may
	 * no longer be available. Therefore, save the initial sycall
	 * number here, so it can be examined during both entry and exit
	 * phases.
	 */
	if (entry)
		self->syscall_nr = get_syscall(_metadata, tracee);
	else
		return;

	nr = get_syscall(_metadata, tracee);

	if (nr == __NR_getpid)
	switch (self->syscall_nr) {
	case __NR_getpid:
		change_syscall(_metadata, tracee, __NR_getppid, 0);
	if (nr == __NR_gettid)
		break;
	case __NR_gettid:
		change_syscall(_metadata, tracee, -1, 45000);
	if (nr == __NR_openat)
		break;
	case __NR_openat:
		change_syscall(_metadata, tracee, -1, -ESRCH);
		break;
	}
}

FIXTURE(TRACE_syscall) {
	struct sock_fprog prog;
	pid_t tracer, mytid, mypid, parent;
};

FIXTURE_VARIANT(TRACE_syscall) {
	/*
@@ -2044,7 +2058,7 @@ FIXTURE_SETUP(TRACE_syscall)
	self->tracer = setup_trace_fixture(_metadata,
					   variant->use_ptrace ? tracer_ptrace
							       : tracer_seccomp,
					   NULL, variant->use_ptrace);
					   self, variant->use_ptrace);

	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
	ASSERT_EQ(0, ret);