Skip to content

Commit 6dffcae

Browse files
committed
- add current and previous TB in post block gen hooks
- possible to run the native qemu signal if a signal hook is set - expose some qemu internal functions - fix libafl format check exit on error - add format check to ci
1 parent 97bef50 commit 6dffcae

File tree

13 files changed

+148
-52
lines changed

13 files changed

+148
-52
lines changed

.github/workflows/build_and_test.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,7 @@ jobs:
1919
container: registry.gitlab.com/qemu-project/qemu/qemu/ubuntu2204:latest
2020
steps:
2121
- uses: actions/checkout@v4
22+
- name: Check LibAFL format
23+
run: ./scripts/libafl-format.sh check
2224
- name: Build QEMU
2325
run: mkdir -p build && cd build && ../configure --enable-werror --disable-docs --enable-fdt=system && make -j $(expr $(nproc) + 1)

accel/tcg/cpu-exec.c

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@
4242
#include "internal-common.h"
4343
#include "internal-target.h"
4444

45+
//// --- Begin LibAFL code ---
46+
#include "libafl/exit.h"
47+
#include "libafl/tcg.h"
48+
49+
#include "libafl/hooks/tcg/block.h"
50+
//// --- End LibAFL code ---
51+
4552
/* -icount align implementation. */
4653

4754
typedef struct SyncClocks {
@@ -286,6 +293,14 @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, vaddr pc,
286293
return tb;
287294
}
288295

296+
//// --- Begin LibAFL code ---
297+
TranslationBlock *libafl_tb_lookup(CPUState *cpu, vaddr pc,
298+
uint64_t cs_base, uint32_t flags,
299+
uint32_t cflags) {
300+
return tb_lookup(cpu, pc, cs_base, flags, cflags);
301+
}
302+
//// --- End LibAFL code ---
303+
289304
static void log_cpu_exec(vaddr pc, CPUState *cpu,
290305
const TranslationBlock *tb)
291306
{
@@ -674,6 +689,13 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
674689
return;
675690
}
676691

692+
//// --- Begin LibAFL code ---
693+
void libafl_tb_add_jump(TranslationBlock *tb, int n,
694+
TranslationBlock *tb_next) {
695+
tb_add_jump(tb, n, tb_next);
696+
}
697+
//// --- End LibAFL code ---
698+
677699
static inline bool cpu_handle_halt(CPUState *cpu)
678700
{
679701
#ifndef CONFIG_USER_ONLY
@@ -708,12 +730,6 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
708730
}
709731
}
710732

711-
//// --- Begin LibAFL code ---
712-
713-
#include "libafl/exit.h"
714-
715-
//// --- End LibAFL code ---
716-
717733
static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
718734
{
719735
//// --- Begin LibAFL code ---
@@ -1017,6 +1033,23 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
10171033

10181034
mmap_lock();
10191035
tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);
1036+
1037+
//// --- Begin LibAFL code ---
1038+
#ifndef CONFIG_USER_ONLY
1039+
/*
1040+
* We don't take care of direct jumps when address mapping
1041+
* changes in system emulation. So it's not safe to make a
1042+
* direct jump to a TB spanning two pages because the mapping
1043+
* for the second page can change.
1044+
*/
1045+
if (tb_page_addr1(tb) != -1) {
1046+
last_tb = NULL;
1047+
}
1048+
#endif
1049+
libafl_qemu_hook_block_post_run(tb, last_tb, pc, tb_exit);
1050+
1051+
//// --- End LibAFL code ---
1052+
10201053
mmap_unlock();
10211054

10221055
/*
@@ -1028,18 +1061,23 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
10281061
jc->array[h].pc = pc;
10291062
qatomic_set(&jc->array[h].tb, tb);
10301063
}
1031-
1064+
//// --- Begin LibAFL code ---
1065+
else {
1066+
//// --- End LibAFL code ---
10321067
#ifndef CONFIG_USER_ONLY
1033-
/*
1034-
* We don't take care of direct jumps when address mapping
1035-
* changes in system emulation. So it's not safe to make a
1036-
* direct jump to a TB spanning two pages because the mapping
1037-
* for the second page can change.
1038-
*/
1039-
if (tb_page_addr1(tb) != -1) {
1040-
last_tb = NULL;
1041-
}
1068+
/*
1069+
* We don't take care of direct jumps when address mapping
1070+
* changes in system emulation. So it's not safe to make a
1071+
* direct jump to a TB spanning two pages because the mapping
1072+
* for the second page can change.
1073+
*/
1074+
if (tb_page_addr1(tb) != -1) {
1075+
last_tb = NULL;
1076+
}
10421077
#endif
1078+
//// --- Begin LibAFL code ---
1079+
}
1080+
//// --- End LibAFL code ---
10431081

10441082
//// --- Begin LibAFL code ---
10451083

accel/tcg/translate-all.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -715,12 +715,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
715715
}
716716
tb->tc.size = gen_code_size;
717717

