• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stddef.h>
2 #include <unistd.h>
3 #include <stdint.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdbool.h>
7 #include <string.h>
8 
9 #include "mpg123.h"
10 
fuzzer_get_tmpfile(const uint8_t * data,size_t size)11 static char* fuzzer_get_tmpfile(const uint8_t* data, size_t size) {
12   char* filename_buffer = strdup("/tmp/generate_temporary_file.XXXXXX");
13   if (!filename_buffer) {
14     perror("Failed to allocate file name buffer.");
15     abort();
16   }
17   const int file_descriptor = mkstemp(filename_buffer);
18   if (file_descriptor < 0) {
19     perror("Failed to make temporary file.");
20     abort();
21   }
22   FILE* file = fdopen(file_descriptor, "wb");
23   if (!file) {
24     perror("Failed to open file descriptor.");
25     close(file_descriptor);
26     abort();
27   }
28   const size_t bytes_written = fwrite(data, sizeof(uint8_t), size, file);
29   if (bytes_written < size) {
30     close(file_descriptor);
31     fprintf(stderr, "Failed to write all bytes to file (%zu out of %zu)",
32             bytes_written, size);
33     abort();
34   }
35   fclose(file);
36   return filename_buffer;
37 }
38 
fuzzer_release_tmpfile(char * filename)39 static void fuzzer_release_tmpfile(char* filename) {
40   if (unlink(filename) != 0) {
41     perror("WARNING: Failed to delete temporary file.");
42   }
43   free(filename);
44 }
45 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)46 int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
47   static bool initialized = false;
48   if (!initialized) {
49     mpg123_init();
50     initialized = true;
51   }
52   char* filename = fuzzer_get_tmpfile(data, size);
53   if (filename == NULL) {
54     return 0;
55   }
56 
57   size_t outmemorysize = size * 2;  // Guess based on the size of data.
58   unsigned char* outmemory = (unsigned char*)malloc(outmemorysize);
59   if (outmemory == NULL) {
60     fuzzer_release_tmpfile(filename);
61     return 0;
62   }
63 
64   int error;
65   mpg123_handle* handle = mpg123_new(NULL, &error);
66   if (handle == NULL || mpg123_param(handle,
67       MPG123_ADD_FLAGS, MPG123_QUIET, 0.) != MPG123_OK) {
68     free(outmemory);
69     fuzzer_release_tmpfile(filename);
70     return 0;
71   }
72 
73   if (mpg123_open(handle, filename) == MPG123_OK) {
74     int read_error;
75     do {
76       size_t decoded_size;
77       read_error = mpg123_read(handle, outmemory, outmemorysize, &decoded_size);
78     } while (read_error == MPG123_OK && mpg123_tellframe(handle) <= 10000
79           && mpg123_tell_stream(handle) <= 1<<20);
80   }
81 
82   mpg123_close(handle);
83   mpg123_delete(handle);
84   free(outmemory);
85   fuzzer_release_tmpfile(filename);
86   return 0;
87 }
88