Coverage Report

Created: 2025-12-28 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/adhd/cras/fuzz/cras_fl_media_fuzzer.cc
Line
Count
Source
1
/* Copyright 2022 The ChromiumOS Authors
2
 * Use of this source code is governed by a BSD-style license that can be
3
 * found in the LICENSE file.
4
 */
5
#include <cstdio>
6
#include <cstring>
7
#include <fuzzer/FuzzedDataProvider.h>
8
#include <stddef.h>
9
#include <stdint.h>
10
#include <stdio.h>
11
#include <string.h>
12
13
#include "cras/common/check.h"
14
#include "cras/src/server/cras_a2dp_manager.h"
15
#include "cras/src/server/cras_alert.h"
16
#include "cras/src/server/cras_bt_log.h"
17
#include "cras/src/server/cras_dsp.h"
18
#include "cras/src/server/cras_fl_media.h"
19
#include "cras/src/server/cras_fl_media_adapter.h"
20
#include "cras/src/server/cras_iodev_list.h"
21
#include "cras/src/server/cras_mix.h"
22
#include "cras/src/server/cras_observer.h"
23
#include "cras/src/server/cras_rclient.h"
24
#include "cras/src/server/cras_stream_apm.h"
25
#include "cras/src/server/cras_system_state.h"
26
#include "cras_shm.h"
27
28
#define BT_OBJECT_BASE "/org/chromium/bluetooth/hci"
29
#define BT_OBJECT_MEDIA "/media"
30
31
static struct fl_media* active_fm = NULL;
32
static std::string addr = "";
33
static cras_rclient* client = NULL;
34
35
/* This fuzzer consumes bytes of size ranging from 270 to 340.
36
 * Minimum fuzzing size if therefore set at 350.
37
 */
38
const int kMinFuzzDataSize = 350;
39
const int kMaxStringLength = 100;
40
41
/* rclient_buffer_on_client consumes an int and a cras_server_message
42
 * struct cras_connect_message is of size 99
43
 */
44
const int kMinRclientMsgSize = 104;
45
46
struct cras_fl_a2dp_codec_config* codecs_create(
47
2.67k
    FuzzedDataProvider* data_provider) {
48
2.67k
  int bps = data_provider->ConsumeIntegral<int>();
49
2.67k
  int channels = data_provider->ConsumeIntegral<int>();
50
2.67k
  int priority = data_provider->ConsumeIntegral<int>();
51
2.67k
  int type = data_provider->ConsumeIntegral<int>();
52
2.67k
  int rate = data_provider->ConsumeIntegral<int>();
53
54
2.67k
  return cras_floss_a2dp_codec_create(bps, channels, priority, type, rate);
55
2.67k
}
56
57
1.33k
void active_fm_create(FuzzedDataProvider* data_provider) {
58
1.33k
  int hci = data_provider->ConsumeIntegral<int>();
59
1.33k
  fl_media_init(hci);
60
1.33k
  active_fm = floss_media_get_active_fm();
61
1.33k
}
62
63
2.06k
std::string get_valid_addr(FuzzedDataProvider* data_provider) {
64
2.06k
  const int STR_LEN = 17;
65
2.06k
  char str[STR_LEN + 1] = {};
66
37.0k
  for (int i = 0; i < STR_LEN; i++) {
67
35.0k
    if ((i + 1) % 3 == 0) {
68
10.3k
      str[i] = ':';
69
24.7k
    } else {
70
24.7k
      snprintf(str + i, 2, "%X",
71
24.7k
               data_provider->ConsumeIntegralInRange<int>(0, 15));
72
24.7k
    }
73
35.0k
  }
74
2.06k
  return std::string(str);
75
2.06k
}
76
77
612
std::string get_random_addr(FuzzedDataProvider* data_provider) {
78
612
  return data_provider->ConsumeRandomLengthString(kMaxStringLength);
79
612
}
80
81
2.67k
void fuzzer_on_bluetooth_device_added(FuzzedDataProvider* data_provider) {
82
2.67k
  struct cras_fl_a2dp_codec_config* codecs = codecs_create(data_provider);
83
84
2.67k
  int32_t hfp_cap = data_provider->ConsumeIntegral<int32_t>();
85
2.67k
  bool abs_vol_supported = data_provider->ConsumeBool();
86
87
2.67k
  if (data_provider->ConsumeBool()) {
88
2.06k
    addr = get_valid_addr(data_provider);
89
2.06k
  } else {
90
612
    addr = get_random_addr(data_provider);
91
612
  }
92
2.67k
  std::string name = data_provider->ConsumeRandomLengthString(kMaxStringLength);
93
94
2.67k
  handle_on_bluetooth_device_added(active_fm, addr.c_str(), name.c_str(),
95
2.67k
                                   codecs, hfp_cap, abs_vol_supported);
96
2.67k
  free(codecs);
97
2.67k
  codecs = NULL;
98
2.67k
}
99
100
1.33k
void fuzzer_on_bluetooth_device_removed() {
101
1.33k
  handle_on_bluetooth_device_removed(active_fm, addr.c_str());
102
1.33k
}
103
104
void fuzzer_on_absolute_volume_supported_changed(
105
1.33k
    FuzzedDataProvider* data_provider) {
106
1.33k
  bool abs_vol_supported = data_provider->ConsumeBool();
107
1.33k
  handle_on_absolute_volume_supported_changed(active_fm, abs_vol_supported);
108
1.33k
}
109
110
1.33k
void fuzzer_on_absolute_volume_changed(FuzzedDataProvider* data_provider) {
111
1.33k
  uint8_t volume = data_provider->ConsumeIntegral<uint8_t>();
112
1.33k
  handle_on_absolute_volume_changed(active_fm, volume);
113
1.33k
}
114
115
2.67k
void fuzzer_on_hfp_volume_changed(FuzzedDataProvider* data_provider) {
116
2.67k
  uint8_t volume = data_provider->ConsumeIntegral<uint8_t>();
117
2.67k
  handle_on_hfp_volume_changed(active_fm, addr.c_str(), volume);
118
2.67k
}
119
120
0
void fuzzer_on_hfp_audio_disconnected(FuzzedDataProvider* data_provider) {
121
0
  handle_on_hfp_audio_disconnected(active_fm, addr.c_str());
122
0
}
123
124
1.33k
void fuzzer_rclient_buffer_on_client(FuzzedDataProvider* data_provider) {
125
1.33k
  if (data_provider->remaining_bytes() < kMinRclientMsgSize) {
126
147
    return;
127
147
  }
128
1.18k
  int fds[1] = {0};
129
1.18k
  int num_fds = data_provider->ConsumeIntegralInRange(0, 1);
130
1.18k
  std::vector<uint8_t> msg_byte =
131
1.18k
      data_provider->ConsumeBytes<uint8_t>(sizeof(struct cras_connect_message));
132
1.18k
  struct cras_server_message* msg =
133
1.18k
      (struct cras_server_message*)msg_byte.data();
134
1.18k
  msg->length = msg_byte.size();
135
1.18k
  cras_rclient_buffer_from_client(client, (const uint8_t*)msg, msg->length, fds,
136
1.18k
                                  num_fds);
137
1.18k
}
138
139
5.94k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
140
5.94k
  client = cras_rclient_create(0, 0, CRAS_CONTROL);
