- Change ptrace_getsiginfo() to use ptrace_rw_siginfo().

- Fix the semantics. We should return EINVAL only if the tracee
  was stopped. If it didn't report the signal, we fill siginfo
  like ptrace_notify() did.

Note! Currently do_ptrace_notify_stop() clears context->ev_code for
debugging purposes, this means info->si_code is not right currently.

---

 kernel/ptrace.c |   33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

--- PU/kernel/ptrace.c~63_GET_SIGINFO   2009-10-03 02:49:42.000000000 +0200
+++ PU/kernel/ptrace.c  2009-10-03 03:19:47.000000000 +0200
@@ -801,22 +801,23 @@ static int ptrace_rw_siginfo(struct task
        return err;
 }
 
-static int ptrace_getsiginfo(struct utrace_engine *engine,
-                               struct task_struct *child, siginfo_t *info)
+static int ptrace_getsiginfo(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)) {
-                       *info = *ptrace_context(engine)->siginfo;
-                       error = 0;
-               }
-               unlock_task_sighand(child, &flags);
-       }
+       if (context->siginfo)
+               return ptrace_rw_siginfo(tracee, context, info, false);
 
-       return error;
+       memset(info, 0, sizeof(*info));
+       info->si_signo = SIGTRAP;
+       info->si_code = context->ev_code; // XXX: ev_code was already cleared!!!
+       info->si_pid = task_pid_vnr(tracee);
+       info->si_uid = task_uid(tracee);
+
+       return 0;
 }
 
 static int ptrace_setsiginfo(struct utrace_engine *engine,
@@ -1045,7 +1046,8 @@ int ptrace_request(struct task_struct *c
                break;
 
        case PTRACE_GETSIGINFO:
-               ret = ptrace_getsiginfo(engine, child, &siginfo);
+               ret = ptrace_getsiginfo(ptrace_context(engine),
+                                       child, &siginfo);
                if (!ret)
                        ret = copy_siginfo_to_user((siginfo_t __user *) data,
                                                   &siginfo);
@@ -1214,7 +1216,8 @@ int compat_ptrace_request(struct task_st
                break;
 
        case PTRACE_GETSIGINFO:
-               ret = ptrace_getsiginfo(engine, child, &siginfo);
+               ret = ptrace_getsiginfo(ptrace_context(engine),
+                                       child, &siginfo);
                if (!ret)
                        ret = copy_siginfo_to_user32(
                                (struct compat_siginfo __user *) datap,

Reply via email to