]>
Commit | Line | Data |
---|---|---|
f412e1b4 PS |
1 | http://sourceware.org/ml/gdb-patches/2012-03/msg00171.html |
2 | Subject: [patch 3/3] attach-fail-reasons: SELinux deny_ptrace | |
3 | ||
4 | Hi, | |
5 | ||
6 | and here is the last bit for new SELinux 'deny_ptrace': | |
7 | https://bugzilla.redhat.com/show_bug.cgi?id=786878 | |
8 | ||
9 | As even PTRACE_TRACEME fails in such case it needs to install hook for even | |
10 | that event. | |
11 | ||
12 | ||
13 | Thanks, | |
14 | Jan | |
15 | ||
16 | ||
17 | gdb/ | |
18 | 2012-03-06 Jan Kratochvil <jan.kratochvil@redhat.com> | |
19 | ||
20 | * common/linux-ptrace.c [HAVE_SELINUX_SELINUX_H]: include | |
21 | selinux/selinux.h. | |
22 | (linux_ptrace_attach_warnings): Call linux_ptrace_create_warnings. | |
23 | (linux_ptrace_create_warnings): New. | |
24 | * common/linux-ptrace.h (linux_ptrace_create_warnings): New declaration. | |
25 | * config.in: Regenerate. | |
26 | * configure: Regenerate. | |
27 | * configure.ac: Check selinux/selinux.h and the selinux library. | |
28 | * inf-ptrace.c (inf_ptrace_me): Check the ptrace result. | |
29 | * linux-nat.c (linux_nat_create_inferior): New variable ex. Wrap | |
30 | to_create_inferior into TRY_CATCH, call linux_ptrace_create_warnings. | |
31 | ||
32 | gdb/gdbserver/ | |
33 | * config.in: Regenerate. | |
34 | * configure: Regenerate. | |
35 | * configure.ac: Check selinux/selinux.h and the selinux library. | |
36 | * linux-low.c (linux_traceme): New function. | |
37 | (linux_create_inferior, linux_tracefork_child): Call it instead of | |
38 | direct ptrace. | |
39 | ||
a7de96f0 PS |
40 | Index: gdb-7.5.0.20120926/gdb/common/linux-ptrace.c |
41 | =================================================================== | |
42 | --- gdb-7.5.0.20120926.orig/gdb/common/linux-ptrace.c 2012-09-17 20:28:14.000000000 +0200 | |
43 | +++ gdb-7.5.0.20120926/gdb/common/linux-ptrace.c 2012-09-26 19:13:53.508780239 +0200 | |
44 | @@ -28,6 +28,10 @@ | |
45 | #include "buffer.h" | |
46 | #include "gdb_assert.h" | |
f412e1b4 PS |
47 | |
48 | +#ifdef HAVE_SELINUX_SELINUX_H | |
49 | +# include <selinux/selinux.h> | |
50 | +#endif /* HAVE_SELINUX_SELINUX_H */ | |
51 | + | |
a7de96f0 PS |
52 | /* Find all possible reasons we could fail to attach PID and append these |
53 | newline terminated reason strings to initialized BUFFER. '\0' termination | |
54 | of BUFFER must be done by the caller. */ | |
55 | @@ -47,6 +51,8 @@ linux_ptrace_attach_warnings (pid_t pid, | |
56 | buffer_xml_printf (buffer, _("warning: process %d is a zombie " | |
57 | "- the process has already terminated\n"), | |
58 | (int) pid); | |
f412e1b4 | 59 | + |
a7de96f0 PS |
60 | + linux_ptrace_create_warnings (buffer); |
61 | } | |
62 | ||
63 | #if defined __i386__ || defined __x86_64__ | |
64 | @@ -242,3 +248,19 @@ linux_ptrace_init_warnings (void) | |
65 | ||
66 | linux_ptrace_test_ret_to_nx (); | |
67 | } | |
f412e1b4 PS |
68 | + |
69 | +/* Print all possible reasons we could fail to create a traced process. */ | |
70 | + | |
71 | +void | |
a7de96f0 | 72 | +linux_ptrace_create_warnings (struct buffer *buffer) |
f412e1b4 PS |
73 | +{ |
74 | +#ifdef HAVE_LIBSELINUX | |
75 | + /* -1 is returned for errors, 0 if it has no effect, 1 if PTRACE_ATTACH is | |
76 | + forbidden. */ | |
77 | + if (security_get_boolean_active ("deny_ptrace") == 1) | |
a7de96f0 PS |
78 | + buffer_xml_printf (buffer, |
79 | + _("the SELinux boolean 'deny_ptrace' is enabled, " | |
80 | + "you can disable this process attach protection by: " | |
81 | + "(gdb) shell sudo setsebool deny_ptrace=0")); | |
f412e1b4 | 82 | +#endif /* HAVE_LIBSELINUX */ |
a7de96f0 PS |
83 | +} |
84 | Index: gdb-7.5.0.20120926/gdb/common/linux-ptrace.h | |
85 | =================================================================== | |
86 | --- gdb-7.5.0.20120926.orig/gdb/common/linux-ptrace.h 2012-07-07 14:13:56.000000000 +0200 | |
87 | +++ gdb-7.5.0.20120926/gdb/common/linux-ptrace.h 2012-09-26 19:13:28.358765406 +0200 | |
88 | @@ -69,5 +69,6 @@ struct buffer; | |
f412e1b4 | 89 | |
a7de96f0 PS |
90 | extern void linux_ptrace_attach_warnings (pid_t pid, struct buffer *buffer); |
91 | extern void linux_ptrace_init_warnings (void); | |
92 | +extern void linux_ptrace_create_warnings (struct buffer *buffer); | |
f412e1b4 PS |
93 | |
94 | #endif /* COMMON_LINUX_PTRACE_H */ | |
a7de96f0 PS |
95 | Index: gdb-7.5.0.20120926/gdb/configure.ac |
96 | =================================================================== | |
97 | --- gdb-7.5.0.20120926.orig/gdb/configure.ac 2012-09-26 19:13:24.000000000 +0200 | |
98 | +++ gdb-7.5.0.20120926/gdb/configure.ac 2012-09-26 19:13:28.410765451 +0200 | |
99 | @@ -2008,6 +2008,10 @@ then | |
f412e1b4 PS |
100 | [Define if you support the personality syscall.]) |
101 | fi | |
102 | ||
103 | +dnl Check security_get_boolean_active availability. | |
104 | +AC_CHECK_HEADERS(selinux/selinux.h) | |
105 | +AC_CHECK_LIB(selinux, security_get_boolean_active) | |
106 | + | |
107 | dnl Handle optional features that can be enabled. | |
108 | ||
109 | # Support for --with-sysroot is a copy of GDB_AC_WITH_DIR, | |
a7de96f0 PS |
110 | Index: gdb-7.5.0.20120926/gdb/gdbserver/configure.ac |
111 | =================================================================== | |
112 | --- gdb-7.5.0.20120926.orig/gdb/gdbserver/configure.ac 2012-04-19 21:34:51.000000000 +0200 | |
113 | +++ gdb-7.5.0.20120926/gdb/gdbserver/configure.ac 2012-09-26 19:13:28.446765428 +0200 | |
114 | @@ -438,6 +438,10 @@ if $want_ipa ; then | |
f412e1b4 PS |
115 | fi |
116 | fi | |
117 | ||
118 | +dnl Check security_get_boolean_active availability. | |
119 | +AC_CHECK_HEADERS(selinux/selinux.h) | |
120 | +AC_CHECK_LIB(selinux, security_get_boolean_active) | |
121 | + | |
122 | AC_SUBST(GDBSERVER_DEPFILES) | |
123 | AC_SUBST(GDBSERVER_LIBS) | |
124 | AC_SUBST(USE_THREAD_DB) | |
a7de96f0 PS |
125 | Index: gdb-7.5.0.20120926/gdb/gdbserver/linux-low.c |
126 | =================================================================== | |
127 | --- gdb-7.5.0.20120926.orig/gdb/gdbserver/linux-low.c 2012-07-07 14:13:57.000000000 +0200 | |
128 | +++ gdb-7.5.0.20120926/gdb/gdbserver/linux-low.c 2012-09-26 19:13:28.453765471 +0200 | |
129 | @@ -601,6 +601,28 @@ add_lwp (ptid_t ptid) | |
f412e1b4 PS |
130 | return lwp; |
131 | } | |
132 | ||
133 | +/* Execute PTRACE_TRACEME with error checking. */ | |
134 | + | |
135 | +static void | |
136 | +linux_traceme (const char *program) | |
137 | +{ | |
138 | + int save_errno; | |
a7de96f0 | 139 | + struct buffer buffer; |
f412e1b4 PS |
140 | + |
141 | + errno = 0; | |
142 | + if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) == 0) | |
143 | + return; | |
144 | + | |
145 | + save_errno = errno; | |
a7de96f0 PS |
146 | + buffer_init (&buffer); |
147 | + linux_ptrace_create_warnings (&buffer); | |
148 | + buffer_grow_str0 (&buffer, ""); | |
149 | + fprintf (stderr, _("%sCannot trace created process %s: %s.\n"), | |
150 | + buffer_finish (&buffer), program, strerror (save_errno)); | |
f412e1b4 PS |
151 | + fflush (stderr); |
152 | + _exit (0177); | |
153 | +} | |
154 | + | |
155 | /* Start an inferior process and returns its pid. | |
156 | ALLARGS is a vector of program-name and args. */ | |
157 | ||
a7de96f0 | 158 | @@ -641,7 +663,7 @@ linux_create_inferior (char *program, ch |
f412e1b4 PS |
159 | |
160 | if (pid == 0) | |
161 | { | |
162 | - ptrace (PTRACE_TRACEME, 0, 0, 0); | |
163 | + linux_traceme (program); | |
164 | ||
165 | #ifndef __ANDROID__ /* Bionic doesn't use SIGRTMIN the way glibc does. */ | |
166 | signal (__SIGRTMIN + 1, SIG_DFL); | |
a7de96f0 | 167 | @@ -4572,7 +4594,7 @@ linux_tracefork_grandchild (void *arg) |
f412e1b4 PS |
168 | static int |
169 | linux_tracefork_child (void *arg) | |
170 | { | |
171 | - ptrace (PTRACE_TRACEME, 0, 0, 0); | |
172 | + linux_traceme ("PTRACE_O_TRACEFORK test"); | |
173 | kill (getpid (), SIGSTOP); | |
174 | ||
175 | #if !(defined(__UCLIBC__) && defined(HAS_NOMMU)) | |
a7de96f0 PS |
176 | Index: gdb-7.5.0.20120926/gdb/inf-ptrace.c |
177 | =================================================================== | |
178 | --- gdb-7.5.0.20120926.orig/gdb/inf-ptrace.c 2012-05-24 18:51:34.000000000 +0200 | |
179 | +++ gdb-7.5.0.20120926/gdb/inf-ptrace.c 2012-09-26 19:13:28.458765461 +0200 | |
f412e1b4 PS |
180 | @@ -105,7 +105,15 @@ static void |
181 | inf_ptrace_me (void) | |
182 | { | |
183 | /* "Trace me, Dr. Memory!" */ | |
184 | + errno = 0; | |
185 | ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3)0, 0); | |
186 | + if (errno != 0) | |
187 | + { | |
188 | + fprintf_unfiltered (gdb_stderr, _("Cannot create process: %s\n"), | |
189 | + safe_strerror (errno)); | |
190 | + gdb_flush (gdb_stderr); | |
191 | + _exit (0177); | |
192 | + } | |
193 | } | |
194 | ||
195 | /* Start a new inferior Unix child process. EXEC_FILE is the file to | |
a7de96f0 PS |
196 | Index: gdb-7.5.0.20120926/gdb/linux-nat.c |
197 | =================================================================== | |
198 | --- gdb-7.5.0.20120926.orig/gdb/linux-nat.c 2012-09-26 19:13:22.000000000 +0200 | |
199 | +++ gdb-7.5.0.20120926/gdb/linux-nat.c 2012-09-26 19:13:28.468765469 +0200 | |
200 | @@ -1574,6 +1574,7 @@ linux_nat_create_inferior (struct target | |
f412e1b4 PS |
201 | #ifdef HAVE_PERSONALITY |
202 | int personality_orig = 0, personality_set = 0; | |
203 | #endif /* HAVE_PERSONALITY */ | |
204 | + volatile struct gdb_exception ex; | |
205 | ||
206 | /* The fork_child mechanism is synchronous and calls target_wait, so | |
207 | we have to mask the async mode. */ | |
a7de96f0 | 208 | @@ -1598,7 +1599,10 @@ linux_nat_create_inferior (struct target |
f412e1b4 PS |
209 | /* Make sure we report all signals during startup. */ |
210 | linux_nat_pass_signals (0, NULL); | |
211 | ||
212 | - linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty); | |
213 | + TRY_CATCH (ex, RETURN_MASK_ERROR) | |
214 | + { | |
215 | + linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty); | |
216 | + } | |
217 | ||
218 | #ifdef HAVE_PERSONALITY | |
219 | if (personality_set) | |
a7de96f0 | 220 | @@ -1610,6 +1614,24 @@ linux_nat_create_inferior (struct target |
f412e1b4 PS |
221 | safe_strerror (errno)); |
222 | } | |
223 | #endif /* HAVE_PERSONALITY */ | |
224 | + | |
225 | + if (ex.reason < 0) | |
226 | + { | |
a7de96f0 PS |
227 | + struct buffer buffer; |
228 | + char *message, *buffer_s; | |
229 | + | |
230 | + message = xstrdup (ex.message); | |
231 | + make_cleanup (xfree, message); | |
232 | + | |
233 | + buffer_init (&buffer); | |
234 | + linux_ptrace_create_warnings (&buffer); | |
235 | + | |
236 | + buffer_grow_str0 (&buffer, ""); | |
237 | + buffer_s = buffer_finish (&buffer); | |
238 | + make_cleanup (xfree, buffer_s); | |
239 | + | |
240 | + throw_error (ex.error, "%s%s", buffer_s, message); | |
f412e1b4 PS |
241 | + } |
242 | } | |
243 | ||
244 | static void |