fuzzer_connect.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*
  2. * Copyright (C) 2017-2020 Felix Weinrank
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the project nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <stdarg.h>
  34. #include <assert.h>
  35. #include <usrsctp.h>
  36. #include "../programs/programs_helper.h"
  37. //#define FUZZ_ALWAYS_INITIALIZE
  38. //#define FUZZ_VERBOSE
  39. #define FUZZ_INTERLEAVING
  40. #define FUZZ_STREAM_RESET
  41. #define FUZZ_B_INJECT_INIT_ACK (1 << 0)
  42. #define FUZZ_B_INJECT_COOKIE_ACK (1 << 1)
  43. #define FUZZ_B_SEND_DATA (1 << 2)
  44. #define FUZZ_B_SEND_STREAM_RESET (1 << 3)
  45. #define FUZZ_B_INJECT_DATA (1 << 4)
  46. #define FUZZ_B_I_DATA_SUPPORT (1 << 5)
  47. #define FUZZ_B_SEND_DATA_FORCE (1 << 6)
  48. #define FUZZ_B_RESERVED (1 << 7)
  49. #define BUFFER_SIZE 4096
  50. #define COMMON_HEADER_SIZE 12
  51. static uint32_t assoc_vtag = 0;
  52. #ifdef FUZZ_VERBOSE
  53. #define fuzzer_printf(...) debug_printf(__VA_ARGS__)
  54. #else
  55. #define fuzzer_printf(...)
  56. #endif
  57. static void
  58. dump_packet(const void *buffer, size_t bufferlen, int inout)
  59. {
  60. #ifdef FUZZ_VERBOSE
  61. static char *dump_buf;
  62. if ((dump_buf = usrsctp_dumppacket(buffer, bufferlen, inout)) != NULL) {
  63. fprintf(stderr, "%s", dump_buf);
  64. usrsctp_freedumpbuffer(dump_buf);
  65. }
  66. #endif // FUZZ_VERBOSE
  67. }
  68. static int
  69. conn_output(void *addr, void *buf, size_t length, uint8_t tos, uint8_t set_df)
  70. {
  71. struct sctp_init_chunk *init_chunk;
  72. const char *init_chunk_first_bytes = "\x13\x88\x13\x89\x00\x00\x00\x00\x00\x00\x00\x00\x01";
  73. // Looking for the outgoing VTAG.
  74. // length >= (COMMON_HEADER_SIZE + 16 (min size of INIT))
  75. // If the common header has no VTAG (all zero), we're assuming it carries an INIT
  76. if ((length >= (COMMON_HEADER_SIZE + 16)) && (memcmp(buf, init_chunk_first_bytes, COMMON_HEADER_SIZE) == 0)) {
  77. init_chunk = (struct sctp_init_chunk*) ((char *)buf + sizeof(struct sctp_common_header));
  78. fuzzer_printf("Found outgoing INIT, extracting VTAG : %u\n", init_chunk->initiate_tag);
  79. assoc_vtag = init_chunk->initiate_tag;
  80. }
  81. dump_packet(buf, length, SCTP_DUMP_OUTBOUND);
  82. return (0);
  83. }
  84. static void
  85. handle_upcall(struct socket *sock, void *arg, int flgs)
  86. {
  87. fuzzer_printf("handle_upcall()\n");
  88. int events = usrsctp_get_events(sock);
  89. while (events & SCTP_EVENT_READ) {
  90. struct sctp_recvv_rn rn;
  91. ssize_t n;
  92. struct sockaddr_in addr;
  93. char *buf = calloc(1, BUFFER_SIZE);
  94. int flags = 0;
  95. socklen_t len = (socklen_t)sizeof(struct sockaddr_in);
  96. unsigned int infotype = 0;
  97. socklen_t infolen = sizeof(struct sctp_recvv_rn);
  98. memset(&rn, 0, sizeof(struct sctp_recvv_rn));
  99. n = usrsctp_recvv(sock, buf, BUFFER_SIZE, (struct sockaddr *) &addr, &len, (void *)&rn, &infolen, &infotype, &flags);
  100. fuzzer_printf("usrsctp_recvv() - returned %zd\n", n);
  101. if (flags & MSG_NOTIFICATION) {
  102. fuzzer_printf("NOTIFICATION received\n");
  103. #ifdef FUZZ_VERBOSE
  104. handle_notification((union sctp_notification *)buf, n);
  105. #endif // FUZZ_VERBOSE
  106. } else {
  107. fuzzer_printf("DATA received\n");
  108. }
  109. free(buf);
  110. if (n <= 0) {
  111. break;
  112. }
  113. events = usrsctp_get_events(sock);
  114. }
  115. }
  116. int
  117. initialize_fuzzer(void) {
  118. #ifdef FUZZ_VERBOSE
  119. usrsctp_init(0, conn_output, debug_printf_stack);
  120. #else // FUZZ_VERBOSE
  121. usrsctp_init(0, conn_output, NULL);
  122. #endif // FUZZ_VERBOSE
  123. usrsctp_enable_crc32c_offload();
  124. #ifdef SCTP_DEBUG
  125. usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_ALL);
  126. #endif // SCTP_DEBUG
  127. usrsctp_register_address((void *)1);
  128. usrsctp_sysctl_set_sctp_pktdrop_enable(1);
  129. usrsctp_sysctl_set_sctp_nrsack_enable(1);
  130. fuzzer_printf("usrsctp initialized\n");
  131. return (1);
  132. }
  133. int
  134. LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
  135. {
  136. static int initialized;
  137. char *fuzz_packet_buffer;
  138. struct sockaddr_conn sconn;
  139. struct socket *socket_client;
  140. struct linger so_linger;
  141. struct sctp_event event;
  142. unsigned long i;
  143. struct sctp_common_header* common_header;
  144. uint16_t event_types[] = {
  145. SCTP_ASSOC_CHANGE,
  146. SCTP_PEER_ADDR_CHANGE,
  147. SCTP_REMOTE_ERROR,
  148. SCTP_SEND_FAILED,
  149. SCTP_SHUTDOWN_EVENT,
  150. SCTP_ADAPTATION_INDICATION,
  151. SCTP_PARTIAL_DELIVERY_EVENT,
  152. SCTP_AUTHENTICATION_EVENT,
  153. SCTP_STREAM_RESET_EVENT,
  154. SCTP_SENDER_DRY_EVENT,
  155. SCTP_ASSOC_RESET_EVENT,
  156. SCTP_STREAM_CHANGE_EVENT,
  157. SCTP_SEND_FAILED_EVENT
  158. };
  159. int optval;
  160. int result;
  161. struct sctp_initmsg initmsg;
  162. #if defined(FUZZ_STREAM_RESET) || defined(FUZZ_INTERLEAVING)
  163. struct sctp_assoc_value assoc_val;
  164. #endif // defined(FUZZ_STREAM_RESET) || defined(FUZZ_INTERLEAVING)
  165. // WITH COMMON HEADER!
  166. char fuzz_init_ack[] = "\x13\x89\x13\x88\x49\xa4\xac\xb2\x00\x00\x00\x00\x02\x00\x01\xb4" \
  167. "\x2b\xe8\x47\x40\x00\x1c\x71\xc7\xff\xff\xff\xff\xed\x69\x58\xec" \
  168. "\xc0\x06\x00\x08\x00\x00\x07\xc4\x80\x00\x00\x04\xc0\x00\x00\x04" \
  169. "\x80\x08\x00\x0b\xc0\xc2\x0f\xc1\x80\x82\x40\x00\x80\x02\x00\x24" \
  170. "\x40\x39\xcf\x32\xd6\x60\xcf\xfa\x3f\x2f\xa9\x52\xed\x2b\xf2\xe6" \
  171. "\x2f\xb7\x81\x96\xf8\xda\xe9\xa0\x62\x01\x79\xe1\x0d\x5f\x38\xaa" \
  172. "\x80\x04\x00\x08\x00\x03\x00\x01\x80\x03\x00\x06\x80\xc1\x00\x00" \
  173. "\x00\x07\x01\x50\x4b\x41\x4d\x45\x2d\x42\x53\x44\x20\x31\x2e\x31" \
  174. "\x00\x00\x00\x00\x64\xdb\x63\x00\x00\x00\x00\x00\xc9\x76\x03\x00" \
  175. "\x00\x00\x00\x00\x60\xea\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
  176. "\xb2\xac\xa4\x49\x2b\xe8\x47\x40\xd4\xc9\x79\x52\x00\x00\x00\x00" \
  177. "\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\xd4\xc9\x79\x53" \
  178. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00" \
  179. "\x00\x00\x00\x00\x5a\x76\x13\x89\x01\x00\x00\x00\x00\x00\x00\x00" \
  180. "\x00\x00\x00\x00\x01\x00\x00\x62\x49\xa4\xac\xb2\x00\x1c\x71\xc7" \
  181. "\x00\x01\xff\xff\x82\xe6\xc8\x44\x80\x00\x00\x04\xc0\x00\x00\x04" \
  182. "\x80\x08\x00\x0b\xc0\xc2\x0f\xc1\x80\x82\x40\x00\x80\x02\x00\x24" \
  183. "\xb6\xbb\xb5\x7f\xbb\x4b\x0e\xb5\x42\xf6\x75\x18\x4f\x79\x0f\x24" \
  184. "\x1c\x44\x0b\xd6\x62\xa9\x84\xe7\x2c\x3c\x7f\xad\x1b\x67\x81\x57" \
  185. "\x80\x04\x00\x08\x00\x03\x00\x01\x80\x03\x00\x06\x80\xc1\x00\x00" \
  186. "\x00\x0c\x00\x06\x00\x05\x00\x00\x02\x00\x01\xb4\x2b\xe8\x47\x40" \
  187. "\x00\x1c\x71\xc7\x00\x01\xff\xff\xed\x69\x58\xec\xc0\x06\x00\x08" \
  188. "\x00\x00\x07\xc4\x80\x00\x00\x04\xc0\x00\x00\x04\x80\x08\x00\x0b" \
  189. "\xc0\xc2\x0f\xc1\x80\x82\x40\x00\x80\x02\x00\x24\x40\x39\xcf\x32" \
  190. "\xd6\x60\xcf\xfa\x3f\x2f\xa9\x52\xed\x2b\xf2\xe6\x2f\xb7\x81\x96" \
  191. "\xf8\xda\xe9\xa0\x62\x01\x79\xe1\x0d\x5f\x38\xaa\x80\x04\x00\x08" \
  192. "\x00\x03\x00\x01\x80\x03\x00\x06\x80\xc1\x00\x00\x81\xe1\x1e\x81" \
  193. "\xea\x41\xeb\xf0\x12\xd9\x74\xbe\x13\xfd\x4b\x6c\x5c\xa2\x8f\x00";
  194. // WITH COMMON HEADER!
  195. char fuzz_cookie_ack[] = "\x13\x89\x13\x88\x54\xc2\x7c\x46\x00\x00\x00\x00\x0b\x00\x00\x04";
  196. // WITH COMMON HEADER!
  197. char fuzz_i_data[] = "\x13\x89\x13\x88\x07\x01\x6c\xd3\x00\x00\x00\x00\x40\x03" \
  198. "\x00\xdc\x2d\x2b\x46\xd4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
  199. "\x00\x27\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  200. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  201. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  202. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  203. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  204. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  205. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  206. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  207. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  208. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  209. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  210. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  211. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41";
  212. // WITH COMMON HEADER!
  213. char fuzz_data[] = "\x13\x89\x13\x88\x27\xc4\xbf\xdf\x00\x00\x00\x00\x00\x03" \
  214. "\x00\xd8\x79\x64\xb7\xc1\x00\x00\x00\x00\x00\x00\x00\x27\x41\x41" \
  215. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  216. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  217. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  218. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  219. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  220. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  221. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  222. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  223. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  224. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  225. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  226. "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" \
  227. "\x41\x41\x41\x41\x41\x41";
  228. char fuzz_common_header[] = "\x13\x89\x13\x88\x54\xc2\x7c\x46\x00\x00\x00\x00";
  229. fuzzer_printf("LLVMFuzzerTestOneInput()\n");
  230. #ifdef FUZZ_ALWAYS_INITIALIZE
  231. initialize_fuzzer();
  232. #else
  233. if (!initialized) {
  234. initialized = initialize_fuzzer();
  235. }
  236. #endif
  237. if (data_size < 5 || data_size > 65535) {
  238. // Skip too small and too large packets
  239. fuzzer_printf("data_size %zu makes no sense, skipping\n", data_size);
  240. return (0);
  241. }
  242. socket_client = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, 0);
  243. FUZZER_ASSERT(socket_client != NULL);
  244. usrsctp_set_non_blocking(socket_client, 1);
  245. // all max!
  246. memset(&initmsg, 1, sizeof(struct sctp_initmsg));
  247. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg));
  248. FUZZER_ASSERT(result == 0);
  249. so_linger.l_onoff = 1;
  250. so_linger.l_linger = 0;
  251. result = usrsctp_setsockopt(socket_client, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(struct linger));
  252. FUZZER_ASSERT(result == 0);
  253. memset(&event, 0, sizeof(event));
  254. event.se_on = 1;
  255. for (i = 0; i < (sizeof(event_types) / sizeof(uint16_t)); i++) {
  256. event.se_type = event_types[i];
  257. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event));
  258. FUZZER_ASSERT(result == 0);
  259. }
  260. optval = 1;
  261. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_RECVRCVINFO, &optval, sizeof(optval));
  262. FUZZER_ASSERT(result == 0);
  263. optval = 1;
  264. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_RECVNXTINFO, &optval, sizeof(optval));
  265. FUZZER_ASSERT(result == 0);
  266. #if defined(FUZZ_STREAM_RESET)
  267. assoc_val.assoc_id = SCTP_ALL_ASSOC;
  268. assoc_val.assoc_value = SCTP_ENABLE_RESET_STREAM_REQ | SCTP_ENABLE_RESET_ASSOC_REQ | SCTP_ENABLE_CHANGE_ASSOC_REQ;
  269. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &assoc_val, sizeof(struct sctp_assoc_value));
  270. FUZZER_ASSERT(result == 0);
  271. #endif // defined(FUZZ_STREAM_RESET)
  272. #if defined(FUZZ_INTERLEAVING)
  273. #if !defined(SCTP_INTERLEAVING_SUPPORTED)
  274. #define SCTP_INTERLEAVING_SUPPORTED 0x00001206
  275. #endif // !defined(SCTP_INTERLEAVING_SUPPORTED)
  276. if (data[0] & FUZZ_B_I_DATA_SUPPORT) {
  277. optval = 2;
  278. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &optval, sizeof(optval));
  279. FUZZER_ASSERT(result == 0);
  280. memset(&assoc_val, 0, sizeof(assoc_val));
  281. assoc_val.assoc_value = 1;
  282. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_INTERLEAVING_SUPPORTED, &assoc_val, sizeof(assoc_val));
  283. FUZZER_ASSERT(result == 0);
  284. }
  285. #endif // defined(FUZZ_INTERLEAVING)
  286. optval = 1;
  287. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_REUSE_PORT, &optval, sizeof(optval));
  288. FUZZER_ASSERT(result == 0);
  289. memset(&sconn, 0, sizeof(struct sockaddr_conn));
  290. sconn.sconn_family = AF_CONN;
  291. #ifdef HAVE_SCONN_LEN
  292. sconn.sconn_len = sizeof(struct sockaddr_conn);
  293. #endif // HAVE_SCONN_LEN
  294. sconn.sconn_port = htons(5000);
  295. sconn.sconn_addr = (void *)1;
  296. result = usrsctp_bind(socket_client, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn));
  297. FUZZER_ASSERT(result == 0);
  298. // Disable Nagle.
  299. optval = 1;
  300. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_NODELAY, &optval, sizeof(optval));
  301. FUZZER_ASSERT(result == 0);
  302. usrsctp_set_upcall(socket_client, handle_upcall, NULL);
  303. memset(&sconn, 0, sizeof(struct sockaddr_conn));
  304. sconn.sconn_family = AF_CONN;
  305. #ifdef HAVE_SCONN_LEN
  306. sconn.sconn_len = sizeof(struct sockaddr_conn);
  307. #endif // HAVE_SCONN_LEN
  308. sconn.sconn_port = htons(5001);
  309. sconn.sconn_addr = (void *)1;
  310. fuzzer_printf("Calling usrsctp_connect()\n");
  311. result = usrsctp_connect(socket_client, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn));
  312. FUZZER_ASSERT(result == 0 || errno == EINPROGRESS);
  313. if (data[0] & FUZZ_B_INJECT_INIT_ACK) {
  314. fuzzer_printf("Injecting INIT-ACK\n");
  315. common_header = (struct sctp_common_header*) fuzz_init_ack;
  316. common_header->verification_tag = assoc_vtag;
  317. dump_packet(fuzz_init_ack, 448, SCTP_DUMP_INBOUND);
  318. usrsctp_conninput((void *)1, fuzz_init_ack, 448, 0);
  319. }
  320. if (data[0] & FUZZ_B_INJECT_COOKIE_ACK) {
  321. fuzzer_printf("Injecting COOKIE-ACK\n");
  322. common_header = (struct sctp_common_header*) fuzz_cookie_ack;
  323. common_header->verification_tag = assoc_vtag;
  324. dump_packet(fuzz_cookie_ack, 16, SCTP_DUMP_INBOUND);
  325. usrsctp_conninput((void *)1, fuzz_cookie_ack, 16, 0);
  326. }
  327. if (data[0] & FUZZ_B_INJECT_INIT_ACK &&
  328. data[0] & FUZZ_B_INJECT_COOKIE_ACK &&
  329. data[0] & FUZZ_B_SEND_DATA) {
  330. const char *sendbuffer = "Geologie ist keine richtige Wissenschaft!";
  331. fuzzer_printf("Calling usrsctp_sendv()\n");
  332. usrsctp_sendv(socket_client, sendbuffer, strlen(sendbuffer), NULL, 0, NULL, 0, SCTP_SENDV_NOINFO, 0);
  333. }
  334. // Required: INIT-ACK and COOKIE-ACK
  335. if (data[0] & FUZZ_B_INJECT_INIT_ACK &&
  336. data[0] & FUZZ_B_INJECT_COOKIE_ACK &&
  337. data[0] & FUZZ_B_SEND_STREAM_RESET) {
  338. fuzzer_printf("Sending Stream Reset for all streams\n");
  339. struct sctp_reset_streams srs;
  340. memset(&srs, 0, sizeof(struct sctp_reset_streams));
  341. srs.srs_flags = SCTP_STREAM_RESET_INCOMING | SCTP_STREAM_RESET_OUTGOING;
  342. result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_RESET_STREAMS, &srs, sizeof(struct sctp_reset_streams));
  343. FUZZER_ASSERT(result == 0);
  344. }
  345. // Required: INIT-ACK and COOKIE-ACK
  346. if (data[0] & FUZZ_B_INJECT_INIT_ACK &&
  347. data[0] & FUZZ_B_INJECT_COOKIE_ACK &&
  348. data[0] & FUZZ_B_INJECT_DATA) {
  349. if (data[0] & FUZZ_B_I_DATA_SUPPORT) {
  350. fuzzer_printf("Injecting I-DATA\n");
  351. common_header = (struct sctp_common_header*) fuzz_i_data;
  352. common_header->verification_tag = assoc_vtag;
  353. dump_packet(fuzz_i_data, 232, SCTP_DUMP_INBOUND);
  354. usrsctp_conninput((void *)1, fuzz_i_data, 232, 0);
  355. } else {
  356. fuzzer_printf("Injecting DATA\n");
  357. common_header = (struct sctp_common_header*) fuzz_data;
  358. common_header->verification_tag = assoc_vtag;
  359. dump_packet(fuzz_data, 228, SCTP_DUMP_INBOUND);
  360. usrsctp_conninput((void *)1, fuzz_data, 228, 0);
  361. }
  362. }
  363. if (data[0] & FUZZ_B_I_DATA_SUPPORT &&
  364. data[0] & FUZZ_B_SEND_DATA_FORCE) {
  365. const char *sendbuffer = "Geologie ist keine richtige Wissenschaft!";
  366. fuzzer_printf("Calling usrsctp_sendv()\n");
  367. usrsctp_sendv(socket_client, sendbuffer, strlen(sendbuffer), NULL, 0, NULL, 0, SCTP_SENDV_NOINFO, 0);
  368. }
  369. fuzz_packet_buffer = malloc(data_size - 1 + COMMON_HEADER_SIZE);
  370. memcpy(fuzz_packet_buffer, fuzz_common_header, COMMON_HEADER_SIZE); // common header
  371. memcpy(fuzz_packet_buffer + COMMON_HEADER_SIZE, data + 1, data_size - 1);
  372. common_header = (struct sctp_common_header*) fuzz_packet_buffer;
  373. common_header->verification_tag = assoc_vtag;
  374. fuzzer_printf("Injecting FUZZER-Packet\n");
  375. dump_packet(fuzz_packet_buffer, data_size - 1 + COMMON_HEADER_SIZE, SCTP_DUMP_INBOUND);
  376. usrsctp_conninput((void *)1, fuzz_packet_buffer, data_size - 1 + COMMON_HEADER_SIZE, 0);
  377. free(fuzz_packet_buffer);
  378. fuzzer_printf("Calling usrsctp_close()\n");
  379. usrsctp_close(socket_client);
  380. #ifdef FUZZ_ALWAYS_INITIALIZE
  381. fuzzer_printf("Calling usrsctp_finish()\n");
  382. while (usrsctp_finish() != 0) {}
  383. fuzzer_printf("Done!\n");
  384. #endif
  385. return (0);
  386. }