etc.git


etc

~ scripts and random things
git clone https://github.com/djnnvx/etc.git
log | files | refs | archive

fuzz_mount.c (1497B)

      1 /*
      2  * MOUNT protocol replies (NFSv3 mount path). The MOUNT protocol runs
      3  * BEFORE any NFS authentication negotiation, so it's the first surface a
      4  * malicious server can attack. mountres3 contains a variable-length
      5  * list of supported auth flavours and a file handle, exports replies
      6  * are linked lists of export entries with embedded group lists.
      7  *
      8  * The exports decoder in particular walks attacker-supplied linked-list
      9  * chains; cycle-checks tend to be lax in legacy XDR codepaths.
     10  */
     11 #include "harness.h"
     12 #include "libnfs-raw-mount.h"
     13 
     14 typedef bool_t (*mount_dec)(ZDR *, void *);
     15 
     16 #define DEC(name)  { #name, (mount_dec)zdr_##name, sizeof(name) }
     17 
     18 static const struct {
     19     const char *name;
     20     mount_dec fn;
     21     size_t result_size;
     22 } decoders[] = {
     23     DEC(mountres3),
     24     DEC(exports),
     25     DEC(mountlist),
     26     DEC(mountres1),
     27     DEC(MOUNT1MNTres),
     28     DEC(MOUNT1DUMPres),
     29 };
     30 #define N_DEC (sizeof(decoders) / sizeof(decoders[0]))
     31 
     32 static int fuzz_one(const uint8_t *data, size_t size)
     33 {
     34     if (size < 1)
     35         return 0;
     36     unsigned idx = data[0] % N_DEC;
     37     const uint8_t *payload = data + 1;
     38     size_t payload_size = size - 1;
     39 
     40     ZDR zdr;
     41     nfs_zdrmem_decode(&zdr, payload, payload_size);
     42 
     43     void *res = calloc(1, decoders[idx].result_size);
     44     if (!res) {
     45         zdr_destroy(&zdr);
     46         return 0;
     47     }
     48     if (decoders[idx].fn(&zdr, res)) {
     49         zdr_free((zdrproc_t)decoders[idx].fn, (caddr_t)res);
     50     }
     51     free(res);
     52     zdr_destroy(&zdr);
     53     return 0;
     54 }