141
5.94k
  if (size < kMinFuzzDataSize) {
142
3.76k
    handle_on_bluetooth_device_added(NULL, NULL, NULL, NULL, 0, 0);
143
3.76k
    cras_rclient_buffer_from_client(client, data, size, NULL, 0);
144
3.76k
  } else {
145
2.18k
    FuzzedDataProvider data_provider(data, size);
146
2.18k
    active_fm_create(&data_provider);
147
2.18k
    fuzzer_on_bluetooth_device_added(&data_provider);
148
2.18k
    fuzzer_on_bluetooth_device_added(&data_provider);
149
2.18k
    fuzzer_on_absolute_volume_supported_changed(&data_provider);
150
2.18k
    fuzzer_on_absolute_volume_changed(&data_provider);
151
2.18k
    fuzzer_on_hfp_volume_changed(&data_provider);
152
2.18k
    fuzzer_rclient_buffer_on_client(&data_provider);
153
2.18k
    fuzzer_on_bluetooth_device_removed();
154
2.18k
    fuzzer_on_hfp_volume_changed(&data_provider);
155
2.18k
    cras_alert_process_all_pending_alerts();
156
2.18k
    fl_media_destroy(&active_fm);
157
2.18k
  }
158
5.94k
  cras_rclient_destroy(client);
159
5.94k
  return 0;
160
5.94k
}
161
162
2
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
163
2
  char* shm_name;
164
2
  if (asprintf(&shm_name, "/cras-%d", getpid()) < 0) {
165
0
    exit(-ENOMEM);
166
0
  }
167
2
  struct cras_server_state* exp_state =
168
2
      (struct cras_server_state*)calloc(1, sizeof(*exp_state));
169
170
2
  int rw_shm_fd = open("/dev/null", O_RDWR);
171
2
  int ro_shm_fd = open("/dev/null", O_RDONLY);
172
173
2
  cras_system_state_init("/tmp", shm_name, rw_shm_fd, ro_shm_fd, exp_state,
174
2
                         sizeof(*exp_state));
175
2
  free(shm_name);
176
177
2
  cras_observer_server_init();
178
2
  btlog = cras_bt_event_log_init();
179
180
2
  cras_mix_init();
181
2
  cras_stream_apm_init("/etc/cras");
182
2
  cras_iodev_list_init();
183
  /* For cros fuzz, emerge adhd with USE=fuzzer will copy dsp.ini.sample to
184
   * etc/cras. For OSS-Fuzz the Dockerfile will be responsible for copying the
185
   * file. This shouldn't crash CRAS even if the dsp file does not exist. */
186
2
  cras_dsp_init("/etc/cras/dsp.ini.sample");
187
2
  return 0;
188
2
}