Bug 181795 - (CVE-2006-0555) CVE-2006-0555 NFS client panic using O_DIRECT
CVE-2006-0555 NFS client panic using O_DIRECT
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: kernel (Show other bugs)
4.0
All Linux
medium Severity high
: ---
: ---
Assigned To: Steve Dickson
Brian Brock
reported=20060215,source=vendorsec,im...
: Security
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2006-02-16 11:49 EST by Mark J. Cox (Product Security)
Modified: 2010-03-08 23:00 EST (History)
3 users (show)

See Also:
Fixed In Version: RHSA-2006-0493
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2006-05-24 05:27:57 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
purposed patch (789 bytes, patch)
2006-04-24 09:33 EDT, Steve Dickson
no flags Details | Diff

  None (edit)
Description Mark J. Cox (Product Security) 2006-02-16 11:49:04 EST
Mike O'Connor of SGI reported this flaw where a normal user who has access to
write to a NFS mounted fs can panic an NFS client and therefore cause a local
DoS using O_DIRECT.

Quote:


Any O_DIRECT write to an NFS file where the user buffer starts
with a valid mapped page and contains an unmapped page, will
crash in this way.  I haven't followed the code, but O_DIRECT
reads with similar user buffers will probably also crash albeit
in different ways.

Details:  when nfs_get_user_pages() calls get_user_pages(), it detects
and correctly handles get_user_pages() returning an error, which happens
if the first page covered by the user buffer's address range is unmapped.
However, if the first page is mapped but some subsequent page isn't,
get_user_pages() will return a positive number which is less than the
number of pages requested (this behaviour is sort of analagous to a
short write() call and appears to be intentional).  nfs_get_user_pages()
doesn't detect this and hands off the array of pages (whose last few
elements are random rubbish from the newly allocated array memory) to
it's caller, whence they go to nfs_direct_write_seg(), which then totally
ignores the nr_pages it's given, and calculates its own idea of how many
pages are in the array from the user buffer length.  Needless to say,
when it comes to transmit those uninitialised page* pointers, we see
a crash in the network stack.
Comment 2 Mark J. Cox (Product Security) 2006-02-16 11:50:59 EST
Proposed fix from Mike:

@@ -88,6 +88,15 @@ nfs_get_user_pages(int rw, unsigned long
                                        *pages, NULL);
                up_read(&current->mm->mmap_sem);
        }
+
+       BUG_ON(result > page_count);
+       /*
+        * If we got fewer pages than expected from get_user_pages(),
+        * the user buffer runs off the end of a mapping; return EFAULT.
+        */
+       if (result > 0 && result < page_count)
+               result = -EFAULT;
+
        return result;
 }

Trond followed up with:

Since get_user_pages() hasn't returned an error here, I think you'll
find you also need to ensure that the pages it returned get released
correctly. Also, a result of zero pages could, AFAICS, create the same panic.

Perhaps something like the following instead?

        if (result >= 0 && result < page_count) {
                nfs_free_user_pages(*pages, result, 0);
                *pages = NULL;
                result = -EFAULT;
        }

Comment 3 Mark J. Cox (Product Security) 2006-02-23 04:58:44 EST
embargo set at 20060227:1600
Comment 4 Steve Dickson 2006-04-24 09:33:14 EDT
Created attachment 128145 [details]
purposed patch
Comment 5 Jason Baron 2006-04-25 22:43:01 EDT
committed in stream U4 build 34.24. A test kernel with this patch is available
from http://people.redhat.com/~jbaron/rhel4/
Comment 10 Red Hat Bugzilla 2006-05-24 05:27:57 EDT
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-2006-0493.html

Note You need to log in before you can comment on or make changes to this bug.