Bug 153303
Summary: | /proc files change ownership too soon with PTRACE_O_TRACEEXIT | ||||||||
---|---|---|---|---|---|---|---|---|---|
Product: | Red Hat Enterprise Linux 4 | Reporter: | Tom Horsley <horsley1953> | ||||||
Component: | kernel | Assignee: | Alexander Viro <aviro> | ||||||
Status: | CLOSED WONTFIX | QA Contact: | Brian Brock <bbrock> | ||||||
Severity: | medium | Docs Contact: | |||||||
Priority: | medium | ||||||||
Version: | 4.0 | CC: | bugsy, davej, jbaron, riel | ||||||
Target Milestone: | --- | ||||||||
Target Release: | --- | ||||||||
Hardware: | i386 | ||||||||
OS: | Linux | ||||||||
Whiteboard: | |||||||||
Fixed In Version: | Doc Type: | Bug Fix | |||||||
Doc Text: | Story Points: | --- | |||||||
Clone Of: | Environment: | ||||||||
Last Closed: | 2012-06-20 16:13:57 UTC | Type: | --- | ||||||
Regression: | --- | Mount Type: | --- | ||||||
Documentation: | --- | CRM: | |||||||
Verified Versions: | Category: | --- | |||||||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||
Cloudforms Team: | --- | Target Upstream Version: | |||||||
Embargoed: | |||||||||
Attachments: |
|
Description
Tom Horsley
2005-04-04 16:53:57 UTC
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. |