random_data.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include "random_data.h"
  2. #include <string.h>
  3. #include <malloc_wrappers.h>
  4. #include <pb_encode.h>
  5. #ifndef LLVMFUZZER
  6. static uint32_t g_random_seed = 1234;
  7. void random_set_seed(uint32_t seed)
  8. {
  9. g_random_seed = seed;
  10. }
  11. uint32_t random_get_seed()
  12. {
  13. return g_random_seed;
  14. }
  15. /* Uses xorshift64 here instead of rand() for both speed and
  16. * reproducibility across platforms. */
  17. uint32_t rand_word()
  18. {
  19. g_random_seed ^= g_random_seed << 13;
  20. g_random_seed ^= g_random_seed >> 17;
  21. g_random_seed ^= g_random_seed << 5;
  22. return g_random_seed;
  23. }
  24. /* Get a random integer in range, with approximately flat distribution. */
  25. int rand_int(int min, int max)
  26. {
  27. return rand_word() % (max + 1 - min) + min;
  28. }
  29. bool rand_bool()
  30. {
  31. return rand_word() & 1;
  32. }
  33. /* Get a random byte, with skewed distribution.
  34. * Important corner cases like 0xFF, 0x00 and 0xFE occur more
  35. * often than other values. */
  36. uint8_t rand_byte()
  37. {
  38. uint32_t w = rand_word();
  39. uint8_t b = w & 0xFF;
  40. if (w & 0x100000)
  41. b >>= (w >> 8) & 7;
  42. if (w & 0x200000)
  43. b <<= (w >> 12) & 7;
  44. if (w & 0x400000)
  45. b ^= 0xFF;
  46. return b;
  47. }
  48. /* Get a random length, with skewed distribution.
  49. * Favors the shorter lengths, but always at least 1. */
  50. size_t rand_len(size_t max)
  51. {
  52. uint32_t w = rand_word();
  53. size_t s;
  54. if (w & 0x800000)
  55. w &= 3;
  56. else if (w & 0x400000)
  57. w &= 15;
  58. else if (w & 0x200000)
  59. w &= 255;
  60. s = (w % max);
  61. if (s == 0)
  62. s = 1;
  63. return s;
  64. }
  65. /* Fills a buffer with random data with skewed distribution. */
  66. void rand_fill(uint8_t *buf, size_t count)
  67. {
  68. for (; count > 0; count--)
  69. {
  70. *buf++ = rand_byte();
  71. }
  72. }
  73. /* Fill with random protobuf-like data */
  74. size_t rand_fill_protobuf(uint8_t *buf, size_t min_bytes, size_t max_bytes, int min_tag)
  75. {
  76. pb_ostream_t stream = pb_ostream_from_buffer(buf, max_bytes);
  77. while(stream.bytes_written < min_bytes)
  78. {
  79. pb_wire_type_t wt = rand_int(0, 3);
  80. if (wt == 3) wt = 5; /* Gap in values */
  81. if (!pb_encode_tag(&stream, wt, rand_int(min_tag, min_tag + 512)))
  82. break;
  83. if (wt == PB_WT_VARINT)
  84. {
  85. uint64_t value;
  86. rand_fill((uint8_t*)&value, sizeof(value));
  87. pb_encode_varint(&stream, value);
  88. }
  89. else if (wt == PB_WT_64BIT)
  90. {
  91. uint64_t value;
  92. rand_fill((uint8_t*)&value, sizeof(value));
  93. pb_encode_fixed64(&stream, &value);
  94. }
  95. else if (wt == PB_WT_32BIT)
  96. {
  97. uint32_t value;
  98. rand_fill((uint8_t*)&value, sizeof(value));
  99. pb_encode_fixed32(&stream, &value);
  100. }
  101. else if (wt == PB_WT_STRING)
  102. {
  103. size_t len;
  104. uint8_t *buf;
  105. if (min_bytes > stream.bytes_written)
  106. len = rand_len(min_bytes - stream.bytes_written);
  107. else
  108. len = 0;
  109. buf = malloc(len);
  110. pb_encode_varint(&stream, len);
  111. rand_fill(buf, len);
  112. pb_write(&stream, buf, len);
  113. free(buf);
  114. }
  115. }
  116. return stream.bytes_written;
  117. }
  118. /* Given a buffer of data, mess it up a bit */
  119. void rand_mess(uint8_t *buf, size_t count)
  120. {
  121. int m = rand_int(0, 3);
  122. if (m == 0)
  123. {
  124. /* Replace random substring */
  125. int s = rand_int(0, count - 1);
  126. int l = rand_len(count - s);
  127. rand_fill(buf + s, l);
  128. }
  129. else if (m == 1)
  130. {
  131. /* Swap random bytes */
  132. int a = rand_int(0, count - 1);
  133. int b = rand_int(0, count - 1);
  134. int x = buf[a];
  135. buf[a] = buf[b];
  136. buf[b] = x;
  137. }
  138. else if (m == 2)
  139. {
  140. /* Duplicate substring */
  141. int s = rand_int(0, count - 2);
  142. int l = rand_len((count - s) / 2);
  143. memcpy(buf + s + l, buf + s, l);
  144. }
  145. else if (m == 3)
  146. {
  147. /* Add random protobuf noise */
  148. int s = rand_int(0, count - 1);
  149. int l = rand_len(count - s);
  150. rand_fill_protobuf(buf + s, l, count - s, 1);
  151. }
  152. }
  153. /* Append or prepend protobuf noise */
  154. void rand_protobuf_noise(uint8_t *buffer, size_t bufsize, size_t *msglen)
  155. {
  156. int m = rand_int(0, 2);
  157. size_t max_size = bufsize - 32 - *msglen;
  158. if (m == 1)
  159. {
  160. /* Prepend */
  161. uint8_t *tmp = malloc_with_check(bufsize);
  162. size_t s = rand_fill_protobuf(tmp, rand_len(max_size), bufsize - *msglen, 1000);
  163. memmove(buffer + s, buffer, *msglen);
  164. memcpy(buffer, tmp, s);
  165. free_with_check(tmp);
  166. *msglen += s;
  167. }
  168. else if (m == 2)
  169. {
  170. /* Append */
  171. size_t s = rand_fill_protobuf(buffer + *msglen, rand_len(max_size), bufsize - *msglen, 1000);
  172. *msglen += s;
  173. }
  174. }
  175. #endif