aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r--kernel/ptrace.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 45a8a4c5d8b2..dcf9f974198c 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -209,10 +209,28 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
209 return !err; 209 return !err;
210} 210}
211 211
212static int ptrace_attach(struct task_struct *task) 212static int ptrace_attach(struct task_struct *task, long request,
213 unsigned long flags)
213{ 214{
215 bool seize = (request == PTRACE_SEIZE);
214 int retval; 216 int retval;
215 217
218 /*
219 * SEIZE will enable new ptrace behaviors which will be implemented
220 * gradually. SEIZE_DEVEL is used to prevent applications
221 * expecting full SEIZE behaviors trapping on kernel commits which
222 * are still in the process of implementing them.
223 *
224 * Only test programs for new ptrace behaviors being implemented
225 * should set SEIZE_DEVEL. If unset, SEIZE will fail with -EIO.
226 *
227 * Once SEIZE behaviors are completely implemented, this flag and
228 * the following test will be removed.
229 */
230 retval = -EIO;
231 if (seize && !(flags & PTRACE_SEIZE_DEVEL))
232 goto out;
233
216 audit_ptrace(task); 234 audit_ptrace(task);
217 235
218 retval = -EPERM; 236 retval = -EPERM;
@@ -244,11 +262,16 @@ static int ptrace_attach(struct task_struct *task)
244 goto unlock_tasklist; 262 goto unlock_tasklist;
245 263
246 task->ptrace = PT_PTRACED; 264 task->ptrace = PT_PTRACED;
265 if (seize)
266 task->ptrace |= PT_SEIZED;
247 if (task_ns_capable(task, CAP_SYS_PTRACE)) 267 if (task_ns_capable(task, CAP_SYS_PTRACE))
248 task->ptrace |= PT_PTRACE_CAP; 268 task->ptrace |= PT_PTRACE_CAP;
249 269
250 __ptrace_link(task, current); 270 __ptrace_link(task, current);
251 send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); 271
272 /* SEIZE doesn't trap tracee on attach */
273 if (!seize)
274 send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);
252 275
253 spin_lock(&task->sighand->siglock); 276 spin_lock(&task->sighand->siglock);
254 277
@@ -785,8 +808,8 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
785 goto out; 808 goto out;
786 } 809 }
787 810
788 if (request == PTRACE_ATTACH) { 811 if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
789 ret = ptrace_attach(child); 812 ret = ptrace_attach(child, request, data);
790 /* 813 /*
791 * Some architectures need to do book-keeping after 814 * Some architectures need to do book-keeping after
792 * a ptrace attach. 815 * a ptrace attach.
@@ -927,8 +950,8 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
927 goto out; 950 goto out;
928 } 951 }
929 952
930 if (request == PTRACE_ATTACH) { 953 if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
931 ret = ptrace_attach(child); 954 ret = ptrace_attach(child, request, data);
932 /* 955 /*
933 * Some architectures need to do book-keeping after 956 * Some architectures need to do book-keeping after
934 * a ptrace attach. 957 * a ptrace attach.