718-
//// --- Begin LibAFL code ---
719-
720-
libafl_qemu_hook_block_post_run(tb, pc);
721-
722-
//// --- End LibAFL code ---
723-
724718
/*
725719
* For CF_PCREL, attribute all executions of the generated code
726720
* to its first mapping.

include/libafl/hooks/tcg/block.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
typedef uint64_t (*libafl_block_pre_gen_cb)(uint64_t data, target_ulong pc);
1414
typedef void (*libafl_block_post_gen_cb)(uint64_t data, target_ulong pc,
15-
target_ulong block_length);
15+
target_ulong block_length, TranslationBlock* tb, TranslationBlock* last_tb, int tb_exit);
1616

1717
typedef void (*libafl_block_exec_cb)(uint64_t data, uint64_t id);
1818

@@ -47,4 +47,4 @@ bool libafl_qemu_block_hook_set_jit(
4747
int libafl_qemu_remove_block_hook(size_t num, int invalidate);
4848

4949
void libafl_qemu_hook_block_pre_run(target_ulong pc);
50-
void libafl_qemu_hook_block_post_run(TranslationBlock* tb, vaddr pc);
50+
void libafl_qemu_hook_block_post_run(TranslationBlock* tb, TranslationBlock* last_tb, vaddr pc, int tb_exit);

include/libafl/tcg.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,14 @@
88

99
void tcg_gen_callN(void* func, TCGHelperInfo* info, TCGTemp* ret,
1010
TCGTemp** args);
11+
12+
TranslationBlock *libafl_tb_lookup(CPUState *cpu, vaddr pc,
13+
uint64_t cs_base, uint32_t flags,
14+
uint32_t cflags);
15+
16+
TranslationBlock *libafl_tb_gen_code(CPUState *cpu, vaddr pc,
17+
uint64_t cs_base, uint32_t flags,
18+
int cflags);
19+
20+
void libafl_tb_add_jump(TranslationBlock *tb, int n,
21+
TranslationBlock *tb_next);

include/libafl/user.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
#include "exec/cpu-defs.h"
88

9+
typedef void(*libafl_qemu_on_signal_hdlr)(int target_sig);
10+
11+
extern libafl_qemu_on_signal_hdlr libafl_signal_hdlr;
12+
913
struct libafl_mapinfo {
1014
target_ulong start;
1115
target_ulong end;
@@ -39,6 +43,8 @@ IntervalTreeNode* libafl_maps_first(IntervalTreeRoot* map_info);
3943
IntervalTreeNode* libafl_maps_next(IntervalTreeNode* pageflags_maps_node,
4044
IntervalTreeRoot* proc_maps_node,
4145
struct libafl_mapinfo* ret);
46+
bool libafl_is_valid_addr(target_ulong addr);
47+
4248

4349
uint64_t libafl_load_addr(void);
4450
struct image_info* libafl_get_image_info(void);
@@ -52,6 +58,8 @@ int _libafl_qemu_user_init(int argc, char** argv, char** envp);
5258
bool libafl_get_return_on_crash(void);
5359
void libafl_set_return_on_crash(bool return_on_crash);
5460

61+
void libafl_set_on_signal_handler(libafl_qemu_on_signal_hdlr hdlr);
62+
5563
#ifdef AS_LIB
5664
void libafl_qemu_init(int argc, char** argv);
5765
#endif

libafl/hooks/tcg/block.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ bool libafl_qemu_block_hook_set_jit(size_t num, libafl_block_jit_cb jit_cb)
5252
return false;
5353
}
5454

55-
void libafl_qemu_hook_block_post_run(TranslationBlock* tb, vaddr pc)
55+
void libafl_qemu_hook_block_post_run(TranslationBlock* tb, TranslationBlock* last_tb, vaddr pc, int tb_exit)
5656
{
5757
struct libafl_block_hook* hook = libafl_block_hooks;
5858
while (hook) {
5959
if (hook->post_gen_cb)
60-
hook->post_gen_cb(hook->data, pc, tb->size);
60+
hook->post_gen_cb(hook->data, pc, tb->size, tb, last_tb, tb_exit);
6161
hook = hook->next;
6262
}
6363
}

libafl/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ specific_ss.add(files(
55
'jit.c',
66
'utils.c',
77
'gdb.c',
8+
'tcg.c',
89

910
# TCG-related hooks
1011
'hooks/tcg/backdoor.c',

libafl/tcg.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "libafl/tcg.h"
2+
3+
#include "exec/exec-all.h"
4+
#include "accel/tcg/internal-common.h"
5+
6+
TranslationBlock *libafl_tb_gen_code(CPUState *cpu, vaddr pc,
7+
uint64_t cs_base, uint32_t flags,
8+
int cflags)
9+
{
10+
mmap_lock();
11+
TranslationBlock* tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);
12+
mmap_unlock();
13+
14+
return tb;
15+
}
16+

libafl/user.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "qemu/osdep.h"
22
#include "qemu.h"
33
#include "loader.h"
4+
#include "exec/exec-all.h"
45

56
#include "libafl/user.h"
67

@@ -14,6 +15,8 @@ static struct libafl_qemu_sig_ctx libafl_qemu_sig_ctx = {0};
1415
// if false, target crahes will raise the appropriate signal.
1516
static bool libafl_return_on_crash = false;
1617

18+
libafl_qemu_on_signal_hdlr libafl_signal_hdlr = NULL;
19+
1720
void host_signal_handler(int host_sig, siginfo_t* info, void* puc);
1821

1922
void libafl_qemu_native_signal_handler(int host_sig, siginfo_t* info, void* puc)
@@ -65,6 +68,10 @@ void libafl_set_return_on_crash(bool return_on_crash)
6568

6669
bool libafl_get_return_on_crash(void) { return libafl_return_on_crash; }
6770

71+
void libafl_set_on_signal_handler(libafl_qemu_on_signal_hdlr hdlr) {
72+
libafl_signal_hdlr = hdlr;
73+
}
74+
6875
#ifdef AS_LIB
6976
void libafl_qemu_init(int argc, char** argv)
7077
{

0 commit comments

Comments
 (0)