Many open source projects have moved to using SPDX identifiers to specify license information, reducing the amount of boilerplate code in every source file. This patch replaces the bulk of SPDK .c, .cpp and Makefiles with the BSD-3-Clause identifier. Almost all of these files share the exact same license text, and this patch only modifies the files that contain the most common license text. There can be slight variations because the third clause contains company names - most say "Intel Corporation", but there are instances for Nvidia, Samsung, Eideticom and even "the copyright holder". Used a bash script to automate replacement of the license text with SPDX identifier which is checked into scripts/spdx.sh. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: Iaa88ab5e92ea471691dc298cfe41ebfb5d169780 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12904 Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Dong Yi <dongx.yi@intel.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com> Reviewed-by: <qun.wan@intel.com>
276 lines
5.7 KiB
C
276 lines
5.7 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright (c) Intel Corporation.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include "spdk/stdinc.h"
|
|
#include "spdk/env.h"
|
|
#include "spdk/file.h"
|
|
#include "spdk/base64.h"
|
|
#include "spdk/json.h"
|
|
|
|
#define DEFAULT_RUNTIME 30 /* seconds */
|
|
#define MAX_RUNTIME_S 86400 /* 24 hours */
|
|
#define IO_TIMEOUT_S 5
|
|
|
|
#define UNSIGNED_2BIT_MAX ((1 << 2) - 1)
|
|
#define UNSIGNED_4BIT_MAX ((1 << 4) - 1)
|
|
#define UNSIGNED_8BIT_MAX ((1 << 8) - 1)
|
|
|
|
typedef bool (*json_parse_fn)(void *ele, struct spdk_json_val *val, size_t num_vals);
|
|
|
|
static void
|
|
fuzz_fill_random_bytes(char *character_repr, size_t len, unsigned int *rand_seed)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
character_repr[i] = rand_r(rand_seed) % UINT8_MAX;
|
|
}
|
|
}
|
|
|
|
static uint64_t
|
|
fuzz_refresh_timeout(void)
|
|
{
|
|
uint64_t current_ticks;
|
|
uint64_t new_timeout_ticks;
|
|
|
|
current_ticks = spdk_get_ticks();
|
|
|
|
new_timeout_ticks = current_ticks + IO_TIMEOUT_S * spdk_get_ticks_hz();
|
|
assert(new_timeout_ticks > current_ticks);
|
|
|
|
return new_timeout_ticks;
|
|
}
|
|
|
|
static char *
|
|
fuzz_get_value_base_64_buffer(void *item, size_t len)
|
|
{
|
|
char *value_string;
|
|
size_t total_size;
|
|
int rc;
|
|
|
|
/* Null pointer */
|
|
total_size = spdk_base64_get_encoded_strlen(len) + 1;
|
|
|
|
value_string = calloc(1, total_size);
|
|
if (value_string == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
rc = spdk_base64_encode(value_string, item, len);
|
|
if (rc < 0) {
|
|
free(value_string);
|
|
return NULL;
|
|
}
|
|
|
|
return value_string;
|
|
}
|
|
|
|
static int
|
|
fuzz_get_base_64_buffer_value(void *item, size_t len, char *buf, size_t buf_len)
|
|
{
|
|
size_t size_of_data;
|
|
char *new_buf;
|
|
int rc;
|
|
|
|
new_buf = malloc(buf_len + 1);
|
|
if (new_buf == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
|
|
snprintf(new_buf, buf_len + 1, "%s", buf);
|
|
|
|
size_of_data = spdk_base64_get_decoded_len(buf_len);
|
|
|
|
if (size_of_data < len) {
|
|
free(new_buf);
|
|
return -EINVAL;
|
|
}
|
|
|
|
rc = spdk_base64_decode(item, &size_of_data, new_buf);
|
|
|
|
if (rc || size_of_data != len) {
|
|
free(new_buf);
|
|
return -EINVAL;
|
|
}
|
|
|
|
free(new_buf);
|
|
return 0;
|
|
}
|
|
|
|
static ssize_t
|
|
read_json_into_buffer(const char *filename, struct spdk_json_val **values, void **file_data)
|
|
{
|
|
FILE *file = fopen(filename, "r");
|
|
size_t file_data_size;
|
|
ssize_t num_json_values = 0, rc;
|
|
|
|
if (file == NULL) {
|
|
/* errno is set by fopen */
|
|
return 0;
|
|
}
|
|
|
|
*file_data = spdk_posix_file_load(file, &file_data_size);
|
|
if (*file_data == NULL) {
|
|
fclose(file);
|
|
return 0;
|
|
}
|
|
|
|
fclose(file);
|
|
|
|
num_json_values = spdk_json_parse(*file_data, file_data_size, NULL, 0, NULL,
|
|
SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
|
|
|
|
*values = calloc(num_json_values, sizeof(**values));
|
|
if (values == NULL) {
|
|
free(*file_data);
|
|
*file_data = NULL;
|
|
return 0;
|
|
}
|
|
|
|
rc = spdk_json_parse(*file_data, file_data_size, *values, num_json_values, NULL,
|
|
SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
|
|
if (num_json_values != rc) {
|
|
free(*values);
|
|
*values = NULL;
|
|
free(*file_data);
|
|
*file_data = NULL;
|
|
return 0;
|
|
}
|
|
|
|
return num_json_values;
|
|
}
|
|
|
|
static size_t
|
|
double_arr_size(void **buffer, size_t num_ele, size_t ele_size)
|
|
{
|
|
void *tmp;
|
|
size_t new_num_ele, allocation_size;
|
|
|
|
if (num_ele > SIZE_MAX / 2) {
|
|
return 0;
|
|
}
|
|
|
|
new_num_ele = num_ele * 2;
|
|
|
|
if (new_num_ele > SIZE_MAX / ele_size) {
|
|
return 0;
|
|
}
|
|
|
|
allocation_size = new_num_ele * ele_size;
|
|
|
|
tmp = realloc(*buffer, allocation_size);
|
|
if (tmp != NULL) {
|
|
*buffer = tmp;
|
|
return new_num_ele;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static uint64_t
|
|
fuzz_parse_args_into_array(const char *file, void **arr, size_t ele_size, const char *obj_name,
|
|
json_parse_fn cb_fn)
|
|
{
|
|
ssize_t i, num_json_values;
|
|
struct spdk_json_val *values = NULL, *values_head = NULL, *obj_start;
|
|
void *file_data = NULL;;
|
|
char *arr_idx_pointer;
|
|
size_t num_arr_elements, arr_elements_used, values_in_obj;
|
|
bool rc;
|
|
|
|
num_json_values = read_json_into_buffer(file, &values_head, &file_data);
|
|
values = values_head;
|
|
if (num_json_values == 0 || values == NULL) {
|
|
if (file_data != NULL) {
|
|
free(file_data);
|
|
}
|
|
fprintf(stderr, "The file provided does not exist or we were unable to parse it.\n");
|
|
return 0;
|
|
}
|
|
|
|
num_arr_elements = 10;
|
|
arr_elements_used = 0;
|
|
*arr = calloc(num_arr_elements, ele_size);
|
|
arr_idx_pointer = (char *)*arr;
|
|
if (arr_idx_pointer == NULL) {
|
|
free(values);
|
|
free(file_data);
|
|
return 0;
|
|
}
|
|
|
|
i = 0;
|
|
while (i < num_json_values) {
|
|
if (values->type != SPDK_JSON_VAL_NAME) {
|
|
i++;
|
|
values++;
|
|
continue;
|
|
}
|
|
|
|
if (!strncmp(values->start, obj_name, values->len)) {
|
|
i++;
|
|
values++;
|
|
assert(values->type == SPDK_JSON_VAL_OBJECT_BEGIN);
|
|
obj_start = values;
|
|
values_in_obj = spdk_json_val_len(obj_start);
|
|
values += values_in_obj;
|
|
i += values_in_obj;
|
|
|
|
rc = cb_fn((void *)arr_idx_pointer, obj_start, values_in_obj);
|
|
if (rc == false) {
|
|
fprintf(stderr, "failed to parse file after %zu elements.\n", arr_elements_used);
|
|
goto fail;
|
|
}
|
|
|
|
arr_idx_pointer += ele_size;
|
|
arr_elements_used++;
|
|
if (arr_elements_used == num_arr_elements) {
|
|
num_arr_elements = double_arr_size(arr, num_arr_elements, ele_size);
|
|
if (num_arr_elements == 0) {
|
|
fprintf(stderr, "failed to allocate enough space for all json elements in your file.\n");
|
|
goto fail;
|
|
} else {
|
|
/* reset the array element position in case the pointer changed. */
|
|
arr_idx_pointer = ((char *)*arr) + arr_elements_used * ele_size;
|
|
}
|
|
}
|
|
|
|
continue;
|
|
} else {
|
|
i++;
|
|
values++;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (arr_elements_used == 0) {
|
|
goto fail;
|
|
}
|
|
|
|
free(values_head);
|
|
free(file_data);
|
|
return arr_elements_used;
|
|
fail:
|
|
free(values_head);
|
|
free(file_data);
|
|
free(*arr);
|
|
*arr = NULL;
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
fuzz_parse_json_num(struct spdk_json_val *val, uint64_t max_val, uint64_t *val_ptr)
|
|
{
|
|
uint64_t tmp_val;
|
|
int rc;
|
|
|
|
rc = spdk_json_number_to_uint64(val, &tmp_val);
|
|
if (rc || tmp_val > max_val) {
|
|
return -EINVAL;
|
|
} else {
|
|
*val_ptr = tmp_val;
|
|
return 0;
|
|
}
|
|
}
|