]>
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 | ||
40 | --- a/gdb/common/linux-ptrace.c | |
41 | +++ b/gdb/common/linux-ptrace.c | |
42 | @@ -26,6 +26,10 @@ | |
43 | #include "linux-ptrace.h" | |
44 | #include "linux-procfs.h" | |
45 | ||
46 | +#ifdef HAVE_SELINUX_SELINUX_H | |
47 | +# include <selinux/selinux.h> | |
48 | +#endif /* HAVE_SELINUX_SELINUX_H */ | |
49 | + | |
50 | /* Print all possible reasons we could fail to attach PID. */ | |
51 | ||
52 | void | |
53 | @@ -41,4 +45,21 @@ linux_ptrace_attach_warnings (pid_t pid) | |
54 | if (linux_proc_pid_is_zombie (pid)) | |
55 | warning (_("process %d is a zombie - the process has already terminated"), | |
56 | (int) pid); | |
57 | + | |
58 | + linux_ptrace_create_warnings (); | |
59 | +} | |
60 | + | |
61 | +/* Print all possible reasons we could fail to create a traced process. */ | |
62 | + | |
63 | +void | |
64 | +linux_ptrace_create_warnings (void) | |
65 | +{ | |
66 | +#ifdef HAVE_LIBSELINUX | |
67 | + /* -1 is returned for errors, 0 if it has no effect, 1 if PTRACE_ATTACH is | |
68 | + forbidden. */ | |
69 | + if (security_get_boolean_active ("deny_ptrace") == 1) | |
70 | + warning (_("the SELinux boolean 'deny_ptrace' is enabled, " | |
71 | + "you can disable this process attach protection by: " | |
72 | + "(gdb) shell sudo setsebool deny_ptrace=0")); | |
73 | +#endif /* HAVE_LIBSELINUX */ | |
74 | } | |
75 | --- a/gdb/common/linux-ptrace.h | |
76 | +++ b/gdb/common/linux-ptrace.h | |
77 | @@ -66,5 +66,6 @@ | |
78 | #endif | |
79 | ||
80 | extern void linux_ptrace_attach_warnings (pid_t pid); | |
81 | +extern void linux_ptrace_create_warnings (void); | |
82 | ||
83 | #endif /* COMMON_LINUX_PTRACE_H */ | |
84 | --- a/gdb/configure.ac | |
85 | +++ b/gdb/configure.ac | |
86 | @@ -1748,6 +1748,10 @@ then | |
87 | [Define if you support the personality syscall.]) | |
88 | fi | |
89 | ||
90 | +dnl Check security_get_boolean_active availability. | |
91 | +AC_CHECK_HEADERS(selinux/selinux.h) | |
92 | +AC_CHECK_LIB(selinux, security_get_boolean_active) | |
93 | + | |
94 | dnl Handle optional features that can be enabled. | |
95 | ||
96 | # Support for --with-sysroot is a copy of GDB_AC_WITH_DIR, | |
97 | --- a/gdb/gdbserver/configure.ac | |
98 | +++ b/gdb/gdbserver/configure.ac | |
99 | @@ -411,6 +411,10 @@ if $want_ipa ; then | |
100 | fi | |
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 | AC_SUBST(GDBSERVER_DEPFILES) | |
108 | AC_SUBST(GDBSERVER_LIBS) | |
109 | AC_SUBST(USE_THREAD_DB) | |
110 | --- a/gdb/gdbserver/linux-low.c | |
111 | +++ b/gdb/gdbserver/linux-low.c | |
112 | @@ -550,6 +550,25 @@ add_lwp (ptid_t ptid) | |
113 | return lwp; | |
114 | } | |
115 | ||
116 | +/* Execute PTRACE_TRACEME with error checking. */ | |
117 | + | |
118 | +static void | |
119 | +linux_traceme (const char *program) | |
120 | +{ | |
121 | + int save_errno; | |
122 | + | |
123 | + errno = 0; | |
124 | + if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) == 0) | |
125 | + return; | |
126 | + | |
127 | + save_errno = errno; | |
128 | + linux_ptrace_create_warnings (); | |
129 | + fprintf (stderr, _("Cannot trace created process %s: %s.\n"), program, | |
130 | + strerror (save_errno)); | |
131 | + fflush (stderr); | |
132 | + _exit (0177); | |
133 | +} | |
134 | + | |
135 | /* Start an inferior process and returns its pid. | |
136 | ALLARGS is a vector of program-name and args. */ | |
137 | ||
138 | @@ -590,7 +609,7 @@ linux_create_inferior (char *program, char **allargs) | |
139 | ||
140 | if (pid == 0) | |
141 | { | |
142 | - ptrace (PTRACE_TRACEME, 0, 0, 0); | |
143 | + linux_traceme (program); | |
144 | ||
145 | #ifndef __ANDROID__ /* Bionic doesn't use SIGRTMIN the way glibc does. */ | |
146 | signal (__SIGRTMIN + 1, SIG_DFL); | |
147 | @@ -4386,7 +4405,7 @@ linux_tracefork_grandchild (void *arg) | |
148 | static int | |
149 | linux_tracefork_child (void *arg) | |
150 | { | |
151 | - ptrace (PTRACE_TRACEME, 0, 0, 0); | |
152 | + linux_traceme ("PTRACE_O_TRACEFORK test"); | |
153 | kill (getpid (), SIGSTOP); | |
154 | ||
155 | #if !(defined(__UCLIBC__) && defined(HAS_NOMMU)) | |
156 | --- a/gdb/inf-ptrace.c | |
157 | +++ b/gdb/inf-ptrace.c | |
158 | @@ -105,7 +105,15 @@ static void | |
159 | inf_ptrace_me (void) | |
160 | { | |
161 | /* "Trace me, Dr. Memory!" */ | |
162 | + errno = 0; | |
163 | ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3)0, 0); | |
164 | + if (errno != 0) | |
165 | + { | |
166 | + fprintf_unfiltered (gdb_stderr, _("Cannot create process: %s\n"), | |
167 | + safe_strerror (errno)); | |
168 | + gdb_flush (gdb_stderr); | |
169 | + _exit (0177); | |
170 | + } | |
171 | } | |
172 | ||
173 | /* Start a new inferior Unix child process. EXEC_FILE is the file to | |
174 | --- a/gdb/linux-nat.c | |
175 | +++ b/gdb/linux-nat.c | |
176 | @@ -1570,6 +1570,7 @@ linux_nat_create_inferior (struct target_ops *ops, | |
177 | #ifdef HAVE_PERSONALITY | |
178 | int personality_orig = 0, personality_set = 0; | |
179 | #endif /* HAVE_PERSONALITY */ | |
180 | + volatile struct gdb_exception ex; | |
181 | ||
182 | /* The fork_child mechanism is synchronous and calls target_wait, so | |
183 | we have to mask the async mode. */ | |
184 | @@ -1594,7 +1595,10 @@ linux_nat_create_inferior (struct target_ops *ops, | |
185 | /* Make sure we report all signals during startup. */ | |
186 | linux_nat_pass_signals (0, NULL); | |
187 | ||
188 | - linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty); | |
189 | + TRY_CATCH (ex, RETURN_MASK_ERROR) | |
190 | + { | |
191 | + linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty); | |
192 | + } | |
193 | ||
194 | #ifdef HAVE_PERSONALITY | |
195 | if (personality_set) | |
196 | @@ -1606,6 +1610,12 @@ linux_nat_create_inferior (struct target_ops *ops, | |
197 | safe_strerror (errno)); | |
198 | } | |
199 | #endif /* HAVE_PERSONALITY */ | |
200 | + | |
201 | + if (ex.reason < 0) | |
202 | + { | |
203 | + linux_ptrace_create_warnings (); | |
204 | + throw_exception (ex); | |
205 | + } | |
206 | } | |
207 | ||
208 | static void | |
209 |