Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux rise in rizin: SLUB dumping, Kernel build configuration #4306

Open
wants to merge 15 commits into
base: dev
Choose a base branch
from

Conversation

rockrid3r
Copy link
Contributor

@rockrid3r rockrid3r commented Feb 28, 2024

DO NOT MERGE IT'S STILL UNTESTED

Addresses #4257

SLUB dumping

  • Dumping of lockless freelist
  • Dumping of other freelists: regular(locking), partial, node freelist
  • Handle different kernel version & .config configuration
  • Add integration tests(is not suitable)

Vmlinux(TODO: Separate PR)

  • Add support to rebase kernel binary (KASLR)
  • Add unit tests

Kernel version handling

  • Use 6.7 kernel as default kernel version
  • Add flag to change kernel version: -e linux.version=5.6.11
  • Add rizin shell command to change kernel version.
  • Add tests

Kernel configuration handling

  • Add defconfig configuration file. It will contain all the default flags used while building kernel.
    It will be the presumed kernel configuration if user does not supply more. (User should set it up in ~/.config/rizin/defconfig)
  • Add CLI flag to support user-supplied kernel build configuration flags. For example, this:
rizin vmlinux --add-vmlinux-flag CONFIG_FREELIST_RANDOM=y

should open vmlinux file and handle the fact that kernel was built with configuration defconfig + CONFIG_FREELIST_RANDOM=y

  • Add rizin shell command user-supplied configuration: > set_config CONFIG_FREELIST_RANDOM=y (same as before, but in shell)
  • Accept user-supplied config file. For example, this:
rizin vmlinux -e linux.config=.config

implies that rizing will use .config instead of defconfig.

  • Add unit tests & integration tests

Basic checklist

  • I've read the guidelines for contributing to this repository
  • I made sure to follow the project's coding style
  • I've documented or updated the documentation of every function and struct this PR changes. If not so I've explained why.
  • I've added tests that prove my fix is effective or that my feature works (if possible)
  • I've updated the rizin book with the relevant information (if needed)

@rockrid3r
Copy link
Contributor Author

The PR is very far from over.

  • Buggy.
  • Has hardcoded member offsets.
  • Does not process kernel build configuration .config
  • Does not reflect Linux Kernel version
  • etc.

Will add todo later.
All comments are appreciated.

Comment on lines 11 to 34
#define call_handler(fun, ...) \
{ \
if (core->rasm->bits == 64) { \
return fun##_64(core, ##__VA_ARGS__); \
} else { \
return fun##_32(core, ##__VA_ARGS__); \
} \
}

RZ_IPI RzCmdStatus rz_cmd_debug_slub_dump_freelist_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *output_state) {
call_handler(rz_cmd_debug_slub_dump_freelist_handler, argc, argv, output_state);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm wrong but can't we just do the following?

Suggested change
#define call_handler(fun, ...) \
{ \
if (core->rasm->bits == 64) { \
return fun##_64(core, ##__VA_ARGS__); \
} else { \
return fun##_32(core, ##__VA_ARGS__); \
} \
}
RZ_IPI RzCmdStatus rz_cmd_debug_slub_dump_freelist_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *output_state) {
call_handler(rz_cmd_debug_slub_dump_freelist_handler, argc, argv, output_state);
}
RZ_IPI RzCmdStatus rz_cmd_debug_slub_dump_freelist_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *output_state) {
if (core->rasm->bits == 64) {
return rz_cmd_debug_slub_dump_freelist_handler_64(core, argc, argv, output_state);
} else {
return rz_cmd_debug_slub_dump_freelist_handler_32(core, argc, argv, output_state);
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add more functions. Macro will come in handy.
See librz/core/cmd/cmd_linux_heap_glibc.c

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these dwarf changes related to the linux heap changes?

Copy link
Contributor Author

@rockrid3r rockrid3r Feb 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, all the dwarf changes are for the sake of debugging the functionality.
I will remove them as soon as I am finished.

It speeds up rizin startup: takes 1 minute instead of 10+.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can, please split them in a separate PR that we can merge sooner then! It would be great to have such an improvement :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But only if it's general enough, currently it just skips everything except specific file. cc @imbillow

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ret2libc of course it's not a problem for me. But you probably don't want to have it.
It's not an optimization. @XVilka is right, it just skips everything.

@ret2libc
Copy link
Member

Thanks @rockrid3r ! Please also add a short description of what you are trying to achieve so people reviewing know immediately and a better title for the PR

@rockrid3r rockrid3r changed the title basic functionality SLUB dumping: basic functionality Feb 28, 2024
@rockrid3r
Copy link
Contributor Author

Thanks @rockrid3r ! Please also add a short description of what you are trying to achieve so people reviewing know immediately and a better title for the PR

My bad. I've pinned the issue link and changed PR title.

@rockrid3r rockrid3r changed the title SLUB dumping: basic functionality Linux rise in rizin: SLUB dumping, Kernel build configuration Feb 28, 2024
@github-actions github-actions bot added API and removed API labels Feb 28, 2024
@rockrid3r
Copy link
Contributor Author

Currently PR is in much better state. It's almost ready for merge.

  • Code is clean. No debug output.
  • Uses struct offsets from dwarf (not hardcoded)
  • Does processes kernel configuration
  • Does processes kernel version

Only tests are left.

Comment on lines 95 to 96
RZ_LOG_INFO("Parsing config file '%s'...\n", vmlinux_config);
vmlinux_parse_apply_config_file(vmlinux_config, core->analysis->vmlinux_config->config_tbl);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe before parsing, you should check if the string is empty and if the file exists.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello. I am verifying it inside the function vmlinux_parse_apply_config_file


if (RZ_STR_ISNOTEMPTY(apply_config_file)) {
printf("Parsing apply_config file '%s'\n", apply_config_file);
RZ_LOG_INFO("Parsingconfig file '%s'\n", apply_config_file);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
RZ_LOG_INFO("Parsingconfig file '%s'\n", apply_config_file);
RZ_LOG_INFO("Parsing config file '%s'\n", apply_config_file);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks

@rockrid3r rockrid3r requested a review from wargio March 21, 2024 11:41
@rockrid3r
Copy link
Contributor Author

I've added basic tests for version handler and configuration handler

@XVilka
Copy link
Member

XVilka commented Mar 21, 2024

I've added basic tests for version handler and configuration handler

There are merge conflicts, please rebase and solve them.

Copy link
Member

@XVilka XVilka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wargio @thestr4ng3r @ret2libc @Rot127 please take a look too, mostly at where things are located architecturally.

#include <stdbool.h>

static bool test_vmlinux_vercmp(void) {
unsigned long v1[3] = {6, 7, 1};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken indentation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ran clang-format

@@ -0,0 +1,29 @@
#pragma once
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. SPDX
  2. Doxygen comments for added structures and the purpose of this file

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't use #pragma once but use proper #ifndef XXX #define XXX also add the c++ guards.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added doxygen & spdx. usnig #ifndef now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wargio could you please elaborate more on c++ guards? what should be added?

@@ -535,6 +537,7 @@ typedef struct rz_analysis_t {
RzAnalysisDebugInfo *debug_info; ///< store all debug info parsed from DWARF, etc..
ut64 cmpval; ///< last compare value for jump table.
ut64 lea_jmptbl_ip; ///< jump table x86 lea ip
RzVmlinuxConfig* vmlinux_config;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not particularly happy about adding the vmlinux config directly in the RzAnalysis; honestly, it looks out of place. @wargio @ret2libc @Rot127 @thestr4ng3r any ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proper way would be to have it in it's own plugin IMHO. Because the logic is very much contained. But it is good how it is currently. Wouldn't know a place where the config fits else.
Added it #4334 as code which should be move to it's own plugin after refactoring. Please remove it if you disagree.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if this should be a bin+io plugin with, like we have for dmp


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

RZ_API bool vmlinux_parse_apply_config_file(const char* config_filepath, RzVmlinuxConfigTable* config_tbl) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doxygen for every new or changed RZ_API function except obvious ones like _free()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added doxygen.

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

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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you add assert, please also add attributes like RZ_NONNULL

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also add rz_ prefix for any new functionality that is RZ_API

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added both prefix and NONNULL

free(vmlinux_config);
}

RZ_API void rz_vmlinux_config_table_free(RzVmlinuxConfigTable* config_tbl) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RZ_NULLABLE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@@ -0,0 +1,33 @@
#include <rz_core.h>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SPDX and Doxygen for file description

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added.

@@ -0,0 +1,1060 @@
#include <rz_core.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SPDX

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@@ -0,0 +1,55 @@
# SPDX-FileCopyrightText: 2021 RizinOrg <[email protected]>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2024

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok.

@@ -0,0 +1,34 @@
// SPDX-FileCopyrightText: 2021 Pulak Malhotra <[email protected]>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong SPDX, put yours

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks.

@@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: 2017 Fangrui Song <[email protected]>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please put your copyright here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks.


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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, remove debug code when done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks.

Copy link
Member

@Rot127 Rot127 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked briefly. And in general LGTM. Please though, resolve comments from @XVilka. Especially the doxygen is important.
If you find the time it would be nice, if you could quickly run the unittest with valgrind --leak-check=full.

@Rot127 Rot127 mentioned this pull request Mar 21, 2024
73 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants