From Bugzilla Helper: User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; T312461) Description of problem: When using the PTRACE_SETOPTIONS feature of ptrace and turning on the PTRACE_O_TRACEEXIT flag (none of which are documented anywhere other than the kernel source - which might should be a separate bug :-), I find that the /proc files for the debugged process have changed ownership to root once the process stoped with the SIGTRAP for the exit event. Though the lack of documentation makes it hard to know for sure, I always got the impression that the exit option was intended to let the user see what went wrong before the process completely vanishes. Part of the useful information to poke around in is obtained from the /proc files (maps for instance might be useful to verify if your stack pointer is off in the weeds). If the ownership of the /proc files has changed to root, it is hard to get useful information out of them :-). I have a sample program and test run listing I will attach to this bugzilla. Version-Release number of selected component (if applicable): lernel-2.6.9-5.0.3.EL How reproducible: Always Steps to Reproduce: 1. gcc -o exitbug exitbug.c 2. ./exitbug Actual Results: The first ls -l shows the files owned by the user running the process. The second ls -l shows the files owned by root. Expected Results: I'm still debugging the process and it hasn't (completely) gone away yet - the files should still be owned by the original user. Additional info:
Created attachment 112664 [details] exitbug.c test program source
Created attachment 112665 [details] test run output from exitbug.c
I'm not sure what the 'solution' might be, but here's what is going on... This exitbug.c test has the target ptraced process execute an "int $1" instruction. This causes a do_general_protection() fault. When the exitbug parent process passes on the signal to the target process on the PTRACE_CONT call (the signal is SIGSEGV), the signal code then will call do_coredump(). The do_coredump() code will clear the task->dumpable field in the target tasks's task structure. At this point we're "hosed". On the subsequent "ls" command to read the /pid/n files, the filesystem code will call the /proc "pid_revalidate()" routine: [0]kdb> bt Stack traceback for pid 2273 0xf4f88d80 2273 2271 1 0 R 0xf4f89020 *ls EBP EIP Function (args) 0xf3867e14 0xc019e6ee pid_revalidate+0x7e (0xf48cbb74, 0xf3867f10, 0xc19b8838, ) 0xf3867e34 0xc017b4bc do_lookup+0x75 (0xf3867f10, 0xf3867ea4, 0xf3867e9c, 0xf38) 0xf3867ec0 0xc017be76 link_path_walk+0x993 (0xbfffe538, 0x1000, 0xf3aa0000, 0xf) 0xf3867edc 0xc017c669 path_lookup+0x185 (0xbfffe538, 0x805d217, 0x0, 0xf3867f68) 0xf3867efc 0xc017c80b __user_walk+0x32 (0x0, 0xc06568f0, 0x8db0000, 0xf3fdad6c,) 0xf3867f58 0xc0176cfc vfs_lstat+0x1e (0xbfffe538, 0xf3867f68, 0x296, 0x296, 0xf) 0xf3867fbc 0xc0177405 sys_lstat64+0x1b 0xc01049c8 syscall_call+0x7 pid_revalidate() calls task_dumpable(), and: - if mm is gone, - OR if mm->dumpable == 0, then task_dumpable() returns 0. When task_dumpable() returns 0, the pid_revalidate() routine clears the uid and gid fields of the /proc file. I guess that this code is trying to detect when a task/process is not really 'viewable' anymore. So it's not really where the PT_TRACE_EXIT check is located in the kernel exit code, but rather the fact that this process has already called do_coredump() and made itself 'un-dumpable'. Note that when the ptraced target task exits normally (without having to call do_coredump()), the /proc/nn files remain unchanged at the point in time when we hit the PT_TRACE_EXIT code in do_exit().
I would like to submit a suggestion for a fixing this problem. The diffs are below. Possibly these changes, or something similar to them would provide a suitable fix. The changes are: - Add a new coredumped bit to the mm_struct. - In do_coredump() when the mm->dumpable bit is cleared, set the mm->coredumped bit. This is the only time that the mm->coredumped bit is non-zero. Note that the mm->coredumped bit is set only if the mm->dumpable bit was set at the time that do_coredump() was called. - In the /proc task_dumpable() routine, return non-zero if either mm->coredumped or mm->dumpable is set. The keeps the uid/gid indoe fields of the /proc/[pid] files from getting set to 0 after a do_coredump() has occurred and the process stopped in exit due to the PTRACE_O_TRACEEXIT flag. These changes preserve the validity of the existing places in the code that examine the mm->dumpable bit for security access reasons, such as setuid operations, etc. Thank you for your considerations in this matter. ------------------------------------------------------------------------ ------------------------------------------------------------------------ diff -ru old/fs/exec.c new/fs/exec.c --- old/fs/exec.c 2005-05-25 08:09:11.481469350 -0400 +++ new/fs/exec.c 2005-05-25 08:10:08.643798039 -0400 @@ -1441,6 +1441,7 @@ goto fail; } mm->dumpable = 0; + mm->coredumped = 1; init_completion(&mm->core_done); spin_lock_irq(¤t->sighand->siglock); current->signal->flags = SIGNAL_GROUP_EXIT; diff -ru old/fs/proc/base.c new/fs/proc/base.c --- old/fs/proc/base.c 2005-05-25 08:09:19.687368419 -0400 +++ new/fs/proc/base.c 2005-05-25 08:10:40.445531072 -0400 @@ -1029,7 +1029,7 @@ task_lock(task); mm = task->mm; if (mm) - dumpable = mm->dumpable; + dumpable = mm->dumpable | mm->coredumped; task_unlock(task); return dumpable; } diff -ru old/include/linux/sched.h new/include/linux/sched.h --- old/include/linux/sched.h 2005-05-25 08:09:01.564801555 -0400 +++ new/include/linux/sched.h 2005-05-25 08:11:23.955606630 -0400 @@ -235,6 +235,7 @@ unsigned long saved_auxv[42]; /* for /proc/PID/auxv */ unsigned dumpable:1; + unsigned coredumped:1; cpumask_t cpu_vm_mask; /* Architecture-specific MM context */
Thank you for submitting this issue for consideration in Red Hat Enterprise Linux. The release for which you requested us to review is now End of Life. Please See https://access.redhat.com/support/policy/updates/errata/ If you would like Red Hat to re-consider your feature request for an active release, please re-open the request via appropriate support channels and provide additional supporting details about the importance of this issue.