]>
git.saurik.com Git - apple/xnu.git/blob - tools/tests/unit_tests/ptrace_tests_10767133_src/ptrace_tests_10767133.c
c863c03d18caa0a449ddb6e4bfa5b2d57a92317d
2 * File: ptrace_tests_10767133.c
3 * Test Description: Testing different functions of the ptrace call.
4 * Radar: <rdar://problem/10767133>
5 * compile command: cc -o ../BUILD/ptrace_tests_10767133 ptrace_tests_10767133.c
13 #include <sys/types.h>
14 #include <sys/ptrace.h>
18 #define assert_condition(condition, exit_status, cause) \
20 printf("[FAILED] %s:%s at %d error: %s \n", "test_10767133", __func__ , __LINE__, cause ); \
26 #define log_message(msg) \
27 printf("%s:%d -> %s \n", __func__, __LINE__, msg);
32 ssize_t
pipe_read_data(pipe_t p
, void *dest_buf
, int size
)
35 int retval
= read(fd
, dest_buf
, size
);
37 printf("Error reading from buffer. ");
43 ssize_t
pipe_write_data(pipe_t p
, void *src_buf
, int size
)
46 int retval
= write(fd
, src_buf
, size
);
48 printf("Error writing to buffer. ");
56 void test_ptrace_deny_tace_sigexc();
57 void test_ptrace_attach_detach();
58 void test_ptrace_step_kill();
62 log_message(" Testing for PT_FORCEQUOTA. it should return EPERM for non root program. ");
64 retval
= ptrace(PT_FORCEQUOTA
, getpid(), NULL
, 0);
65 assert_condition( (retval
== -1 && errno
== EPERM
), -1, "PT_FORCEQUOTA");
67 log_message(" Testing to PT_DENY_ATTACH. should return successfully as nobody is tracing me.")
68 retval
= ptrace(PT_DENY_ATTACH
, getpid(), NULL
, 0);
69 assert_condition (retval
== 0 , -2, "PR_DENY_ATTACH");
70 test_ptrace_deny_tace_sigexc();
71 test_ptrace_attach_detach();
72 test_ptrace_step_kill();
74 printf("[PASSED] Test test_10767133 passed. \n");
77 printf("[FAILED] Test test_10767133 failed. \n");
81 void test_ptrace_step_kill(){
82 int retval
= 0, status
=1;
83 int parentpipe
[2], childpipe
[2], data
;
84 enum data_state
{ begin
, finished_child_loop
, finished_parent_detach
};
85 retval
= pipe(childpipe
);
86 assert_condition(retval
== 0, -1, "Pipe create");
87 retval
= pipe(parentpipe
);
88 assert_condition(retval
== 0, -1, "Pipe create");
89 int childpid
= fork();
90 assert_condition(childpid
>=0, -1, "fork failed");
92 if (childpid
== 0){ /* child */
93 pipe_read_data(parentpipe
, &data
, sizeof(data
));
94 assert_condition(data
== begin
, -1, "child: parent not setting begin");
95 pipe_write_data(childpipe
, &data
, sizeof(data
));
96 log_message("child: running the sleep loop");
98 log_message("child: sleep loop");
103 data
= finished_child_loop
;
104 log_message("child: finished sleep loop");
105 pipe_write_data(childpipe
, &data
, sizeof(data
));
106 pipe_read_data(parentpipe
, &data
, sizeof(data
));
107 assert_condition(data
== finished_parent_detach
, -1, "child: parent not done with detach");
109 log_message("child: sleep loop 2");
117 pipe_write_data(parentpipe
, &data
, sizeof(data
));
119 pipe_read_data(childpipe
, &data
, sizeof(data
));
120 assert_condition(data
== begin
, -1, "child is not ready with TRACE_ME setup");
121 printf("parent: attaching to child with pid %d \n", childpid
);
122 retval
= ptrace(PT_ATTACH
, childpid
, NULL
, 0);
123 assert_condition(retval
== 0, -1, "parent: failed to attach to child");
125 log_message("parent: attached to child. Now PT_STEP through it");
126 retval
= ptrace(PT_STEP
, childpid
, (caddr_t
)1, 0);
127 assert_condition(retval
== 0, -1, "parent: failed to continue the child");
129 retval
= ptrace(PT_STEP
, childpid
, (caddr_t
)1, 0);
130 assert_condition(retval
== 0, -1, "parent: failed to continue the child");
131 log_message("parent: issuing PT_KILL to child ");
133 retval
= ptrace(PT_KILL
, childpid
, NULL
, 0);
134 assert_condition(retval
== 0, -1, "parent: failed to PT_KILL the child");
135 data
= finished_parent_detach
;
136 pipe_write_data(parentpipe
, &data
, sizeof(data
));
137 waitpid(childpid
,&status
,0);
138 assert_condition(status
!= 57, -1, "child has exited successfully. It should have died with signal 9");
139 assert_condition(status
== 9, -1, "child has exited unexpectedly. Should have died with signal 9");
144 void test_ptrace_attach_detach(){
145 int retval
= 0, status
=1;
146 int parentpipe
[2], childpipe
[2], data
;
147 enum data_state
{ begin
, finished_child_loop
, finished_parent_detach
};
148 retval
= pipe(childpipe
);
149 assert_condition(retval
== 0, -1, "Pipe create");
150 retval
= pipe(parentpipe
);
151 assert_condition(retval
== 0, -1, "Pipe create");
152 int childpid
= fork();
153 assert_condition(childpid
>=0, -1, "fork failed");
155 if (childpid
== 0){ /* child */
156 //retval = ptrace(PT_TRACE_ME, getpid(), NULL, 0);
157 //assert_condition(retval == 0, -1, "PT_TRACE_ME failed");
158 pipe_read_data(parentpipe
, &data
, sizeof(data
));
159 assert_condition(data
== begin
, -1, "child: parent not setting begin");
160 pipe_write_data(childpipe
, &data
, sizeof(data
));
161 log_message("child: running the sleep loop");
163 log_message("child: sleep looping");
168 data
= finished_child_loop
;
169 log_message("child: finished sleep loop");
170 pipe_write_data(childpipe
, &data
, sizeof(data
));
171 pipe_read_data(parentpipe
, &data
, sizeof(data
));
172 assert_condition(data
== finished_parent_detach
, -1, "child: parent not done with detach");
174 log_message("child sleep looping too");
182 pipe_write_data(parentpipe
, &data
, sizeof(data
));
184 pipe_read_data(childpipe
, &data
, sizeof(data
));
185 assert_condition(data
== begin
, -1, "child is not ready with TRACE_ME setup");
186 printf("parent: attaching to child with pid %d \n", childpid
);
187 retval
= ptrace(PT_ATTACH
, childpid
, NULL
, 0);
188 assert_condition(retval
== 0, -1, "parent: failed to attach to child");
190 log_message("parent: attached to child. Now continuing it");
191 retval
= ptrace(PT_CONTINUE
, childpid
, (caddr_t
)1, 0);
192 assert_condition(retval
== 0, -1, "parent: failed to continue the child");
194 pipe_read_data(childpipe
, &data
, sizeof(data
));
195 assert_condition(data
== finished_child_loop
, -1, "parent: child has not finished while loop");
197 retval
= kill(childpid
, SIGSTOP
);
198 assert_condition(retval
== 0, -1, "parent: failed to SIGSTOP child");
201 log_message("parent: child has finished loop. Now detaching the child");
202 retval
= ptrace(PT_DETACH
, childpid
, NULL
, 0);
203 assert_condition(retval
== 0, -1, "parent: failed to detach");
205 data
= finished_parent_detach
;
206 pipe_write_data(parentpipe
, &data
, sizeof(data
));
207 waitpid(childpid
,&status
,0);
208 assert_condition(status
== 0, -1, "child has exited unexpectedly");
213 void test_ptrace_deny_tace_sigexc(){
214 enum ptrace_state
{ begin
,denied_attach
, sigexc_tested
,trace_me_set
, attached
, stepped
, continued
, killed
};
216 int childpipe
[2],parentpipe
[2], data
[2];
217 retval
= pipe(childpipe
);
218 assert_condition( retval
== 0, -3, "Pipe create");
219 retval
= pipe(parentpipe
);
220 assert_condition( retval
== 0, -3, "Pipe create");
222 data
[0] = begin
; // parent
223 data
[1] = begin
; //child
225 int childpid
= fork();
227 assert_condition(childpid
>=0, -4, "fork failed");
231 retval
= ptrace(PT_DENY_ATTACH
, getpid(), NULL
,0);
232 data
[1] = denied_attach
;
233 pipe_write_data(childpipe
, &data
[1], sizeof(int));
234 log_message("child: waiting for parent to write something");
235 pipe_read_data(parentpipe
, &data
[0], sizeof(int));
236 assert_condition(data
[0] == begin
, -5, "child: parent didnt begin with right state");
238 /* waiting for parent to verify that PT_SIGEXC fails since child is not yet traced. */
240 pipe_read_data(parentpipe
, &data
[0], sizeof(int));
241 assert_condition(data
[0] == sigexc_tested
, -5, " child: parent didnt test for sigexc failure");
242 log_message("child: setting myself to be traced");
243 retval
= ptrace(PT_TRACE_ME
, getpid(), NULL
,0);
244 assert_condition(retval
== 0, -6, "child: failed to setmyself for tracing");
245 data
[1]=trace_me_set
;
246 pipe_write_data(childpipe
, &data
[1], sizeof(int));
247 log_message("child: setting signals to be exceptions. PT_SIGEXC");
248 retval
= ptrace(PT_SIGEXC
, getpid(), NULL
, 0);
249 assert_condition(retval
== 0, -7, "child: failed to set PT_SIGEXC");
255 // get status of child
256 pipe_read_data(childpipe
, &data
[1], sizeof(int));
257 assert_condition(data
[1] == denied_attach
, -5, "parent: deny_attach_check");
258 pipe_write_data(parentpipe
, &data
[0], sizeof(int));
260 log_message("parent: testing for failure fo PT_SIGEXC ");
261 retval
= ptrace(PT_SIGEXC
, childpid
, NULL
, 0);
262 assert_condition(retval
< 0 , -5, "PT_SIGEXC did not fail for untraced child");
263 data
[0] = sigexc_tested
;
264 pipe_write_data(parentpipe
, &data
[0], sizeof(int));
266 pipe_read_data(childpipe
, &data
[1], sizeof(int));
267 assert_condition(data
[1] == trace_me_set
, -7, "parent: child has not set PT_TRACE_ME");
269 waitpid(childpid
, &status
, 0);
271 log_message("Child exited with non zero status");
278 close(parentpipe
[0]);
279 close(parentpipe
[1]);