Full Disclosure mailing list archives

Advisory: FUSE: Filesystem in Userspace - Information Disclosure (version mixup update)


From: Sven Tantau <sven () sven-tantau de>
Date: Mon, 06 Jun 2005 09:35:58 +0200


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/


Current thread: