Like the previous patch, but if the tracee didn't report a signal we do nothing but return success.
Currently ptrace_notify() always sets ->last_siginfo != NULL which can be update via PTRACE_SETSIGINFO, but this info will be never used. We pretend siginfo was updated for compatibility but the stupid app can read it back, in this case we will have bug-reports. --- kernel/ptrace.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) --- PU/kernel/ptrace.c~64_PUT_SIGINFO 2009-10-03 03:19:47.000000000 +0200 +++ PU/kernel/ptrace.c 2009-10-03 03:44:56.000000000 +0200 @@ -820,22 +820,18 @@ static int ptrace_getsiginfo(struct ptra return 0; } -static int ptrace_setsiginfo(struct utrace_engine *engine, - struct task_struct *child, const siginfo_t *info) +static int ptrace_setsiginfo(struct ptrace_context *context, + struct task_struct *tracee, siginfo_t *info) { - unsigned long flags; - int error = -ESRCH; + /* jctl stop ? */ + if (!ev_pending(context)) + return -EINVAL; - if (lock_task_sighand(child, &flags)) { - error = -EINVAL; - if (likely(ptrace_context(engine)->siginfo != NULL)) { - *ptrace_context(engine)->siginfo = *info; - error = 0; - } - unlock_task_sighand(child, &flags); - } + if (context->siginfo) + return ptrace_rw_siginfo(tracee, context, info, true); - return error; + /* compatibility: pretend it was updated */ + return 0; } @@ -1058,7 +1054,8 @@ int ptrace_request(struct task_struct *c sizeof siginfo)) ret = -EFAULT; else - ret = ptrace_setsiginfo(engine, child, &siginfo); + ret = ptrace_setsiginfo(ptrace_context(engine), + child, &siginfo); break; case PTRACE_DETACH: /* detach a process that was attached. */ @@ -1230,7 +1227,8 @@ int compat_ptrace_request(struct task_st &siginfo, (struct compat_siginfo __user *) datap)) ret = -EFAULT; else - ret = ptrace_setsiginfo(engine, child, &siginfo); + ret = ptrace_setsiginfo(ptrace_context(engine), + child, &siginfo); break; default: