Skip to content

Commit

Permalink
Added tests for vmlinux version & config
Browse files Browse the repository at this point in the history
  • Loading branch information
rockrid3r committed Mar 21, 2024
1 parent 7cdb3e3 commit a637b5c
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 26 deletions.
3 changes: 1 addition & 2 deletions librz/core/cconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ static bool cb_vmlinux(void *_core, void *_node) {
}

core->analysis->vmlinux_config = rz_vmlinux_config_new();
core->analysis->vmlinux_config->config_tbl = rz_vmlinux_config_table_new();

const char *vmlinux_config = rz_config_get(core->config, "bin.elf.vmlinux.config");
const char *vmlinux_version = rz_config_get(core->config, "bin.elf.vmlinux.version");
Expand All @@ -100,7 +99,7 @@ static bool cb_vmlinux(void *_core, void *_node) {
const char *apply_config_file = rz_config_get(core->config, "bin.elf.vmlinux.apply_config");

if (RZ_STR_ISNOTEMPTY(apply_config_file)) {
RZ_LOG_INFO("Parsingconfig file '%s'\n", apply_config_file);
RZ_LOG_INFO("Parsing config file '%s'...\n", apply_config_file);
vmlinux_parse_apply_config_file(apply_config_file, core->analysis->vmlinux_config->config_tbl);
}

Expand Down
49 changes: 34 additions & 15 deletions librz/core/vmlinux.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
#include <rz_core.h>
#include <rz_util/rz_str.h>
#include <rz_util/rz_assert.h>
#include "vmlinux.h"
#include <stdio.h>

static void add_config(RzVmlinuxConfigTable* config_tbl, char* config_name, char* config_value);

RZ_IPI bool vmlinux_parse_apply_config_file(const char* config_filepath, RzVmlinuxConfigTable* config_tbl) {
RZ_API bool vmlinux_parse_apply_config_file(const char* config_filepath, RzVmlinuxConfigTable* config_tbl) {
rz_return_val_if_fail(config_filepath && config_tbl, false);

FILE* f = fopen(config_filepath, "r");
if (!f) {
return false;
}

size_t line_size = 256;
char* line = malloc(line_size);
if (!line) {
return false;
}

int err = 0;
while (true) {
ssize_t read_sz = getline(&line, &line_size, f); // reallocs if not enough
Expand All @@ -23,16 +30,8 @@ RZ_IPI bool vmlinux_parse_apply_config_file(const char* config_filepath, RzVmlin

rz_str_trim(line);

char* config_name;
char* config_value;

if (line[0] == '#' || !line[0]) {
continue;
} else if (rz_str_split_by_first_dupstr(line, "=", true, &config_name, &config_value)) {
add_config(config_tbl, config_name, config_value);
} else {
if (!vmlinux_parse_apply_config_string(line, config_tbl)) {
RZ_LOG_WARN("Skipping line '%s'", line);
continue;
}
}
out:
Expand All @@ -41,10 +40,27 @@ RZ_IPI bool vmlinux_parse_apply_config_file(const char* config_filepath, RzVmlin
return !err;
}

RZ_API bool vmlinux_parse_apply_config_string(const char *config_str, RzVmlinuxConfigTable *config_tbl) {
rz_return_val_if_fail(config_str && config_tbl, false);

char* config_name;
char* config_value;

if (config_str[0] == '#' || !config_str[0]) {
return true;
} else if (rz_str_split_by_first_dupstr(config_str, "=", true, &config_name, &config_value)) {
add_config(config_tbl, config_name, config_value);
free(config_name);
free(config_value);
return true;
}
return false;
}

/**
* Numeric 90+
*/
RZ_IPI bool vmlinux_parse_version(const char* version_string, unsigned long version[3]) {
RZ_API bool vmlinux_parse_version(const char* version_string, unsigned long version[3]) {
RzList* version_list = rz_str_split_duplist_n(version_string, ".", 3, true);
RzListIter* it;
char* str;
Expand All @@ -65,11 +81,13 @@ RZ_IPI bool vmlinux_parse_version(const char* version_string, unsigned long vers
unsigned long numbr = strtoul(str, NULL, 10);
version[v] = numbr;
} else {
rz_list_free(version_list);
return false;
}

++v;
}
rz_list_free(version_list);
return true;
}

Expand Down Expand Up @@ -97,7 +115,7 @@ static void add_config(RzVmlinuxConfigTable* config_tbl, char* config_name, char
}


RZ_IPI RzVmlinuxConfigTable* rz_vmlinux_config_table_new() {
RZ_API RzVmlinuxConfigTable* rz_vmlinux_config_table_new() {
RzVmlinuxConfigTable* config_tbl = malloc(sizeof(RzVmlinuxConfigTable));
config_tbl->config_slab_freelist_random = VMLINUX_CONFIG_VALUE_N;
config_tbl->config_slab_freelist_hardened = VMLINUX_CONFIG_VALUE_N;
Expand All @@ -106,8 +124,9 @@ RZ_IPI RzVmlinuxConfigTable* rz_vmlinux_config_table_new() {
return config_tbl;
}

RZ_IPI RzVmlinuxConfig* rz_vmlinux_config_new() {
RZ_API RzVmlinuxConfig* rz_vmlinux_config_new() {
RzVmlinuxConfig* config = malloc(sizeof(RzVmlinuxConfig));
config->config_tbl = rz_vmlinux_config_table_new();
return config;
}

Expand Down Expand Up @@ -135,11 +154,11 @@ RZ_API int vmlinux_vercmp_with_str(unsigned long v1[3], const char* v2_str) {
}


RZ_IPI void rz_vmlinux_config_free(RzVmlinuxConfig* vmlinux_config) {
RZ_API void rz_vmlinux_config_free(RzVmlinuxConfig* vmlinux_config) {
rz_vmlinux_config_table_free(vmlinux_config->config_tbl);
free(vmlinux_config);
}

RZ_IPI void rz_vmlinux_config_table_free(RzVmlinuxConfigTable* config_tbl) {
RZ_API void rz_vmlinux_config_table_free(RzVmlinuxConfigTable* config_tbl) {
free(config_tbl);
}
13 changes: 7 additions & 6 deletions librz/include/vmlinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ typedef struct vmlinux_config {
unsigned long version[3];
} RzVmlinuxConfig;

RZ_IPI RzVmlinuxConfigTable* rz_vmlinux_config_table_new();
RZ_IPI RzVmlinuxConfig* rz_vmlinux_config_new();
RZ_IPI void rz_vmlinux_config_free(RzVmlinuxConfig* vmlinux_config);
RZ_IPI void rz_vmlinux_config_table_free(RzVmlinuxConfigTable* config_tbl);
RZ_IPI bool vmlinux_parse_apply_config_file(const char* config_filepath, RzVmlinuxConfigTable* config_tbl);
RZ_IPI bool vmlinux_parse_version(const char* version_string, unsigned long version[3]);
RZ_API RzVmlinuxConfigTable* rz_vmlinux_config_table_new();
RZ_API RzVmlinuxConfig* rz_vmlinux_config_new();
RZ_API void rz_vmlinux_config_free(RzVmlinuxConfig* vmlinux_config);
RZ_API void rz_vmlinux_config_table_free(RzVmlinuxConfigTable* config_tbl);
RZ_API bool vmlinux_parse_apply_config_file(const char* config_filepath, RzVmlinuxConfigTable* config_tbl);
RZ_API bool vmlinux_parse_apply_config_string(const char *config_str, RzVmlinuxConfigTable *config_tbl);
RZ_API bool vmlinux_parse_version(const char* version_string, unsigned long version[3]);
RZ_API int vmlinux_vercmp(unsigned long v1[3], unsigned long v2[3]);
RZ_API int vmlinux_vercmp_with_str(unsigned long v1[3], const char* v2_str);
7 changes: 6 additions & 1 deletion librz/util/str.c
Original file line number Diff line number Diff line change
Expand Up @@ -3535,14 +3535,19 @@ RZ_API RZ_OWN RzList /*<char *>*/ *rz_str_split_list_regex(RZ_NONNULL char *str,
}

/**
* \brief Split the string \p str on 2 parts according to the substring \p r . Result is stored in the \p first_half , \p second_half .
* \brief Split the string \p str on 2 parts according to the first occurence of the substring \p r . Result is stored in the \p first_half , \p second_half .
*
* \param str Input string to split
* \param c Delimiter string used to split \p str
* \param trim If true each half is trimmed after split
* \return true on success
*/
RZ_API RZ_OWN bool rz_str_split_by_first_dupstr(RZ_NONNULL const char *_str, RZ_NONNULL const char *r, bool trim, char** first_half, char** second_half) {
char *str = strdup(_str);
if (!str) {
return false;
}

char* e = strstr(str, r);

if (!e) {
Expand Down
32 changes: 30 additions & 2 deletions test/unit/test_vmlinux.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,45 @@
#include <vmlinux.h>
#include <stdbool.h>

int test_vmlinux_vercmp(void) {
static bool test_vmlinux_vercmp(void) {
unsigned long v1[3] = {6, 7, 1};
unsigned long v2[3] = {5, 17, 0};
mu_assert("v1 > v2", vmlinux_vercmp(v1, v2) > 0);

mu_assert("v1 > v2", vmlinux_vercmp(v1, v2) > 0);
mu_assert("v1 > v2_str", vmlinux_vercmp_with_str(v1, "5.17") > 0);

mu_end;
}

static bool test_vmlinux_config(void) {
RzVmlinuxConfig *vmlinux_config = rz_vmlinux_config_new();
RzVmlinuxConfigTable *config_tbl = vmlinux_config->config_tbl;
const char *config_lines[] = {
"CONFIG_SLAB_FREELIST_RANDOM=y",
"CONFIG_SLAB_FREELIST_HARDENED=n",
"# CONFIG_SLAB_FREELIST_HARDENED=y",
"CONFIG_STATIC_USERMODEHELPER=y",
"CONFIG_UNKNOWN=y",
};

size_t config_size = sizeof(config_lines) / sizeof(config_lines[0]);
for (size_t i = 0; i < config_size; ++i) {
// eprintf("%p, %p\n", config_lines[i], config_tbl);
vmlinux_parse_apply_config_string(config_lines[i], config_tbl);
}

mu_assert("Expected CONFIG_SLAB_FREELIST_RANDOM=y", config_tbl->config_slab_freelist_random);
mu_assert("Expected CONFIG_SLAB_FREELIST_HARDENED=n", !config_tbl->config_slab_freelist_hardened);

rz_vmlinux_config_free(vmlinux_config);

mu_end;
}


int all_tests(void) {
mu_run_test(test_vmlinux_vercmp);
mu_run_test(test_vmlinux_config);
return tests_passed != tests_run;
}

Expand Down

0 comments on commit a637b5c

Please sign in to comment.