tools/testing/selftests/ptrace/set_syscall_info.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/ptrace/set_syscall_info.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/ptrace/set_syscall_info.c
Extension
.c
Size
11935 bytes
Lines
520
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: syscall or user/kernel boundary
Status
core implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct si_entry {
	int nr;
	kernel_ulong_t args[6];
};
struct si_exit {
	unsigned int is_error;
	int rval;
};

static unsigned int ptrace_stop;
static pid_t tracee_pid;

static int
kill_tracee(pid_t pid)
{
	if (!pid)
		return 0;

	int saved_errno = errno;

	int rc = kill(pid, SIGKILL);

	errno = saved_errno;
	return rc;
}

static long
sys_ptrace(int request, pid_t pid, unsigned long addr, unsigned long data)
{
	return syscall(__NR_ptrace, request, pid, addr, data);
}

#define LOG_KILL_TRACEE(fmt, ...)				\
	do {							\
		kill_tracee(tracee_pid);			\
		TH_LOG("wait #%d: " fmt,			\
		       ptrace_stop, ##__VA_ARGS__);		\
	} while (0)

static void
check_psi_entry(struct __test_metadata *_metadata,
		const struct ptrace_syscall_info *info,
		const struct si_entry *exp_entry,
		const char *text)
{
	unsigned int i;
	int exp_nr = exp_entry->nr;
#if defined __s390__ || defined __s390x__
	/* s390 is the only architecture that has 16-bit syscall numbers */
	exp_nr &= 0xffff;
#endif

	ASSERT_EQ(PTRACE_SYSCALL_INFO_ENTRY, info->op) {
		LOG_KILL_TRACEE("%s: entry stop mismatch", text);
	}
	ASSERT_TRUE(info->arch) {
		LOG_KILL_TRACEE("%s: entry stop mismatch", text);
	}
	ASSERT_TRUE(info->instruction_pointer) {
		LOG_KILL_TRACEE("%s: entry stop mismatch", text);
	}
	ASSERT_TRUE(info->stack_pointer) {
		LOG_KILL_TRACEE("%s: entry stop mismatch", text);
	}
	ASSERT_EQ(exp_nr, info->entry.nr) {
		LOG_KILL_TRACEE("%s: syscall nr mismatch", text);
	}
	for (i = 0; i < ARRAY_SIZE(exp_entry->args); ++i) {
		ASSERT_EQ(exp_entry->args[i], info->entry.args[i]) {
			LOG_KILL_TRACEE("%s: syscall arg #%u mismatch",
					text, i);
		}
	}
}

static void
check_psi_exit(struct __test_metadata *_metadata,
	       const struct ptrace_syscall_info *info,
	       const struct si_exit *exp_exit,
	       const char *text)
{
	ASSERT_EQ(PTRACE_SYSCALL_INFO_EXIT, info->op) {
		LOG_KILL_TRACEE("%s: exit stop mismatch", text);
	}
	ASSERT_TRUE(info->arch) {
		LOG_KILL_TRACEE("%s: exit stop mismatch", text);
	}
	ASSERT_TRUE(info->instruction_pointer) {
		LOG_KILL_TRACEE("%s: exit stop mismatch", text);
	}

Annotation

Implementation Notes