This source file includes following definitions.
- aarch64_get_regs
- aarch64_set_regs
- read_memory
- user_alloca
- user_copy
- remove_tracee
- find_tracee
- handle_clone_prepare
- handle_clone
- syscall_trap_p
- check_signal
- handle_exec
- handle_readlinkat
- process_system_call
- tracing_execve
- after_fork
- exec_waitpid
- exec_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21
22 #include <sys/ptrace.h>
23 #include <sys/types.h>
24 #include <sys/wait.h>
25
26 #include <limits.h>
27 #include <stddef.h>
28 #include <string.h>
29 #include <assert.h>
30 #include <signal.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <errno.h>
34
35 #include "exec.h"
36
37 #include SYSCALL_HEADER
38 #include USER_HEADER
39
40 #ifdef __aarch64__
41 #include <sys/uio.h>
42 #include <linux/elf.h>
43 #endif
44
45 #ifdef HAVE_SYS_UIO_H
46 #include <sys/uio.h>
47 #endif
48
49 #ifndef SYS_SECCOMP
50 #define SYS_SECCOMP 1
51 #endif
52
53 #ifndef PTRACE_GETEVENTMSG
54 #define PTRACE_GETEVENTMSG 0x4201
55 #endif
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 #define MAX_TRACEES 4096
71
72 #ifdef __aarch64__
73
74
75
76
77 int
78 aarch64_get_regs (pid_t pid, USER_REGS_STRUCT *regs)
79 {
80 struct iovec iov;
81
82 iov.iov_base = regs;
83 iov.iov_len = sizeof *regs;
84
85 return (ptrace (PTRACE_GETREGSET, pid, NT_PRSTATUS,
86 &iov) != 0);
87 }
88
89
90
91
92
93
94 int
95 aarch64_set_regs (pid_t pid, USER_REGS_STRUCT *regs,
96 bool syscall_p)
97 {
98 struct iovec iov;
99 USER_WORD callno;
100 long rc;
101
102
103
104 iov.iov_base = regs;
105 iov.iov_len = sizeof *regs;
106
107 rc = ptrace (PTRACE_SETREGSET, pid, NT_PRSTATUS,
108 &iov);
109 if (rc < 0)
110 return 1;
111
112
113
114 if (syscall_p)
115 {
116 callno = regs->regs[8];
117 iov.iov_base = &callno;
118 iov.iov_len = sizeof callno;
119
120 return (ptrace (PTRACE_SETREGSET, pid, NT_ARM_SYSTEM_CALL,
121 &iov) != 0);
122 }
123
124 return 0;
125 }
126
127 #endif
128
129
130
131
132 static struct exec_tracee *tracing_processes;
133
134
135
136
137
138
139
140
141
142 static void
143 read_memory (struct exec_tracee *tracee, char *buffer,
144 USER_WORD n, USER_WORD address)
145 {
146 USER_WORD word, n_words, n_bytes, i;
147 long rc;
148 #ifdef HAVE_PROCESS_VM
149 struct iovec iov, remote;
150
151
152
153 iov.iov_base = buffer;
154 iov.iov_len = n;
155 remote.iov_base = (void *) address;
156 remote.iov_len = n;
157
158
159
160
161 if (n <= SSIZE_MAX
162 && ((size_t) process_vm_readv (tracee->pid, &iov, 1,
163 &remote, 1, 0) != -1))
164 return;
165
166 #endif
167
168
169 n_words = n & ~(sizeof (USER_WORD) - 1);
170
171
172
173 n_bytes = n & (sizeof (USER_WORD) - 1);
174
175
176 i = 0;
177 while (n_words)
178 {
179 rc = ptrace (PTRACE_PEEKTEXT, tracee->pid,
180 (void *) address + i, NULL);
181 word = rc;
182 memcpy (buffer, &word, sizeof word);
183 buffer += sizeof word;
184 i += sizeof word;
185 n_words -= sizeof word;
186 }
187
188
189 assert (n_bytes < sizeof (word));
190
191 if (n_bytes)
192 {
193 rc = ptrace (PTRACE_PEEKTEXT, tracee->pid,
194 (void *) address + i, NULL);
195 word = rc;
196
197
198 memcpy (buffer, &word, n_bytes);
199 }
200 }
201
202
203
204
205
206
207
208
209
210
211 USER_WORD
212 user_alloca (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
213 USER_REGS_STRUCT *new_regs, USER_WORD n)
214 {
215 USER_WORD sp, old_sp;
216
217
218 old_sp = sp = new_regs->STACK_POINTER;
219
220 #if RED_ZONE_SIZE
221
222
223
224 #ifdef STACK_GROWS_DOWNWARDS
225 if (sp == regs->STACK_POINTER)
226 sp -= RED_ZONE_SIZE;
227 #else
228 if (sp == regs->STACK_POINTER)
229 sp += RED_ZONE_SIZE;
230 #endif
231 #endif
232
233
234
235 #ifdef STACK_GROWS_DOWNWARDS
236 sp = sp - n;
237
238
239
240 if (sp > new_regs->STACK_POINTER)
241 return 0;
242 #else
243 sp = sp + n;
244
245
246
247 if (sp < new_regs->STACK_POINTER)
248 return 0;
249 #endif
250
251
252 new_regs->STACK_POINTER = sp;
253
254 #ifdef __aarch64__
255 if (aarch64_set_regs (tracee->pid, new_regs, false))
256 goto fail;
257 #else
258 if (ptrace (PTRACE_SETREGS, tracee->pid, NULL,
259 new_regs))
260 goto fail;
261 #endif
262
263
264 #ifdef STACK_GROWS_DOWNWARDS
265 return sp;
266 #else
267 return sp - n;
268 #endif
269
270 fail:
271
272 new_regs->STACK_POINTER = old_sp;
273 return 0;
274 }
275
276
277
278
279 int
280 user_copy (struct exec_tracee *tracee, const unsigned char *buffer,
281 USER_WORD address, USER_WORD n)
282 {
283 USER_WORD start, end, word;
284 unsigned char *bytes;
285 #ifdef HAVE_PROCESS_VM
286 struct iovec iov, remote;
287
288
289
290
291 iov.iov_base = (void *) buffer;
292 iov.iov_len = n;
293 remote.iov_base = (void *) address;
294 remote.iov_len = n;
295
296 if (n <= SSIZE_MAX
297 && ((size_t) process_vm_writev (tracee->pid, &iov, 1,
298 &remote, 1, 0) == n))
299 return 0;
300 #endif
301
302
303
304 start = address;
305 end = address + n;
306
307
308
309 while (start < end)
310 {
311 if (start + sizeof word <= end)
312 {
313
314 memcpy (&word, buffer, sizeof word);
315 buffer += sizeof word;
316
317 if (ptrace (PTRACE_POKEDATA, tracee->pid,
318 (void *) start, (void *) word))
319 return 1;
320
321 start += sizeof word;
322 }
323 else
324 {
325
326
327
328
329 word = ptrace (PTRACE_PEEKDATA, tracee->pid,
330 (void *) start, NULL);
331 bytes = (unsigned char *) &word;
332 memcpy (bytes, buffer, end - start);
333
334 if (ptrace (PTRACE_POKEDATA, tracee->pid,
335 (void *) start, (void *) word))
336 return 1;
337
338
339 return 0;
340 }
341 }
342
343 return 0;
344 }
345
346
347
348
349 static struct exec_tracee *free_tracees;
350
351
352
353
354 static void
355 remove_tracee (struct exec_tracee *tracee)
356 {
357 struct exec_tracee **last;
358
359 last = &tracing_processes;
360 while (*last)
361 {
362 if (*last == tracee)
363 {
364 *last = tracee->next;
365
366
367 tracee->next = free_tracees;
368
369 #ifndef REENTRANT
370
371 free (tracee->exec_file);
372 tracee->exec_file = NULL;
373 #endif
374
375 free_tracees = tracee;
376
377 return;
378 }
379 else
380 last = &(*last)->next;
381 }
382 }
383
384
385
386
387
388
389 static struct exec_tracee static_tracees[MAX_TRACEES];
390
391
392 static int tracees;
393
394
395
396
397 static struct exec_tracee *
398 find_tracee (pid_t process)
399 {
400 struct exec_tracee *tracee;
401
402 for (tracee = tracing_processes; tracee; tracee = tracee->next)
403 {
404 if (tracee->pid == process)
405 return tracee;
406 }
407
408 return NULL;
409 }
410
411
412
413
414
415
416
417
418 static void
419 handle_clone_prepare (struct exec_tracee *parent)
420 {
421 #ifndef REENTRANT
422 long rc;
423 unsigned long pid;
424 struct exec_tracee *tracee;
425
426 rc = ptrace (PTRACE_GETEVENTMSG, parent->pid, NULL,
427 &pid);
428 if (rc)
429 return;
430
431
432 tracee = find_tracee (pid);
433
434 if (tracee)
435 {
436
437
438
439 assert (tracee->new_child);
440 tracee->new_child = false;
441 tracee->exec_file = NULL;
442 ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0);
443
444 if (parent->exec_file)
445 tracee->exec_file = strdup (parent->exec_file);
446 return;
447 }
448
449 if (free_tracees)
450 {
451 tracee = free_tracees;
452 free_tracees = free_tracees->next;
453 }
454 else if (tracees < MAX_TRACEES)
455 {
456 tracee = &static_tracees[tracees];
457 tracees++;
458 }
459 #ifndef REENTRANT
460
461
462 else if ((tracee = malloc (sizeof *tracee)))
463 ;
464 #endif
465 else
466 return;
467
468 tracee->pid = pid;
469 tracee->next = tracing_processes;
470 tracee->waiting_for_syscall = false;
471 tracee->new_child = true;
472 tracee->exec_file = NULL;
473 tracing_processes = tracee;
474
475
476
477 if (parent->exec_file)
478 tracee->exec_file = strdup (parent->exec_file);
479 #endif
480 }
481
482
483
484
485
486
487
488
489
490
491
492 static int
493 handle_clone (struct exec_tracee *tracee, pid_t pid)
494 {
495 long rc;
496 int flags, value;
497
498
499
500
501 value = 0;
502
503 if (!tracee)
504 {
505 if (free_tracees)
506 {
507 tracee = free_tracees;
508 free_tracees = free_tracees->next;
509 }
510 else if (tracees < MAX_TRACEES)
511 {
512 tracee = &static_tracees[tracees];
513 tracees++;
514 }
515 #ifndef REENTRANT
516
517
518 else if ((tracee = malloc (sizeof *tracee)))
519 ;
520 #endif
521 else
522 return 1;
523
524 tracee->pid = pid;
525 tracee->next = tracing_processes;
526 tracee->waiting_for_syscall = false;
527 #ifndef REENTRANT
528 tracee->exec_file = NULL;
529 #endif
530 tracing_processes = tracee;
531 tracee->new_child = true;
532
533
534 value = 2;
535 }
536 else
537
538
539 tracee->new_child = false;
540
541
542
543
544
545 flags = PTRACE_O_TRACECLONE;
546 flags |= PTRACE_O_TRACEVFORK;
547 flags |= PTRACE_O_TRACEFORK;
548 flags |= PTRACE_O_TRACESYSGOOD;
549 flags |= PTRACE_O_TRACEEXIT;
550
551 rc = ptrace (PTRACE_SETOPTIONS, pid, 0, flags);
552
553 if (rc)
554 goto bail;
555
556 if (value != 2)
557 {
558
559
560
561 rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
562
563 if (rc)
564 goto bail;
565 }
566
567 return value;
568
569 bail:
570 remove_tracee (tracee);
571 return 1;
572 }
573
574
575
576
577
578
579
580 static const char *loader_name;
581
582
583
584
585
586
587 static bool
588 syscall_trap_p (siginfo_t *signal)
589 {
590
591
592 return (signal->si_code == SIGTRAP
593 || signal->si_code == (SIGTRAP | SI_KERNEL));
594 }
595
596
597
598
599
600
601
602 static int
603 check_signal (struct exec_tracee *tracee, int status)
604 {
605 siginfo_t siginfo;
606
607 switch ((status & 0xfff00) >> 8)
608 {
609 case SIGTRAP:
610
611
612
613 if (ptrace (PTRACE_GETSIGINFO, tracee->pid, 0, &siginfo))
614 return -1;
615
616 if (!syscall_trap_p (&siginfo))
617 {
618 if (siginfo.si_code < 0)
619
620 ptrace (PTRACE_SYSCALL, tracee->pid, 0, SIGTRAP);
621 else
622 ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0);
623
624 return 1;
625 }
626
627 case SIGTRAP | 0x80:
628
629 break;
630
631 #ifdef SIGSYS
632 case SIGSYS:
633 if (ptrace (PTRACE_GETSIGINFO, tracee->pid, 0, &siginfo))
634 return -1;
635
636
637
638
639 #ifdef HAVE_SIGINFO_T_SI_SYSCALL
640 #ifndef __arm__
641 ptrace (PTRACE_SYSCALL, tracee->pid,
642 0, ((siginfo.si_code == SYS_SECCOMP
643 && siginfo.si_syscall == -1)
644 ? 0 : status));
645 #else
646 ptrace (PTRACE_SYSCALL, tracee->pid,
647 0, ((siginfo.si_code == SYS_SECCOMP
648 && siginfo.si_syscall == 222)
649 ? 0 : status));
650 #endif
651 #else
652
653 ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0);
654 #endif
655 return 1;
656 #endif
657
658 default:
659
660 ptrace (PTRACE_SYSCALL, tracee->pid, 0, status);
661 return 1;
662 }
663
664 return 0;
665 }
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683 static int
684 handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
685 {
686 char buffer[PATH_MAX + 80], *area;
687 USER_REGS_STRUCT original;
688 size_t size, loader_size;
689 USER_WORD loader, size1, sp;
690 int rc, wstatus;
691 siginfo_t siginfo;
692
693
694 sp = regs->STACK_POINTER;
695
696
697 read_memory (tracee, buffer, PATH_MAX,
698 regs->SYSCALL_ARG_REG);
699
700
701
702 if (!memchr (buffer, '\0', PATH_MAX))
703 {
704 errno = ENAMETOOLONG;
705 return 1;
706 }
707
708
709 memcpy (&original, regs, sizeof *regs);
710
711
712 again1:
713 area = exec_0 (buffer, tracee, &size, regs);
714
715 if (!area)
716 {
717
718 if (errno == EINTR)
719 goto again1;
720
721 return 1;
722 }
723
724
725
726 loader_size = strlen (loader_name) + 1;
727 loader = user_alloca (tracee, &original, regs,
728 loader_size);
729
730 if (!loader)
731 {
732 errno = ENOMEM;
733 return 1;
734 }
735
736 if (user_copy (tracee, (unsigned char *) loader_name,
737 loader, loader_size))
738 {
739 errno = EIO;
740 return 1;
741 }
742
743 regs->SYSCALL_ARG_REG = loader;
744
745 #ifdef __aarch64__
746
747 if (aarch64_set_regs (tracee->pid, regs, false))
748 {
749 errno = EIO;
750 return 1;
751 }
752
753 #else
754
755 if (ptrace (PTRACE_SETREGS, tracee->pid, NULL,
756 regs))
757 {
758 errno = EIO;
759 return 1;
760 }
761
762 #endif
763
764
765
766 if (ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL))
767 {
768 errno = EIO;
769 return 1;
770 }
771
772 #ifndef REENTRANT
773
774
775
776
777
778 if (tracee->exec_file)
779 free (tracee->exec_file);
780 tracee->exec_file = strdup (buffer);
781 #endif
782
783 again:
784 rc = waitpid (tracee->pid, &wstatus, __WALL);
785 if (rc == -1 && errno == EINTR)
786 goto again;
787
788 if (rc < 0)
789 return 1;
790
791 if (!WIFSTOPPED (wstatus))
792
793
794 return 2;
795 else
796 {
797
798
799 rc = check_signal (tracee, wstatus);
800
801 if (rc == -1)
802 return 2;
803 else if (rc)
804 goto again;
805
806
807
808
809 if (ptrace (PTRACE_GETSIGINFO, tracee->pid, 0,
810 &siginfo))
811 return 3;
812
813 if (!syscall_trap_p (&siginfo))
814 {
815
816 if (ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0))
817 return 3;
818
819 goto again;
820 }
821 }
822
823 #ifdef __aarch64__
824
825 if (aarch64_get_regs (tracee->pid, &original))
826 return 3;
827
828 #else
829
830
831
832 if (ptrace (PTRACE_GETREGS, tracee->pid, NULL,
833 &original))
834 return 3;
835
836 #endif
837
838 *regs = original;
839
840
841
842
843 if (original.SYSCALL_RET_REG)
844 {
845
846 regs->STACK_POINTER = sp;
847
848 #ifdef __aarch64__
849 aarch64_set_regs (tracee->pid, regs, false);
850 #else
851 ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs);
852 #endif
853
854 goto exec_failure;
855 }
856
857
858
859
860 loader = user_alloca (tracee, &original, regs,
861 size + sizeof loader * 2);
862 if (!loader)
863 return 3;
864
865 size1 = size;
866
867 #ifndef STACK_GROWS_DOWNWARDS
868
869 NOT_IMPLEMENTED;
870
871 #else
872
873 if (user_copy (tracee, (unsigned char *) area,
874 loader + sizeof size1 * 2, size)
875 || user_copy (tracee, (unsigned char *) &size1,
876 loader + sizeof size1, sizeof size1))
877 return 3;
878
879 size1 = original.STACK_POINTER;
880
881 if (user_copy (tracee, (unsigned char *) &size1,
882 loader, sizeof size1))
883 return 3;
884
885 #endif
886
887
888 if (ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0))
889 return 3;
890
891 return 0;
892
893 exec_failure:
894 return 3;
895 }
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913 static int
914 handle_readlinkat (USER_WORD callno, USER_REGS_STRUCT *regs,
915 struct exec_tracee *tracee, USER_WORD *result)
916 {
917 #ifdef REENTRANT
918
919
920
921 return 0;
922 #else
923
924 char buffer[PATH_MAX + 1];
925 USER_WORD address, return_buffer, size;
926 size_t length;
927
928
929
930 #ifdef READLINK_SYSCALL
931 if (callno == READLINK_SYSCALL)
932 {
933 address = regs->SYSCALL_ARG_REG;
934 return_buffer = regs->SYSCALL_ARG1_REG;
935 size = regs->SYSCALL_ARG2_REG;
936 }
937 else
938 #endif
939 {
940 address = regs->SYSCALL_ARG1_REG;
941 return_buffer = regs->SYSCALL_ARG2_REG;
942 size = regs->SYSCALL_ARG3_REG;
943 }
944
945 read_memory (tracee, buffer, PATH_MAX, address);
946
947
948
949 if (!memchr (buffer, '\0', PATH_MAX))
950 {
951 errno = ENAMETOOLONG;
952 return 1;
953 }
954
955
956
957
958
959
960 if (strcmp (buffer, "/proc/self/exe") || !tracee->exec_file)
961 return 0;
962
963
964
965
966 length = strlen (tracee->exec_file);
967 length = MIN (size, MIN (PATH_MAX, length));
968 strncpy (buffer, tracee->exec_file, length);
969
970 if (user_copy (tracee, (unsigned char *) buffer,
971 return_buffer, length))
972 {
973 errno = EIO;
974 return 1;
975 }
976
977 *result = length;
978 return 2;
979 #endif
980 }
981
982
983
984
985
986 static void
987 process_system_call (struct exec_tracee *tracee)
988 {
989 USER_REGS_STRUCT regs;
990 int rc, wstatus, save_errno;
991 USER_WORD callno, sp;
992 USER_WORD result;
993 bool reporting_error;
994
995 #ifdef __aarch64__
996 rc = aarch64_get_regs (tracee->pid, ®s);
997 #else
998 rc = ptrace (PTRACE_GETREGS, tracee->pid, NULL,
999 ®s);
1000 #endif
1001
1002
1003 if (rc < 0)
1004 return;
1005
1006
1007 sp = regs.STACK_POINTER;
1008
1009
1010 callno = regs.SYSCALL_NUM_REG;
1011 switch (callno)
1012 {
1013 case EXEC_SYSCALL:
1014
1015
1016 assert (!tracee->waiting_for_syscall);
1017 rc = handle_exec (tracee, ®s);
1018
1019 switch (rc)
1020 {
1021 case 3:
1022
1023 break;
1024
1025 case 2:
1026
1027 remove_tracee (tracee);
1028 break;
1029
1030 case 1:
1031
1032 goto report_syscall_error;
1033 }
1034
1035 break;
1036
1037 #ifdef READLINK_SYSCALL
1038 case READLINK_SYSCALL:
1039 #endif
1040 case READLINKAT_SYSCALL:
1041
1042
1043 rc = handle_readlinkat (callno, ®s, tracee,
1044 &result);
1045
1046
1047
1048 if (rc == 1)
1049 goto report_syscall_error;
1050 else if (rc == 2)
1051 goto emulate_syscall;
1052
1053
1054
1055 default:
1056
1057
1058
1059
1060 rc = ptrace (PTRACE_SYSCALL, tracee->pid,
1061 NULL, NULL);
1062 if (rc < 0)
1063 return;
1064
1065 tracee->waiting_for_syscall = !tracee->waiting_for_syscall;
1066 }
1067
1068 return;
1069
1070 report_syscall_error:
1071 reporting_error = true;
1072 goto common;
1073
1074 emulate_syscall:
1075 reporting_error = false;
1076 common:
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 save_errno = errno;
1087
1088 regs.SYSCALL_NUM_REG = -1;
1089 regs.STACK_POINTER = sp;
1090
1091 #ifdef __aarch64__
1092 if (aarch64_set_regs (tracee->pid, ®s, true))
1093 return;
1094 #else
1095
1096 #ifdef __arm__
1097
1098
1099
1100
1101
1102 if (ptrace (PTRACE_SET_SYSCALL, tracee->pid, NULL, 222))
1103 return;
1104 #endif
1105
1106 if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s))
1107 return;
1108 #endif
1109
1110
1111 if (ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL))
1112 return;
1113
1114 again1:
1115 rc = waitpid (tracee->pid, &wstatus, __WALL);
1116 if (rc == -1 && errno == EINTR)
1117 goto again1;
1118
1119
1120
1121 if (rc == -1)
1122 return;
1123
1124
1125
1126
1127 if (WIFSTOPPED (wstatus))
1128 {
1129 rc = check_signal (tracee, wstatus);
1130
1131 if (rc == -1)
1132 return;
1133 else if (rc)
1134 goto again1;
1135 }
1136
1137 if (!WIFSTOPPED (wstatus))
1138
1139
1140 remove_tracee (tracee);
1141 else if (reporting_error)
1142 {
1143 #ifdef __mips__
1144
1145 regs.gregs[2] = save_errno;
1146 regs.gregs[7] = 1;
1147 #else
1148 regs.SYSCALL_RET_REG = -save_errno;
1149 #endif
1150
1151
1152 #ifdef __aarch64__
1153 aarch64_set_regs (tracee->pid, ®s, false);
1154 #else
1155 ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s);
1156 #endif
1157
1158
1159 ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL);
1160 }
1161 else
1162 {
1163
1164
1165
1166 #ifdef __mips__
1167
1168 regs.gregs[2] = result;
1169 regs.gregs[7] = 0;
1170 #else
1171 regs.SYSCALL_RET_REG = result;
1172 #endif
1173
1174
1175 #ifdef __aarch64__
1176 aarch64_set_regs (tracee->pid, ®s, false);
1177 #else
1178 ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s);
1179 #endif
1180
1181
1182 ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL);
1183 }
1184 }
1185
1186
1187
1188
1189
1190
1191 int
1192 tracing_execve (const char *file, char *const *argv,
1193 char *const *envp)
1194 {
1195 int rc;
1196
1197
1198 rc = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
1199 if (rc)
1200 return rc;
1201
1202
1203 raise (SIGSTOP);
1204 return execve (file, argv, envp);
1205 }
1206
1207
1208
1209
1210
1211
1212
1213
1214 int
1215 after_fork (pid_t pid)
1216 {
1217 int wstatus, rc, flags;
1218 struct exec_tracee *tracee;
1219
1220
1221 again:
1222 rc = waitpid (pid, &wstatus, __WALL);
1223 if (rc != pid && errno == EINTR)
1224 goto again;
1225
1226 if (rc != pid)
1227 return 1;
1228
1229
1230
1231 if (!WIFSTOPPED (wstatus))
1232 return 2;
1233
1234
1235
1236
1237
1238 flags = PTRACE_O_TRACECLONE;
1239 flags |= PTRACE_O_TRACEVFORK;
1240 flags |= PTRACE_O_TRACEFORK;
1241 flags |= PTRACE_O_TRACESYSGOOD;
1242 flags |= PTRACE_O_TRACEEXIT;
1243
1244 rc = ptrace (PTRACE_SETOPTIONS, pid, 0, flags);
1245
1246 if (rc)
1247 {
1248
1249
1250 ptrace (PTRACE_DETACH, pid, 0, 0);
1251 return 1;
1252 }
1253
1254
1255 rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
1256 if (rc)
1257 return 1;
1258
1259
1260
1261 if (free_tracees)
1262 {
1263 tracee = free_tracees;
1264 free_tracees = free_tracees->next;
1265 }
1266 else
1267 tracee = malloc (sizeof *tracee);
1268
1269 if (!tracee)
1270 return 1;
1271
1272 tracee->pid = pid;
1273 tracee->next = tracing_processes;
1274 tracee->waiting_for_syscall = false;
1275 tracee->new_child = false;
1276 #ifndef REENTRANT
1277 tracee->exec_file = NULL;
1278 #endif
1279 tracing_processes = tracee;
1280 return 0;
1281 }
1282
1283
1284
1285
1286
1287 pid_t
1288 exec_waitpid (pid_t pid, int *wstatus, int options)
1289 {
1290 int status;
1291 struct exec_tracee *tracee;
1292 siginfo_t siginfo;
1293
1294 pid = waitpid (pid, &status, options | __WALL);
1295 if (pid < 0)
1296 return pid;
1297
1298
1299 if (wstatus)
1300 *wstatus = status;
1301
1302
1303
1304
1305
1306 if (WIFSTOPPED (status))
1307 {
1308 tracee = find_tracee (pid);
1309
1310 if (!tracee || tracee->new_child)
1311 {
1312 if (WSTOPSIG (status) == SIGSTOP)
1313
1314
1315 handle_clone (tracee, pid);
1316
1317 return -1;
1318 }
1319
1320
1321 status &= 0xfff00;
1322 status = status >> 8;
1323
1324 switch (status)
1325 {
1326 case SIGTRAP:
1327
1328
1329
1330 if (ptrace (PTRACE_GETSIGINFO, pid, 0, &siginfo))
1331 return -1;
1332
1333 if (!syscall_trap_p (&siginfo))
1334 {
1335 if (siginfo.si_code < 0)
1336
1337 ptrace (PTRACE_SYSCALL, pid, 0, SIGTRAP);
1338 else
1339 ptrace (PTRACE_SYSCALL, pid, 0, 0);
1340
1341 return -1;
1342 }
1343
1344 case SIGTRAP | 0x80:
1345
1346
1347 process_system_call (tracee);
1348 return -1;
1349
1350 case SIGTRAP | (PTRACE_EVENT_EXIT << 8):
1351
1352 ptrace (PTRACE_SYSCALL, pid, 0, 0);
1353 remove_tracee (tracee);
1354 return -1;
1355
1356 case SIGTRAP | (PTRACE_EVENT_FORK << 8):
1357 case SIGTRAP | (PTRACE_EVENT_VFORK << 8):
1358 case SIGTRAP | (PTRACE_EVENT_CLONE << 8):
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372 handle_clone_prepare (tracee);
1373
1374
1375
1376
1377 ptrace (PTRACE_SYSCALL, pid, 0, 0);
1378 return -1;
1379
1380 #ifdef SIGSYS
1381 case SIGSYS:
1382 if (ptrace (PTRACE_GETSIGINFO, pid, 0, &siginfo))
1383 return -1;
1384
1385
1386
1387
1388 #ifdef HAVE_SIGINFO_T_SI_SYSCALL
1389 #ifndef __arm__
1390 ptrace (PTRACE_SYSCALL, pid, 0, ((siginfo.si_code == SYS_SECCOMP
1391 && siginfo.si_syscall == -1)
1392 ? 0 : status));
1393 #else
1394 ptrace (PTRACE_SYSCALL, pid, 0, ((siginfo.si_code == SYS_SECCOMP
1395 && siginfo.si_syscall == 222)
1396 ? 0 : status));
1397 #endif
1398 #else
1399
1400 ptrace (PTRACE_SYSCALL, pid, 0, 0);
1401 #endif
1402 return -1;
1403 #endif
1404
1405 default:
1406
1407 ptrace (PTRACE_SYSCALL, pid, 0, status);
1408 return -1;
1409 }
1410 }
1411 else
1412 {
1413
1414 tracee = find_tracee (pid);
1415
1416 if (tracee)
1417 remove_tracee (tracee);
1418
1419 return pid;
1420 }
1421 }
1422
1423
1424
1425
1426
1427
1428 void
1429 exec_init (const char *loader)
1430 {
1431 loader_name = loader;
1432 }