Changeset 1641 for zzuf


Ignore:
Timestamp:
Jan 10, 2007, 6:17:26 PM (13 years ago)
Author:
Sam Hocevar
Message:
  • Implemented memory limits. Probably breaks on other arches because of all the new functions.
Location:
zzuf/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • zzuf/trunk/doc/zzuf.1

    r1640 r1641  
    33zzuf \- multiple purpose fuzzer
    44.SH SYNOPSIS
    5 \fBzzuf\fR [\fB\-cdiMnqS\fR] [\fB\-r\fR \fIratio\fR] [\fB\-s\fR \fIseed\fR | \fB\-s\fR \fIstart:stop\fR]
     5\fBzzuf\fR [\fB\-cdiMnqS\fR] [\fB\-r\fR \fIratio\fR] [\fB\-s\fR \fIseed\fR|\fB\-s\fR \fIstart:stop\fR]
    66.br
    77                [\fB\-F\fR \fIforks\fR] [\fB\-C\fR \fIcrashes\fR] [\fB\-B\fR \fIbytes\fR] [\fB\-T\fR \fIseconds\fR]
    88.br
    9                 [\fB\-P\fR \fIprotect\fR] [\fB\-R\fR \fIrefuse\fR]
     9                [\fB\-M\fR \fImegabytes\fR] [\fB\-P\fR \fIprotect\fR] [\fB\-R\fR \fIrefuse\fR]
    1010.br
    1111                [\fB\-I\fR \fIinclude\fR] [\fB\-E\fR \fIexclude\fR] [\fIPROGRAM\fR [\fIARGS\fR]...]
     
    9999Instead of displaying the program's standard output, just print the MD5 digest
    100100of that output. The standard error channel is left untouched.
     101.TP
     102\fB\-M\fR, \fB\-\-max-memory\fR=\fImegabytes\fR
     103Specify the maximum amount of memory, in megabytes, that children are allowed
     104to allocate. This is useful to detect infinite loops that eat up a lot of
     105memory. The value should set reasonably high so as not to interfer with normal
     106program operation.
     107
     108\fBZzuf\fR uses the \fBsetrlimit\fR() call to set memory usage limitations and
     109relies on the operating system's ability to enforce such limitations.
    101110.TP
    102111\fB\-n\fR, \fB\-\-network\fR
     
    228237.PP
    229238\fB    zzuf \-c \-s 87423 \-r 0.01 vlc movie.avi\fR
    230 \fB    zzuf \-c \-s 87423 \-r 0.01 cp movie.avi fuzzy\-movie.avi\fR
     239\fB    zzuf \-c \-s 87423 \-r 0.01 <movie.avi >fuzzy\-movie.avi\fR
    231240\fB    vlc fuzzy\-movie.avi\fR
    232241.PP
     
    241250.SH RESTRICTIONS
    242251.PP
    243 Due to \fBzzuf\fR using shared object preloading (\fBLD_PRELOAD\fR on most
    244 Unix systems, \fBDYLD_INSERT_LIBRARIES\fR on Mac OS X) to run its child
     252Due to \fBzzuf\fR using shared object preloading (\fBLD_PRELOAD\fR,
     253\fB_RLD_LIST\fB, \fBDYLD_INSERT_LIBRARIES\fR, etc.) to run its child
    245254processes, it will fail in the presence of any mechanism that disables
    246255preloading. For instance setuid root binaries will not be fuzzed when run
     
    267276descriptor operations is undefined.
    268277.SH NOTES
    269 In order to intercept file and network operations and signal handlers,
    270 \fBzzuf\fR diverts and reimplements the following functions, which can
    271 be private libc symbols, too:
     278In order to intercept file and network operations, signal handlers and memory
     279allocations, \fBzzuf\fR diverts and reimplements the following functions,
     280which can be private libc symbols, too:
    272281.TP
    273282Unix file descriptor handling:
    274283\fBopen\fR(), \fBlseek\fR(), \fBread\fR(), \fBaccept\fR(), \fBsocket\fR(),
    275 \fBmmap\fR(), \fBmunmap\fR(), \fBclose\fR()
     284\fBclose\fR()
    276285.TP
    277286Standard IO streams:
     
    279288\fBfread\fR(), \fBgetc\fR(), \fBfgetc\fR(), \fBfgets\fR(), \fBungetc\fR(),
    280289\fBfclose\fR()
     290.TP
     291Memory management:
     292\fBmmap\fR(), \fBmunmap\fR(), \fBmalloc\fR(), \fBcalloc\fR(), \fBvalloc\fR(),
     293\fBfree\fR(), \fBmemalign\fR(), \fBposix_memalign\fR(), \fBbrk\fR(),
     294\fBsbrk\fR()
    281295.TP
    282296Linux-specific:
  • zzuf/trunk/src/libzzuf.c

    r1639 r1641  
    4545int   _zz_hasdebug = 0;
    4646int   _zz_signal   = 0;
     47int   _zz_memory   = 0;
    4748int   _zz_network  = 0;
    4849
     
    8485        _zz_signal = 1;
    8586
     87    tmp = getenv("ZZUF_MEMORY");
     88    if(tmp && *tmp == '1')
     89        _zz_memory = 1;
     90
    8691    tmp = getenv("ZZUF_NETWORK");
    8792    if(tmp && *tmp == '1')
  • zzuf/trunk/src/libzzuf.h

    r1614 r1641  
    4040extern int   _zz_hasdebug;
    4141extern int   _zz_signal;
     42extern int   _zz_memory;
    4243extern int   _zz_network;
    4344
  • zzuf/trunk/src/load-mem.c

    r1639 r1641  
    2323/* Use this to get mmap64() on glibc systems */
    2424#define _LARGEFILE64_SOURCE
     25/* Use this to get posix_memalign */
     26#define _XOPEN_SOURCE 600
    2527
    2628#if defined HAVE_STDINT_H
     
    3234#include <string.h>
    3335#include <dlfcn.h>
    34 
     36#include <errno.h>
     37#include <signal.h>
     38
     39#include <malloc.h>
    3540#include <unistd.h>
    3641#include <sys/mman.h>
     
    4651
    4752/* Library functions that we divert */
    48 static void *  (*mmap_orig)    (void *start, size_t length, int prot,
    49                                 int flags, int fd, off_t offset);
     53static void *  (*calloc_orig)   (size_t nmemb, size_t size);
     54static void *  (*malloc_orig)   (size_t size);
     55static void    (*free_orig)     (void *ptr);
     56static void *  (*valloc_orig)   (size_t size);
     57static void *  (*memalign_orig) (size_t boundary, size_t size);
     58static int     (*posix_memalign_orig) (void **memptr, size_t alignment,
     59                                       size_t size);
     60static void *  (*realloc_orig)  (void *ptr, size_t size);
     61static int     (*brk_orig)      (void *end_data_segment);
     62static void *  (*sbrk_orig)     (intptr_t increment);
     63
     64static void *  (*mmap_orig)     (void *start, size_t length, int prot,
     65                                 int flags, int fd, off_t offset);
     66/* TODO */
     67/* static void *  (*mremap_orig)   (void *old_address, size_t old_size,
     68                                 size_t new_size, int flags); */
    5069#ifdef HAVE_MMAP64
    51 static void *  (*mmap64_orig)  (void *start, size_t length, int prot,
    52                                 int flags, int fd, off64_t offset);
    53 #endif
    54 static int     (*munmap_orig)  (void *start, size_t length);
     70static void *  (*mmap64_orig)   (void *start, size_t length, int prot,
     71                                 int flags, int fd, off64_t offset);
     72#endif
     73static int     (*munmap_orig)   (void *start, size_t length);
    5574#ifdef HAVE_MAP_FD
    5675static kern_return_t (*map_fd_orig) (int fd, vm_offset_t offset,
     
    6180void _zz_load_mem(void)
    6281{
     82    LOADSYM(calloc);
     83    LOADSYM(malloc);
     84    LOADSYM(free);
     85    LOADSYM(realloc);
     86    LOADSYM(valloc);
     87    LOADSYM(memalign);
     88    LOADSYM(posix_memalign);
     89    LOADSYM(brk);
     90    LOADSYM(sbrk);
     91
    6392    LOADSYM(mmap);
    6493#ifdef HAVE_MMAP64
     
    6998    LOADSYM(map_fd);
    7099#endif
     100}
     101
     102/* 32k of ugly static memory for programs that call us *before* we’re
     103 * initialised */
     104uint64_t dummy_buffer[4096];
     105
     106void *calloc(size_t nmemb, size_t size)
     107{
     108    void *ret;
     109    if(!_zz_ready)
     110    {
     111        /* Calloc says we must zero the data */
     112        int i = (nmemb * size + 7) / 8;
     113        while(i--)
     114            dummy_buffer[i] = 0;
     115        return dummy_buffer;
     116    }
     117    ret = calloc_orig(nmemb, size);
     118    if(ret == NULL && _zz_memory && errno == ENOMEM)
     119        raise(SIGKILL);
     120    return ret;
     121}
     122
     123void *malloc(size_t size)
     124{
     125    void *ret;
     126    if(!_zz_ready)
     127        return dummy_buffer;
     128    ret = malloc_orig(size);
     129    if(ret == NULL && _zz_memory && errno == ENOMEM)
     130        raise(SIGKILL);
     131    return ret;
     132}
     133
     134void free(void *ptr)
     135{
     136    if(ptr == dummy_buffer)
     137        return;
     138    if(!_zz_ready)
     139        LOADSYM(free);
     140    free_orig(ptr);
     141}
     142
     143void *realloc(void *ptr, size_t size)
     144{
     145    void *ret;
     146    if(ptr == dummy_buffer)
     147        return ptr;
     148    if(!_zz_ready)
     149        LOADSYM(realloc);
     150    ret = realloc_orig(ptr, size);
     151    if(ret == NULL && _zz_memory && errno == ENOMEM)
     152        raise(SIGKILL);
     153    return ret;
     154}
     155
     156void *valloc(size_t size)
     157{
     158    void *ret;
     159    if(!_zz_ready)
     160        LOADSYM(valloc);
     161    ret = valloc_orig(size);
     162    if(ret == NULL && _zz_memory && errno == ENOMEM)
     163        raise(SIGKILL);
     164    return ret;
     165}
     166
     167void *memalign(size_t boundary, size_t size)
     168{
     169    void *ret;
     170    if(!_zz_ready)
     171        LOADSYM(memalign);
     172    ret = memalign_orig(boundary, size);
     173    if(ret == NULL && _zz_memory && errno == ENOMEM)
     174        raise(SIGKILL);
     175    return ret;
     176}
     177
     178int posix_memalign(void **memptr, size_t alignment, size_t size)
     179{
     180    int ret;
     181    if(!_zz_ready)
     182        LOADSYM(posix_memalign);
     183    ret = posix_memalign_orig(memptr, alignment, size);
     184    if(ret == ENOMEM && _zz_memory)
     185        raise(SIGKILL);
     186    return ret;
     187}
     188
     189int brk(void *end_data_segment)
     190{
     191    int ret;
     192    if(!_zz_ready)
     193        LOADSYM(brk);
     194    ret = brk_orig(end_data_segment);
     195    if(ret == -1 && _zz_memory && errno == ENOMEM)
     196        raise(SIGKILL);
     197    return ret;
     198}
     199
     200void *sbrk(intptr_t increment)
     201{
     202    void *ret;
     203    if(!_zz_ready)
     204        LOADSYM(sbrk);
     205    ret = sbrk_orig(increment);
     206    if(ret == (void *)-1 && _zz_memory && errno == ENOMEM)
     207        raise(SIGKILL);
     208    return ret;
    71209}
    72210
  • zzuf/trunk/src/zzuf.c

    r1640 r1641  
    3737#include <time.h>
    3838#include <sys/wait.h>
     39#include <sys/time.h>
     40#include <sys/resource.h>
    3941
    4042#include "libzzuf.h"
     
    8183static int md5 = 0;
    8284static int checkexit = 0;
     85static int maxmem = -1;
    8386static double maxtime = -1.0;
    8487
     
    120123            { "include",     1, NULL, 'I' },
    121124            { "md5",         0, NULL, 'm' },
     125            { "max-memory",  1, NULL, 'M' },
    122126            { "network",     0, NULL, 'n' },
    123127            { "protect",     1, NULL, 'P' },
     
    132136            { "version",     0, NULL, 'v' },
    133137        };
    134         int c = getopt_long(argc, argv, "B:cC:dE:F:iI:mnP:qr:R:s:ST:xhv",
     138        int c = getopt_long(argc, argv, "B:cC:dE:F:iI:mM:nP:qr:R:s:ST:xhv",
    135139                            long_options, &option_index);
    136140#   else
    137141#       define MOREINFO "Try `%s -h' for more information.\n"
    138         int c = getopt(argc, argv, "B:cC:dE:F:iI:mnP:qr:R:s:ST:xhv");
     142        int c = getopt(argc, argv, "B:cC:dE:F:iI:mM:nP:qr:R:s:ST:xhv");
    139143#   endif
    140144        if(c == -1)
     
    181185        case 'm': /* --md5 */
    182186            md5 = 1;
     187            break;
     188        case 'M': /* --max-memory */
     189            setenv("ZZUF_MEMORY", "1", 1);
     190            maxmem = atoi(optarg);
    183191            break;
    184192        case 'n': /* --network */
     
    425433        case 0:
    426434            /* We’re the child */
     435            if(maxmem >= 0)
     436            {
     437                struct rlimit rlim;
     438                rlim.rlim_cur = maxmem * 1000000;
     439                rlim.rlim_max = maxmem * 1000000;
     440                setrlimit(RLIMIT_AS, &rlim);
     441            }
     442
    427443            for(j = 0; j < 3; j++)
    428444            {
     
    529545        else if(WIFSIGNALED(status))
    530546        {
    531             fprintf(stdout, "zzuf[seed=%i]: signal %i\n",
    532                     child_list[i].seed, WTERMSIG(status));
     547            fprintf(stdout, "zzuf[seed=%i]: signal %i%s\n",
     548                    child_list[i].seed, WTERMSIG(status),
     549                      (WTERMSIG(status) == SIGKILL && maxmem >= 0) ?
     550                      " (memory exceeded?)" : "");
    533551            crashes++;
    534552        }
     
    667685    printf("Usage: zzuf [-cdimnqSx] [-r ratio] [-s seed | -s start:stop]\n");
    668686    printf("                        [-F forks] [-C crashes] [-B bytes] [-T seconds]\n");
    669     printf("                        [-P protect] [-R refuse]\n");
     687    printf("                        [-M bytes] [-P protect] [-R refuse]\n");
    670688    printf("                        [-I include] [-E exclude] [PROGRAM [ARGS]...]\n");
    671689#   ifdef HAVE_GETOPT_LONG
     
    689707    printf("  -I, --include <regex>    only fuzz files matching <regex>\n");
    690708    printf("  -m, --md5                compute the output's MD5 hash\n");
     709    printf("  -M, --max-memory <n>     maximum child virtual memory size in MB\n");
    691710    printf("  -n, --network            fuzz network input\n");
    692711    printf("  -P, --protect <list>     protect bytes and characters in <list>\n");
     
    711730    printf("  -I <regex>       only fuzz files matching <regex>\n");
    712731    printf("  -m               compute the output's MD5 hash\n");
     732    printf("  -M               maximum child virtual memory size in MB\n");
    713733    printf("  -n               fuzz network input\n");
    714734    printf("  -P <list>        protect bytes and characters in <list>\n");
Note: See TracChangeset for help on using the changeset viewer.