Coverage Report

Created: 2025-07-11 06:20

/src/tmux/fuzz/input-fuzzer.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2020 Sergey Nizovtsev <snizovtsev@gmail.com>
3
 *
4
 * Permission to use, copy, modify, and distribute this software for any
5
 * purpose with or without fee is hereby granted, provided that the above
6
 * copyright notice and this permission notice appear in all copies.
7
 *
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
13
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
14
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
 */
16
17
#include <stddef.h>
18
#include <assert.h>
19
#include <fcntl.h>
20
21
#include "tmux.h"
22
23
11.2k
#define FUZZER_MAXLEN 512
24
11.2k
#define PANE_WIDTH 80
25
11.2k
#define PANE_HEIGHT 25
26
27
struct event_base *libevent;
28
29
int
30
LLVMFuzzerTestOneInput(const u_char *data, size_t size)
31
11.2k
{
32
11.2k
  struct bufferevent  *vpty[2];
33
11.2k
  struct window   *w;
34
11.2k
  struct window_pane  *wp;
35
11.2k
  int      error;
36
37
  /*
38
   * Since AFL doesn't support -max_len parameter we have to
39
   * discard long inputs manually.
40
   */
41
11.2k
  if (size > FUZZER_MAXLEN)
42
0
    return 0;
43
44
11.2k
  w = window_create(PANE_WIDTH, PANE_HEIGHT, 0, 0);
45
11.2k
  wp = window_add_pane(w, NULL, 0, 0);
46
11.2k
  bufferevent_pair_new(libevent, BEV_OPT_CLOSE_ON_FREE, vpty);
47
11.2k
  wp->ictx = input_init(wp, vpty[0], NULL);
48
11.2k
  window_add_ref(w, __func__);
49
50
11.2k
  wp->fd = open("/dev/null", O_WRONLY);
51
11.2k
  if (wp->fd == -1)
52
0
    errx(1, "open(\"/dev/null\") failed");
53
11.2k
  wp->event = bufferevent_new(wp->fd, NULL, NULL, NULL, NULL);
54
55
11.2k
  input_parse_buffer(wp, (u_char *)data, size);
56
11.6k
  while (cmdq_next(NULL) != 0)
57
395
    ;
58
11.2k
  error = event_base_loop(libevent, EVLOOP_NONBLOCK);
59
11.2k
  if (error == -1)
60
0
    errx(1, "event_base_loop failed");
61
62
11.2k
  assert(w->references == 1);
63
11.2k
  window_remove_ref(w, __func__);
64
65
11.2k
  bufferevent_free(vpty[0]);
66
11.2k
  bufferevent_free(vpty[1]);
67
68
11.2k
  return 0;
69
11.2k
}
70
71
int
72
LLVMFuzzerInitialize(__unused int *argc, __unused char ***argv)
73
2
{
74
2
  const struct options_table_entry  *oe;
75
76
2
  global_environ = environ_create();
77
2
  global_options = options_create(NULL);
78
2
  global_s_options = options_create(NULL);
79
2
  global_w_options = options_create(NULL);
80
412
  for (oe = options_table; oe->name != NULL; oe++) {
81
410
    if (oe->scope & OPTIONS_TABLE_SERVER)
82
48
      options_default(global_options, oe);
83
410
    if (oe->scope & OPTIONS_TABLE_SESSION)
84
216
      options_default(global_s_options, oe);
85
410
    if (oe->scope & OPTIONS_TABLE_WINDOW)
86
146
      options_default(global_w_options, oe);
87
410
  }
88
2
  libevent = osdep_event_init();
89
90
2
  options_set_number(global_w_options, "monitor-bell", 0);
91
2
  options_set_number(global_w_options, "allow-rename", 1);
92
2
  options_set_number(global_options, "set-clipboard", 2);
93
2
  socket_path = xstrdup("dummy");
94
95
2
  return 0;
96
2
}