Spdk/test/app/fuzz/common/fuzz_common.h
Jim Harris 488570ebd4 Replace most BSD 3-clause license text with SPDX identifier.
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>
2022-06-09 07:35:12 +00:00

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;
}
}