This ensures that we don't open some other fd, for example when loading playlist. Also filters out loading any local files. This also allows to remove custom filtering from fuzzer itself.
Unified · Split
| @@ -45,6 +45,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) · 44 unmodified lines | |||
| 45 | int fd = memfd_create("fuzz_mpv_load", MFD_CLOEXEC | MFD_ALLOW_SEALING); | 45 | int fd = memfd_create("fuzz_mpv_load", MFD_CLOEXEC | MFD_ALLOW_SEALING); |
| 46 | if (fd == -1) | 46 | if (fd == -1) |
| 47 | exit(1); | 47 | exit(1); |
| 48 | if (dup3(fd, 42, O_CLOEXEC) != 42 || close(fd)) | ||
| 49 | exit(1); | ||
| 50 | fd = 42; | ||
| 48 | ssize_t written = 0; | 51 | ssize_t written = 0; |
| 49 | while (written < size) { | 52 | while (written < size) { |
| 50 | ssize_t result = write(fd, data + written, size - written); | 53 | ssize_t result = write(fd, data + written, size - written); |
| @@ -85,7 +88,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) · 34 unmodified lines | |||
| 85 | #endif | 88 | #endif |
| 86 | 89 | ||
| 87 | mpv_terminate_destroy(ctx); | 90 | mpv_terminate_destroy(ctx); |
| 88 | close(fd); | 91 | |
| 92 | if (close(fd)) | ||
| 93 | exit(1); | ||
| 89 | 94 | ||
| 90 | return 0; | 95 | return 0; |
| 91 | } | 96 | } |
| @@ -38,26 +38,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) · 37 unmodified lines | |||
| 38 | return 0; | 38 | return 0; |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | #if !defined(MPV_PROTO) || defined(MPV_PROTO_FILE) | ||
| 42 | const uint8_t *data_check = data; | ||
| 43 | size_t size_check = size; | ||
| 44 | size_t prefix_size = sizeof("file://") - 1; | ||
| 45 | if (str_startswith(data, size - 1, "file://", prefix_size)) { | ||
| 46 | data_check += prefix_size; | ||
| 47 | size_check -= prefix_size; | ||
| 48 | } | ||
| 49 | // Exclude some common paths that are not useful for testing. | ||
| 50 | // Exclude - | ||
| 51 | if (size_check == 2 && !strncmp(data_check, "-", 1)) | ||
| 52 | return 0; | ||
| 53 | // Exclude relative paths | ||
| 54 | if (str_startswith(data_check, size_check - 1, ".", 1)) | ||
| 55 | return 0; | ||
| 56 | // Exclude absolute paths | ||
| 57 | if (str_startswith(data_check, size_check - 1, "/", 1)) | ||
| 58 | return 0; | ||
| 59 | #endif | ||
| 60 | |||
| 61 | mpv_handle *ctx = mpv_create(); | 41 | mpv_handle *ctx = mpv_create(); |
| 62 | if (!ctx) | 42 | if (!ctx) |
| 63 | exit(1); | 43 | exit(1); |
| @@ -1182,18 +1182,6 @@ static void start_open(struct MPContext *mpctx, char *url, int url_flags, · 1181 unmodified lines | |||
| 1182 | mpctx->open_for_prefetch = for_prefetch && mpctx->opts->demuxer_thread; | 1182 | mpctx->open_for_prefetch = for_prefetch && mpctx->opts->demuxer_thread; |
| 1183 | mpctx->demuxer_changed = false; | 1183 | mpctx->demuxer_changed = false; |
| 1184 | 1184 | ||
| 1185 | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | ||
| 1186 | // Don't allow to open local paths or stdin during fuzzing | ||
| 1187 | bstr open_url = bstr0(mpctx->open_url); | ||
| 1188 | if (bstr_startswith0(open_url, "/") || | ||
| 1189 | bstr_startswith0(open_url, ".") || | ||
| 1190 | bstr_equals0(open_url, "-")) | ||
| 1191 | { | ||
| 1192 | cancel_open(mpctx); | ||
| 1193 | return; | ||
| 1194 | } | ||
| 1195 | #endif | ||
| 1196 | |||
| 1197 | if (mp_thread_create(&mpctx->open_thread, open_demux_thread, mpctx)) { | 1185 | if (mp_thread_create(&mpctx->open_thread, open_demux_thread, mpctx)) { |
| 1198 | cancel_open(mpctx); | 1186 | cancel_open(mpctx); |
| 1199 | return; | 1187 | return; |
| @@ -309,10 +309,6 @@ static int open_f(stream_t *stream, const struct stream_open_args *args) · 308 unmodified lines | |||
| 309 | MP_ERR(stream, "Invalid FD: %d\n", p->fd); | 309 | MP_ERR(stream, "Invalid FD: %d\n", p->fd); |
| 310 | return STREAM_ERROR; | 310 | return STREAM_ERROR; |
| 311 | } | 311 | } |
| 312 | #endif | ||
| 313 | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | ||
| 314 | if (p->fd == STDIN_FILENO || p->fd == STDOUT_FILENO || p->fd == STDERR_FILENO) | ||
| 315 | return STREAM_ERROR; | ||
| 316 | #endif | 312 | #endif |
| 317 | if (is_fdclose) | 313 | if (is_fdclose) |
| 318 | p->close = true; | 314 | p->close = true; |
| @@ -344,6 +340,13 @@ static int open_f(stream_t *stream, const struct stream_open_args *args) · 25 unmodified lines | |||
| 344 | p->close = true; | 340 | p->close = true; |
| 345 | } | 341 | } |
| 346 | 342 | ||
| 343 | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | ||
| 344 | if (p->fd != 42) { | ||
| 345 | s_close(stream); | ||
| 346 | return STREAM_ERROR; | ||
| 347 | } | ||
| 348 | #endif | ||
| 349 | |||
| 347 | struct stat st; | 350 | struct stat st; |
| 348 | bool is_sock_or_fifo = false; | 351 | bool is_sock_or_fifo = false; |
| 349 | if (fstat(p->fd, &st) == 0) { | 352 | if (fstat(p->fd, &st) == 0) { |