Gentoo Archives: gentoo-commits

From: Mike Frysinger <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/sandbox:master commit in: libsandbox/trace/linux/, libsandbox/
Date: Sun, 20 Dec 2015 08:41:24
Message-Id: 1450572914.13b45f7910d6039e3a3a0971c786a5750f80cd9b.vapier@gentoo
1 commit: 13b45f7910d6039e3a3a0971c786a5750f80cd9b
2 Author: Mike Frysinger <vapier <AT> gentoo <DOT> org>
3 AuthorDate: Sun Dec 20 00:55:14 2015 +0000
4 Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org>
5 CommitDate: Sun Dec 20 00:55:14 2015 +0000
6 URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=13b45f79
7
8 libsandbox: switch to PTRACE_O_TRACEEXEC
9
10 Rather than try to deal with the inconsistent cross-arch behavior when it
11 comes to tracking exec behavior, use the PTRACE_O_TRACEEXEC option. This
12 means we only support ptrace on linux-2.6+ systems, but that's fine as we
13 have been requiring that for a long time now. It also means the code is
14 much simpler and stable across arches.
15
16 Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org>
17
18 libsandbox/trace.c | 68 +++++++++++++++----------------------------
19 libsandbox/trace/linux/arch.c | 8 +++--
20 2 files changed, 29 insertions(+), 47 deletions(-)
21
22 diff --git a/libsandbox/trace.c b/libsandbox/trace.c
23 index f9194fe..d424389 100644
24 --- a/libsandbox/trace.c
25 +++ b/libsandbox/trace.c
26 @@ -430,41 +430,34 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
27 static void trace_loop(void)
28 {
29 trace_regs regs;
30 - bool before_syscall, fake_syscall_ret;
31 + bool before_exec, before_syscall, fake_syscall_ret;
32 long ret;
33 - int nr, exec_state;
34 - const struct syscall_entry *se, *tbl_at_fork, *tbl_after_fork;
35 + int nr, status;
36 + const struct syscall_entry *se, *tbl_after_fork;
37
38 - exec_state = 0;
39 - before_syscall = true;
40 + before_exec = true;
41 + before_syscall = false;
42 fake_syscall_ret = false;
43 - tbl_at_fork = tbl_after_fork = NULL;
44 + tbl_after_fork = NULL;
45 do {
46 ret = do_ptrace(PTRACE_SYSCALL, NULL, NULL);
47 - waitpid(trace_pid, NULL, 0);
48 - ret = trace_get_regs(&regs);
49 - nr = trace_get_sysnum(&regs);
50 + waitpid(trace_pid, &status, 0);
51
52 - if (!exec_state) {
53 - if (!tbl_at_fork)
54 - tbl_at_fork = trace_check_personality(&regs);
55 - se = lookup_syscall_in_tbl(tbl_at_fork, nr);
56 - if (!before_syscall || !se || se->sys != SB_NR_EXECVE) {
57 - if (before_syscall)
58 - _sb_debug(">%s:%i", se ? se->name : "IDK", nr);
59 - else
60 - __sb_debug("(...pre-exec...) = ...\n");
61 - goto loop_again;
62 - }
63 - ++exec_state;
64 - } else if (exec_state == 1) {
65 - /* Don't bother poking exec return */
66 - ++exec_state;
67 - goto loop_again;
68 + if (before_exec) {
69 + unsigned event = ((unsigned)status >> 16);
70 + if (event == PTRACE_EVENT_EXEC) {
71 + _sb_debug("hit exec!");
72 + before_exec = false;
73 + } else
74 + _sb_debug("waiting for exec; status: %#x", status);
75 + ret = trace_get_regs(&regs);
76 + tbl_after_fork = trace_check_personality(&regs);
77 + continue;
78 }
79
80 - if (!tbl_after_fork)
81 - tbl_after_fork = trace_check_personality(&regs);
82 + ret = trace_get_regs(&regs);
83 + nr = trace_get_sysnum(&regs);
84 +
85 se = lookup_syscall_in_tbl(tbl_after_fork, nr);
86 ret = trace_get_regs(&regs);
87 if (before_syscall) {
88 @@ -486,24 +479,11 @@ static void trace_loop(void)
89 ret = trace_result(&regs, &err);
90
91 __sb_debug(" = %li", ret);
92 - if (err) {
93 + if (err)
94 __sb_debug(" (errno: %i: %s)", err, strerror(err));
95 -
96 - /* If the exec() failed for whatever reason, kill the
97 - * child and have the parent resume like normal
98 - */
99 - if (exec_state == 1) {
100 - do_ptrace(PTRACE_KILL, NULL, NULL);
101 - trace_pid = 0;
102 - return;
103 - }
104 - }
105 __sb_debug("\n");
106 -
107 - exec_state = 2;
108 }
109
110 - loop_again:
111 before_syscall = !before_syscall;
112 } while (1);
113 }
114 @@ -527,10 +507,8 @@ void trace_main(const char *filename, char *const argv[])
115 } else if (trace_pid) {
116 sb_debug("parent waiting for child (pid=%i) to signal", trace_pid);
117 waitpid(trace_pid, NULL, 0);
118 -#if defined(PTRACE_SETOPTIONS) && defined(PTRACE_O_TRACESYSGOOD)
119 - /* Not all kernel versions support this, so ignore return */
120 - ptrace(PTRACE_SETOPTIONS, trace_pid, NULL, (void *)PTRACE_O_TRACESYSGOOD);
121 -#endif
122 + do_ptrace(PTRACE_SETOPTIONS, NULL,
123 + (void *)(PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC));
124 sb_close_all_fds();
125 trace_loop();
126 sb_ebort("ISE: child should have quit, as should we\n");
127
128 diff --git a/libsandbox/trace/linux/arch.c b/libsandbox/trace/linux/arch.c
129 index 5ca1acb..957db3b 100644
130 --- a/libsandbox/trace/linux/arch.c
131 +++ b/libsandbox/trace/linux/arch.c
132 @@ -1,7 +1,11 @@
133 #include "common.c"
134
135 -/* Linux uses ptrace() */
136 -#if !defined(HAVE_PTRACE) || !defined(HAVE_SYS_PTRACE_H) || !defined(HAVE_SYS_USER_H)
137 +/* Linux uses ptrace(). We require PTRACE_SETOPTIONS so the exec tracing logic
138 + * is sane. Otherwise we need a lot of arch-specific hacks to make it work.
139 + * This should be fine for linux-2.6+ versions.
140 + */
141 +#if !defined(HAVE_PTRACE) || !defined(HAVE_SYS_PTRACE_H) || \
142 + !defined(HAVE_SYS_USER_H) || !defined(PTRACE_SETOPTIONS)
143 # define SB_NO_TRACE_ARCH
144 #elif defined(__bfin__)
145 # include "bfin.c"