-
Notifications
You must be signed in to change notification settings - Fork 82
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
[DO NOT MERGE] LLM-based crash triaging #252
Open
DonggeLiu
wants to merge
2
commits into
main
Choose a base branch
from
crash-triaging
base: main
Could not load branches
Branch not found: {{ refName }}
Could not load tags
Nothing to show
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
+309
−34
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DonggeLiu
added
the
Experiment-only
A PR only to run experiments, do not merge it to main.
label
May 7, 2024
Experiment based on the idea from #221 and more.
# Triaging runtime crash via LLM mentioned in [#221](#221) To reduce the workload of manually triaging runtime crash, we leverage LLM to identify the cause of crash. We pass fuzz target code and crash information to LLM, ask LLM with designed prompts,and save the reponse from LLM. The crash information contains stack trace and sanitizer output. We can also pass related project code to LLM in the future. ## Conditions to LLM triaging Currently, triaging runtime crash with LLM would be activated only when all the following conditions are met: - Build successfully. - Trigger crash. ## Input to LLM triaging To retrieve crash information from fuzz log, we add function `extract_crash_info` to class `SemanticCheckResult` in `experiment/fuzz_target_error.py` file. The retrieved information is stored in variable `crash_info` in class `RunResult`. The fuzz target code can be obtained from `result/output-ProjectName-FunctionName/fixed_targets` folder. ## Prompt design We require that the LLM: 1) definitively ascertain whether the crash is due to errors within the fuzz target or results from a vulnerability in the project under test; 2) deliver a thorough analysis of the findings. Two triage prompts, `triage_priming.txt` and `triage_problem.txt`, are appended to `prompts/template_xml` folder. Three functions, `build_triage_prompt`, `_format_triage_priming`, and `_format_triage_problem`, are added to `llm_toolkit/prompt_builder.py` file. The generated triage prompt would be saved in `result/output-ProjectName-FunctionName/fixed_targets/TargetName-triage` folder. Below is a generated prompt example: ```plaintext [{"role": "system", "content": "Given the following crash report and fuzz target, investigate the cause of the crash.\n"}, {"role": "user", "content": "Below is the crash report:\n<log>\n=================================================================\r\n\u001b[1m\u001b[31m==13==ERROR: AddressSanitizer: SEGV on unknown address 0x0000000003a7 (pc 0x000000572ba3 bp 0x7ffd25f0ba10 sp 0x7ffd25f0b970 T0)\r\n\u001b[1m\u001b[0m==13==The signal is caused by a READ memory access.\r\n==13==Hint: address points to the zero page.\r\nSCARINESS: 10 (null-deref)\r\n #0 0x572ba3 in finalizeTable /src/liblouis/liblouis/compileTranslationTable.c:4377:13\r\n #1 0x570e1c in _lou_getTranslationTable /src/liblouis/liblouis/compileTranslationTable.c:5059:8\r\n #2 0x56c574 in LLVMFuzzerTestOneInput /src/liblouis/tests/fuzzing/table_fuzzer.cc:11:50\r\n #3 0x43de33 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15\r\n #4 0x43d61a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:514:3\r\n #5 0x43ece9 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:757:19\r\n #6 0x43f9b5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, std::__Fuzzer::allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:895:5\r\n #7 0x42ed1f in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:912:6\r\n #8 0x458372 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10\r\n #9 0x7f72da84a082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 87b331c034a6458c64ce09c03939e947212e18ce)\r\n #10 0x41f75d in _start (/out/table_fuzzer+0x41f75d)\r\n\r\nDEDUP_TOKEN: finalizeTable--_lou_getTranslationTable--LLVMFuzzerTestOneInput\r\nAddressSanitizer can not provide additional info.\r\nSUMMARY: AddressSanitizer: SEGV /src/liblouis/liblouis/compileTranslationTable.c:4377:13 in finalizeTable\r\n==13==ABORTING\r\nMS: 3 CMP-ChangeByte-InsertRepeatedBytes- DE: \"\\000\\000\\000\\001\"-; base unit: 9fe132914f92e1ad968c7b50f9c606d3922e86c6\r\n0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x23,0x20,0x5d,0x6b,0x6f,0x69,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x6f,0x4c,0x65,\r\n\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000# ]koi\\000\\000\\000\\001\\000\\000\\000oLe\r\nartifact_prefix='./'; Test unit written to ./crash-578f79fcf8db7fb291a77fb9c20abf8c01eff949\r\nBase64: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMgXWtvaQAAAAEAAABvTGU=\r\nstat::number_of_executed_units: 938\r\nstat::average_exec_per_sec: 0\r\nstat::new_units_added: 57\r\nstat::slowest_unit_time_sec: 0\r\nstat::peak_rss_mb: 46\r\n\n</log>\n\nBelow is the fuzz target:\n<code>\n#include <fuzzer/FuzzedDataProvider.h>\n#include <liblouis/internal.h>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {\n FuzzedDataProvider stream(data, size);\n\n // Consume a random length string\n std::string table_name = stream.ConsumeRandomLengthString();\n\n // Call the _lou_getTranslationTable function\n const TranslationTableHeader *table_header = _lou_getTranslationTable(table_name.c_str());\n\n // Perform some operations with the table_header if needed\n // For example, checking if the table_header is not NULL\n if (table_header != nullptr) {\n // Do something with the table_header\n }\n\n // Return 0 to indicate successful execution\n return 0;\n}\n</code>\n\nTriage the crash:\nFirstly, you must clearly determine whether the crash is caused by errors within the fuzz target, such as incorrect function usage, improper parameter initializations, missing setup steps, etc., or if it stems from a vulnerability in the project under test.\nSecondly, you are required to provide a comprehensive analysis of your findings.\n<solution>"}] ``` ## LLM triaging One function, `triage_crash`, is added to `experiment/evaluator.py` file. The core component of LLM triage, `crash_triage.py`, is appended to `llm_toolkit` folder. `crash_triage.py` mainly contains functions `llm_triage` and `apply_llm_triage`. ## Response from LLM triaging One function, `parse_triage_response`, is appended to `llm_toolkit/output_parser.py` file. The generated triage response from LLM would be saved in `result/output-ProjectName-FunctionName/fixed_targets/TargetName-triage` folder. Below is a reponse example: ```plaintext ### Triage Analysis: 1. **Crash Cause:** The crash occurred in the `finalizeTable` function at line 4377 of `compileTranslationTable.c`. The crash is a segmentation fault (SEGV) caused by a READ memory access at an unknown address. 2. **Fuzz Target Analysis:** - The fuzz target reads input data using `FuzzedDataProvider` and extracts a random length string as `table_name`. - It then calls the `_lou_getTranslationTable` function with `table_name` as input. - The crash happens during the execution of the fuzz target, specifically within the `_lou_getTranslationTable` function. 3. **Root Cause Analysis:** - The crash is likely due to a bug in the `_lou_getTranslationTable` function or its interaction with the provided `table_name`. - The fuzz target does not seem to have any obvious issues that could directly cause a crash, such as invalid memory accesses or incorrect function usage. 4. **Next Steps:** - To investigate further, you need to analyze the implementation of the `_lou_getTranslationTable` function in the `compileTranslationTable.c` file. - Look for potential issues such as NULL pointer dereferences, out-of-bounds memory accesses, or incorrect handling of input data. - Consider running the fuzz target with different inputs to see if the crash is consistently reproducible. - Use debugging tools like AddressSanitizer, Valgrind, or GDB to pinpoint the exact cause of the crash within the `_lou_getTranslationTable` function. 5. **Recommendations:** - Review the implementation of `_lou_getTranslationTable` function for any potential vulnerabilities. - Validate input data handling within the function to ensure it can handle all possible inputs gracefully. - Test the function with various inputs, including edge cases, to uncover any hidden issues. - Consider adding additional checks and error handling mechanisms to prevent crashes in case of unexpected input scenarios. 6. **Conclusion:** - The crash is most likely caused by an issue within the `_lou_getTranslationTable` function or its interaction with the provided input data. - Further investigation into the function's implementation and input handling is necessary to identify and fix the root cause of the crash. ``` ## Additions within `results` folder `result/output-ProjectName-FunctionName/fixed_targets/TargetName-triage` folder is created to store the generated prompt file and trirage rawoutput from LLM. ## Additions within results report Triage report is appended to results report web. We add a column `Triage` under `Run logs` to store triage reports. One function, `get_triage`, is added to `report/web.py` file. --------- Signed-off-by: David Korczynski <david@adalogics.com> Co-authored-by: Dongge Liu <donggeliu@google.com> Co-authored-by: DavidKorczynski <david@adalogics.com>
/gcbrun exp -n dg |
@fdt622 the experiment is running at here. |
No, I do not have the access. |
/gcbrun exp -n dg -f |
Not sure why the previous exp did not launch successfully, retrying ... |
/gcbrun exp -n dg -f |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Experiment based on the idea from #221 and more.