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 }