0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "../kselftest_harness.h"
0011 #include <err.h>
0012 #include <signal.h>
0013 #include <asm/unistd.h>
0014 #include "linux/ptrace.h"
0015
0016 static int
0017 kill_tracee(pid_t pid)
0018 {
0019 if (!pid)
0020 return 0;
0021
0022 int saved_errno = errno;
0023
0024 int rc = kill(pid, SIGKILL);
0025
0026 errno = saved_errno;
0027 return rc;
0028 }
0029
0030 static long
0031 sys_ptrace(int request, pid_t pid, unsigned long addr, unsigned long data)
0032 {
0033 return syscall(__NR_ptrace, request, pid, addr, data);
0034 }
0035
0036 #define LOG_KILL_TRACEE(fmt, ...) \
0037 do { \
0038 kill_tracee(pid); \
0039 TH_LOG("wait #%d: " fmt, \
0040 ptrace_stop, ##__VA_ARGS__); \
0041 } while (0)
0042
0043 TEST(get_syscall_info)
0044 {
0045 static const unsigned long args[][7] = {
0046
0047 {
0048 __NR_chdir,
0049 (unsigned long) "",
0050 0xbad1fed1,
0051 0xbad2fed2,
0052 0xbad3fed3,
0053 0xbad4fed4,
0054 0xbad5fed5
0055 },
0056 {
0057 __NR_gettid,
0058 0xcaf0bea0,
0059 0xcaf1bea1,
0060 0xcaf2bea2,
0061 0xcaf3bea3,
0062 0xcaf4bea4,
0063 0xcaf5bea5
0064 },
0065 {
0066 __NR_exit_group,
0067 0,
0068 0xfac1c0d1,
0069 0xfac2c0d2,
0070 0xfac3c0d3,
0071 0xfac4c0d4,
0072 0xfac5c0d5
0073 }
0074 };
0075 const unsigned long *exp_args;
0076
0077 pid_t pid = fork();
0078
0079 ASSERT_LE(0, pid) {
0080 TH_LOG("fork: %m");
0081 }
0082
0083 if (pid == 0) {
0084
0085 pid = getpid();
0086 ASSERT_EQ(0, sys_ptrace(PTRACE_TRACEME, 0, 0, 0)) {
0087 TH_LOG("PTRACE_TRACEME: %m");
0088 }
0089 ASSERT_EQ(0, kill(pid, SIGSTOP)) {
0090
0091 TH_LOG("kill SIGSTOP: %m");
0092 }
0093 for (unsigned int i = 0; i < ARRAY_SIZE(args); ++i) {
0094 syscall(args[i][0],
0095 args[i][1], args[i][2], args[i][3],
0096 args[i][4], args[i][5], args[i][6]);
0097 }
0098
0099 _exit(1);
0100 }
0101
0102 const struct {
0103 unsigned int is_error;
0104 int rval;
0105 } *exp_param, exit_param[] = {
0106 { 1, -ENOENT },
0107 { 0, pid }
0108 };
0109
0110 unsigned int ptrace_stop;
0111
0112 for (ptrace_stop = 0; ; ++ptrace_stop) {
0113 struct ptrace_syscall_info info = {
0114 .op = 0xff
0115 };
0116 const size_t size = sizeof(info);
0117 const int expected_none_size =
0118 (void *) &info.entry - (void *) &info;
0119 const int expected_entry_size =
0120 (void *) &info.entry.args[6] - (void *) &info;
0121 const int expected_exit_size =
0122 (void *) (&info.exit.is_error + 1) -
0123 (void *) &info;
0124 int status;
0125 long rc;
0126
0127 ASSERT_EQ(pid, wait(&status)) {
0128
0129 LOG_KILL_TRACEE("wait: %m");
0130 }
0131 if (WIFEXITED(status)) {
0132 pid = 0;
0133 ASSERT_EQ(0, WEXITSTATUS(status));
0134 break;
0135 }
0136 ASSERT_FALSE(WIFSIGNALED(status)) {
0137 pid = 0;
0138 LOG_KILL_TRACEE("unexpected signal %u",
0139 WTERMSIG(status));
0140 }
0141 ASSERT_TRUE(WIFSTOPPED(status)) {
0142
0143 LOG_KILL_TRACEE("unexpected wait status %#x", status);
0144 }
0145
0146 switch (WSTOPSIG(status)) {
0147 case SIGSTOP:
0148 ASSERT_EQ(0, ptrace_stop) {
0149 LOG_KILL_TRACEE("unexpected signal stop");
0150 }
0151 ASSERT_EQ(0, sys_ptrace(PTRACE_SETOPTIONS, pid, 0,
0152 PTRACE_O_TRACESYSGOOD)) {
0153 LOG_KILL_TRACEE("PTRACE_SETOPTIONS: %m");
0154 }
0155 ASSERT_LT(0, (rc = sys_ptrace(PTRACE_GET_SYSCALL_INFO,
0156 pid, size,
0157 (unsigned long) &info))) {
0158 LOG_KILL_TRACEE("PTRACE_GET_SYSCALL_INFO: %m");
0159 }
0160 ASSERT_EQ(expected_none_size, rc) {
0161 LOG_KILL_TRACEE("signal stop mismatch");
0162 }
0163 ASSERT_EQ(PTRACE_SYSCALL_INFO_NONE, info.op) {
0164 LOG_KILL_TRACEE("signal stop mismatch");
0165 }
0166 ASSERT_TRUE(info.arch) {
0167 LOG_KILL_TRACEE("signal stop mismatch");
0168 }
0169 ASSERT_TRUE(info.instruction_pointer) {
0170 LOG_KILL_TRACEE("signal stop mismatch");
0171 }
0172 ASSERT_TRUE(info.stack_pointer) {
0173 LOG_KILL_TRACEE("signal stop mismatch");
0174 }
0175 break;
0176
0177 case SIGTRAP | 0x80:
0178 ASSERT_LT(0, (rc = sys_ptrace(PTRACE_GET_SYSCALL_INFO,
0179 pid, size,
0180 (unsigned long) &info))) {
0181 LOG_KILL_TRACEE("PTRACE_GET_SYSCALL_INFO: %m");
0182 }
0183 switch (ptrace_stop) {
0184 case 1:
0185 case 3:
0186 case 5:
0187 exp_args = args[ptrace_stop / 2];
0188 ASSERT_EQ(expected_entry_size, rc) {
0189 LOG_KILL_TRACEE("entry stop mismatch");
0190 }
0191 ASSERT_EQ(PTRACE_SYSCALL_INFO_ENTRY, info.op) {
0192 LOG_KILL_TRACEE("entry stop mismatch");
0193 }
0194 ASSERT_TRUE(info.arch) {
0195 LOG_KILL_TRACEE("entry stop mismatch");
0196 }
0197 ASSERT_TRUE(info.instruction_pointer) {
0198 LOG_KILL_TRACEE("entry stop mismatch");
0199 }
0200 ASSERT_TRUE(info.stack_pointer) {
0201 LOG_KILL_TRACEE("entry stop mismatch");
0202 }
0203 ASSERT_EQ(exp_args[0], info.entry.nr) {
0204 LOG_KILL_TRACEE("entry stop mismatch");
0205 }
0206 ASSERT_EQ(exp_args[1], info.entry.args[0]) {
0207 LOG_KILL_TRACEE("entry stop mismatch");
0208 }
0209 ASSERT_EQ(exp_args[2], info.entry.args[1]) {
0210 LOG_KILL_TRACEE("entry stop mismatch");
0211 }
0212 ASSERT_EQ(exp_args[3], info.entry.args[2]) {
0213 LOG_KILL_TRACEE("entry stop mismatch");
0214 }
0215 ASSERT_EQ(exp_args[4], info.entry.args[3]) {
0216 LOG_KILL_TRACEE("entry stop mismatch");
0217 }
0218 ASSERT_EQ(exp_args[5], info.entry.args[4]) {
0219 LOG_KILL_TRACEE("entry stop mismatch");
0220 }
0221 ASSERT_EQ(exp_args[6], info.entry.args[5]) {
0222 LOG_KILL_TRACEE("entry stop mismatch");
0223 }
0224 break;
0225 case 2:
0226 case 4:
0227 exp_param = &exit_param[ptrace_stop / 2 - 1];
0228 ASSERT_EQ(expected_exit_size, rc) {
0229 LOG_KILL_TRACEE("exit stop mismatch");
0230 }
0231 ASSERT_EQ(PTRACE_SYSCALL_INFO_EXIT, info.op) {
0232 LOG_KILL_TRACEE("exit stop mismatch");
0233 }
0234 ASSERT_TRUE(info.arch) {
0235 LOG_KILL_TRACEE("exit stop mismatch");
0236 }
0237 ASSERT_TRUE(info.instruction_pointer) {
0238 LOG_KILL_TRACEE("exit stop mismatch");
0239 }
0240 ASSERT_TRUE(info.stack_pointer) {
0241 LOG_KILL_TRACEE("exit stop mismatch");
0242 }
0243 ASSERT_EQ(exp_param->is_error,
0244 info.exit.is_error) {
0245 LOG_KILL_TRACEE("exit stop mismatch");
0246 }
0247 ASSERT_EQ(exp_param->rval, info.exit.rval) {
0248 LOG_KILL_TRACEE("exit stop mismatch");
0249 }
0250 break;
0251 default:
0252 LOG_KILL_TRACEE("unexpected syscall stop");
0253 abort();
0254 }
0255 break;
0256
0257 default:
0258 LOG_KILL_TRACEE("unexpected stop signal %#x",
0259 WSTOPSIG(status));
0260 abort();
0261 }
0262
0263 ASSERT_EQ(0, sys_ptrace(PTRACE_SYSCALL, pid, 0, 0)) {
0264 LOG_KILL_TRACEE("PTRACE_SYSCALL: %m");
0265 }
0266 }
0267
0268 ASSERT_EQ(ARRAY_SIZE(args) * 2, ptrace_stop);
0269 }
0270
0271 TEST_HARNESS_MAIN