OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
[Full-disclosure] Advisory: FUSE: Filesystem in Userspace - Information Disclosure (version mixup update)

From: Sven Tantau (svensven-tantau.de)
Date: Mon Jun 06 2005 - 02:35:58 CDT


Advisory: FUSE: Filesystem in Userspace - Information Disclosure

Update: Correction of affected versions and os.

Product: FUSE: Filesystem in Userspace
Affected Version: 2.2, 2.2.1, 2.3-pre* and 2.3-rc1
Immune Version: < 2.2, 2.3.0
OS affected: Linux 2.4.*, 2.6.*
Security-Risk: high
Remote-Exploit: no
Date: 03.06.2005
Author: Sven Tantau - http://www.sven-tantau.de/
Vendor-URL: http://sourceforge.net/projects/fuse
Vendor-Status: informed, vendor released a fixed version
Advisory-URL:
http://www.sven-tantau.de/public_files/fuse/fuse_20050603.txt
Exploit-URL: http://www.sven-tantau.de/public_files/fuse/memfs.c

Product
=======

> From fuse/README

FUSE (Filesystem in Userspace) is a simple interface for userspace
programs to export a virtual filesystem to the linux kernel. FUSE
also aims to provide a secure method for non privileged users to
create and mount their own filesystem implementations.

You can download the source code releases from

  http://sourceforge.net/projects/fuse

Details
=======

kernel/file.c:
static int fuse_readpage(struct file *file, struct page *page)
{
        ....

        req->num_pages = 1;
        req->pages[0] = page;
        req->out.page_zeroing = 1;

        ....
}

kernel/dev.c:
static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
                           int zeroing)
{
        unsigned i;
        struct fuse_req *req = cs->req;
        unsigned offset = req->page_offset;
        unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);

        for (i = 0; i < req->num_pages && nbytes; i++) { // <--- nbytes
can be 0
                struct page *page = req->pages[i];
                int err = fuse_copy_page(cs, page, offset, count, zeroing);
                if (err)
                        return err;

                nbytes -= count;
                count = min(nbytes, (unsigned) PAGE_SIZE);
                offset = 0;
        }
        return 0;
}

static inline int fuse_copy_page(struct fuse_copy_state *cs, struct page
*page,
                                 unsigned offset, unsigned count, int zeroing)
{
        if (page && zeroing && count < PAGE_SIZE) {
                void *mapaddr = kmap_atomic(page, KM_USER1);
                memset(mapaddr, 0, PAGE_SIZE);
                kunmap_atomic(mapaddr, KM_USER1);
        }

        ....
}

Pages will not be zeroed if nbytes==0 which leads to
information disclosure of previous page content. As those can contain
sensitive data of other users (including root), risk is rated high.

A proof of concept file system is available at:
http://www.sven-tantau.de/public_files/fuse/memfs.c

Workaround
==========

rmmod fuse
Install the patch or update to fuse-2.3.0.

Patch
=====

Vendor (Miklos Szeredi) provided fix:

Index: linux/fs/fuse/dev.c
===================================================================
--- linux.orig/fs/fuse/dev.c 2005-06-01 12:22:08.000000000 +0200
+++ linux/fs/fuse/dev.c 2005-06-02 11:10:08.000000000 +0200
-525,7 +525,7 static int fuse_copy_pages(struct fuse_c
         unsigned offset = req->page_offset;
         unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);

- for (i = 0; i < req->num_pages && nbytes; i++) {
+ for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
                 struct page *page = req->pages[i];
                 int err = fuse_copy_page(cs, page, offset, count, zeroing);
                 if (err)

History
=======

2005-06-01 issue found by Sven Tantau
2005-06-02 vendor contacted
2005-06-02 quick vendor reaction with confirmation, patch and public
disclosure
2005-06-06 release of this advisory + exploit
2005-06-06 Update of this advisory (affected versions mixup)

--
Sven Tantau
http://www.sven-tantau.de/ *** http://www.beastiebytes.de/
http://twe.sven-tantau.de/ *** http://www.bewiso.de/
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/