Hide Forgot
Description of problem: clone() syscall has special support for TID of created threads. This support includes two features. One (CLONE_CHILD_SETTID) is to set an integer into user memory with the TID value. One (CLONE_CHILD_CLEARTID) is to clear this same integer once the created thread dies. The integer location is a user provided pointer, provided at clone() time. kernel keeps this pointer value into current->clear_child_tid. At execve() time, we should make sure kernel doesnt keep this user provided pointer, as full user memory is replaced by a new one. As glibc fork() actually uses clone() syscall with CLONE_CHILD_SETTID and CLONE_CHILD_CLEARTID set, chances are high that we might corrupt user memory in forked processes. Following sequence could happen: 1) bash (or any program) starts a new process, by a fork() call that glibc maps to a clone( ... CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID...) syscall 2) When new process starts, its current->clear_child_tid is set to a location that has a meaning only in bash (or initial program) context (&THREAD_SELF->tid) 3) This new process does the execve() syscall to start a new program. current->clear_child_tid is left unchanged (a non NULL value) 4) If this new program creates some threads, and initial thread exits, kernel will attempt to clear the integer pointed by current->clear_child_tid from mm_release() : if (tsk->clear_child_tid && !(tsk->flags & PF_SIGNALED) && atomic_read(&mm->mm_users) > 1) { u32 __user * tidptr = tsk->clear_child_tid; tsk->clear_child_tid = NULL; /* * We don't check the error code - if userspace has * not set up a proper pointer then tough luck. */ << here >> put_user(0, tidptr); sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0); } 5) OR : if new program is not multi-threaded, but spied by /proc/pid users (ps command for example), mm_users > 1, and the exiting program could corrupt 4 bytes in a persistent memory area (shm or memory mapped file) If current->clear_child_tid points to a writeable portion of memory of the new program, kernel happily and silently corrupts 4 bytes of memory, with unexpected effects. http://article.gmane.org/gmane.linux.kernel/871942
Created attachment 356253 [details] Proposed patch + execve-must-clear-current-clear_child_tid-v2.patch added to -mm tree
Upstream commit: http://git.kernel.org/linus/9c8a8228d0827e0d91d28527209988f672f97d28
MITRE's CVE-2009-2848 record: ---------------------------- The execve function in unspecified versions of the Linux kernel does not clear the current->clear_child_tid pointer, which allows local users to cause a denial of service (memory corruption) via a clone system call with CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID enabled, which is not properly handled during thread creation and exit. References: ---------- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-2848 http://article.gmane.org/gmane.linux.kernel/871942 http://www.openwall.com/lists/oss-security/2009/08/04/2 http://www.openwall.com/lists/oss-security/2009/08/05/10
kernel-2.6.29.6-217.2.16.fc11 has been submitted as an update for Fedora 11. http://admin.fedoraproject.org/updates/kernel-2.6.29.6-217.2.16.fc11
kernel-2.6.29.6-217.2.16.fc11 has been pushed to the Fedora 11 stable repository. If problems still persist, please make note of it in this bug report.
This issue has been addressed in following products: MRG for RHEL-5 Via RHSA-2009:1239 https://rhn.redhat.com/errata/RHSA-2009-1239.html
This issue has been addressed in following products: Red Hat Enterprise Linux 5 Via RHSA-2009:1243 https://rhn.redhat.com/errata/RHSA-2009-1243.html
This issue has been addressed in following products: Red Hat Enterprise Linux 4 Via RHSA-2009:1438 https://rhn.redhat.com/errata/RHSA-2009-1438.html
This issue has been addressed in following products: Red Hat Enterprise Linux 5.3.Z - Server Only Via RHSA-2009:1466 https://rhn.redhat.com/errata/RHSA-2009-1466.html
This issue has been addressed in following products: Red Hat Enterprise Linux 3 Via RHSA-2009:1550 https://rhn.redhat.com/errata/RHSA-2009-1550.html