Skip to content

Commit d663793

Browse files
authored
Early return from libafl edge generation if no exec hooks (#85)
* bug with edges in systemmode, not fixed yet * timeout request only for systemmode
1 parent f58a685 commit d663793

File tree

8 files changed

+68
-26
lines changed

8 files changed

+68
-26
lines changed

accel/tcg/cpu-exec.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,13 +1039,13 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
10391039

10401040
//// --- Begin LibAFL code ---
10411041

1042-
int has_libafl_edge = 0;
1042+
bool libafl_edge_generated = false;
10431043
TranslationBlock *edge;
10441044

10451045
/* See if we can patch the calling TB. */
10461046
if (last_tb) {
10471047
// tb_add_jump(last_tb, tb_exit, tb);
1048-
1048+
10491049
if (last_tb->jmp_reset_offset[1] != TB_JMP_OFFSET_INVALID) {
10501050
mmap_lock();
10511051
edge = libafl_gen_edge(cpu, last_tb->pc, pc, tb_exit, cs_base, flags, cflags);
@@ -1054,7 +1054,7 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
10541054
if (edge) {
10551055
tb_add_jump(last_tb, tb_exit, edge);
10561056
tb_add_jump(edge, 0, tb);
1057-
has_libafl_edge = 1;
1057+
libafl_edge_generated = true;
10581058
} else {
10591059
tb_add_jump(last_tb, tb_exit, tb);
10601060
}
@@ -1063,7 +1063,7 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
10631063
}
10641064
}
10651065

1066-
if (has_libafl_edge) {
1066+
if (libafl_edge_generated) {
10671067
// execute the edge to make sure to log it the first execution
10681068
// the edge will then jump to the translated block
10691069
cpu_loop_exec_tb(cpu, edge, pc, &last_tb, &tb_exit);

accel/tcg/translate-all.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,11 +378,20 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
378378
int64_t ti;
379379
void *host_pc;
380380

381+
// edge hooks generation callbacks
382+
// early check if it should be skipped or not
383+
bool no_exec_hook = libafl_qemu_hook_edge_gen(src_block, dst_block);
384+
if (no_exec_hook) {
385+
// no exec hooks to run for edges, not point in generating a TB
386+
return NULL;
387+
}
388+
381389
target_ulong pc = src_block ^ reverse_bits((target_ulong)exit_n);
382390

383391
assert_memory_lock();
384392
qemu_thread_jit_write();
385393

394+
// TODO: this (get_page_addr_code_hostp) is a bottleneck in systemmode, investigate why
386395
phys_pc = get_page_addr_code_hostp(env, src_block, &host_pc);
387396
phys_pc ^= reverse_bits((tb_page_addr_t)exit_n);
388397

@@ -401,11 +410,6 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
401410
}
402411
QEMU_BUILD_BUG_ON(CF_COUNT_MASK + 1 != TCG_MAX_INSNS);
403412

404-
// edge hooks generation callbacks
405-
bool no_exec_hook = libafl_qemu_hook_edge_gen(src_block, dst_block);
406-
if (no_exec_hook)
407-
return NULL;
408-
409413
buffer_overflow:
410414
assert_no_pages_locked();
411415
tb = tcg_tb_alloc(tcg_ctx);

include/libafl/exit.h

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ enum libafl_exit_reason_kind {
2121
INTERNAL = 0,
2222
BREAKPOINT = 1,
2323
SYNC_EXIT = 2,
24+
TIMEOUT = 3,
25+
};
26+
27+
// QEMU exited on its own for some reason.
28+
struct libafl_exit_reason_internal {
29+
ShutdownCause cause;
30+
int signal; // valid if cause == SHUTDOWN_CAUSE_HOST_SIGNAL
2431
};
2532

2633
// A breakpoint has been triggered.
@@ -29,23 +36,20 @@ struct libafl_exit_reason_breakpoint {
2936
};
3037

3138
// A synchronous exit has been triggered.
32-
struct libafl_exit_reason_sync_exit {
33-
};
39+
struct libafl_exit_reason_sync_exit {};
3440

35-
// QEMU exited on its own for some reason.
36-
struct libafl_exit_reason_internal {
37-
ShutdownCause cause;
38-
int signal; // valid if cause == SHUTDOWN_CAUSE_HOST_SIGNAL
39-
};
41+
// A timeout occured and we were asked to exit on timeout
42+
struct libafl_exit_reason_timeout {};
4043

4144
struct libafl_exit_reason {
4245
enum libafl_exit_reason_kind kind;
4346
CPUState* cpu; // CPU that triggered an exit.
4447
vaddr next_pc; // The PC that should be stored in the CPU when re-entering.
4548
union {
46-
struct libafl_exit_reason_internal internal;
47-
struct libafl_exit_reason_breakpoint breakpoint; // kind == BREAKPOINT
48-
struct libafl_exit_reason_sync_exit sync_exit; // kind == SYNC_EXIT
49+
struct libafl_exit_reason_internal internal; // kind == INTERNAL
50+
struct libafl_exit_reason_breakpoint breakpoint; // kind == BREAKPOINT
51+
struct libafl_exit_reason_sync_exit sync_exit; // kind == SYNC_EXIT
52+
struct libafl_exit_reason_timeout timeout; // kind == TIMEOUT
4953
} data;
5054
};
5155

@@ -59,6 +63,11 @@ void libafl_sync_exit_cpu(void);
5963

6064
void libafl_exit_request_internal(CPUState* cpu, uint64_t pc,
6165
ShutdownCause cause, int signal);
62-
void libafl_exit_request_sync_backdoor(CPUState* cpu, target_ulong pc);
6366
void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc);
67+
void libafl_exit_request_sync_backdoor(CPUState* cpu, target_ulong pc);
68+
69+
#ifndef CONFIG_USER_ONLY
70+
void libafl_exit_request_timeout(void);
71+
#endif
72+
6473
struct libafl_exit_reason* libafl_get_exit_reason(void);

libafl/exit.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static void prepare_qemu_exit(CPUState* cpu, target_ulong next_pc)
8181
qemu_system_debug_request();
8282
cpu->stopped = true; // TODO check if still needed
8383
#endif
84+
8485
// in usermode, this may be called from the syscall hook, thus already out
8586
// of the cpu_exec but still in the cpu_loop
8687
if (cpu->running) {
@@ -125,6 +126,17 @@ void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc)
125126
prepare_qemu_exit(cpu, pc);
126127
}
127128

129+
#ifndef CONFIG_USER_ONLY
130+
void libafl_exit_request_timeout(void)
131+
{
132+
expected_exit = true;
133+
last_exit_reason.kind = TIMEOUT;
134+
last_exit_reason.cpu = current_cpu;
135+
136+
qemu_system_debug_request();
137+
}
138+
#endif
139+
128140
void libafl_qemu_trigger_breakpoint(CPUState* cpu)
129141
{
130142
CPUClass* cc = CPU_GET_CLASS(cpu);

libafl/hooks/tcg/block.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,11 @@ void libafl_qemu_hook_block_run(target_ulong pc)
7171

7272
while (hook) {
7373
uint64_t cur_id = 0;
74-
if (hook->gen)
74+
75+
if (hook->gen) {
7576
cur_id = hook->gen(hook->data, pc);
77+
}
78+
7679
if (cur_id != (uint64_t)-1 && hook->helper_info.func) {
7780
TCGv_i64 tmp0 = tcg_constant_i64(hook->data);
7881
TCGv_i64 tmp1 = tcg_constant_i64(cur_id);
@@ -81,9 +84,11 @@ void libafl_qemu_hook_block_run(target_ulong pc)
8184
tcg_temp_free_i64(tmp0);
8285
tcg_temp_free_i64(tmp1);
8386
}
87+
8488
if (cur_id != (uint64_t)-1 && hook->jit) {
8589
hook->jit(hook->data, cur_id);
8690
}
91+
8792
hook = hook->next;
8893
}
8994
}

libafl/hooks/tcg/edge.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,22 @@ bool libafl_qemu_hook_edge_gen(target_ulong src_block, target_ulong dst_block)
5656
{
5757
struct libafl_edge_hook* hook = libafl_edge_hooks;
5858
bool no_exec_hook = true;
59+
5960
while (hook) {
6061
hook->cur_id = 0;
61-
if (hook->gen)
62+
63+
if (hook->gen) {
6264
hook->cur_id = hook->gen(hook->data, src_block, dst_block);
65+
}
66+
6367
if (hook->cur_id != (uint64_t)-1 &&
64-
(hook->helper_info.func || hook->jit))
68+
(hook->helper_info.func || hook->jit)) {
6569
no_exec_hook = false;
70+
}
71+
6672
hook = hook->next;
6773
}
74+
6875
return no_exec_hook;
6976
}
7077

libafl/syx-snapshot/syx-snapshot.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -713,8 +713,8 @@ SyxSnapshotCheckResult syx_snapshot_check(SyxSnapshot* ref_snapshot)
713713
void syx_snapshot_root_restore(SyxSnapshot* snapshot)
714714
{
715715
// health check.
716-
CPUState* cpu;
717-
CPU_FOREACH(cpu) { assert(cpu->stopped); }
716+
// CPUState* cpu;
717+
// CPU_FOREACH(cpu) { assert(cpu->stopped); }
718718

719719
bool must_unlock_bql = false;
720720

subprojects/libvduse/meson.build

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@ add_project_arguments(cc.get_supported_arguments('-Wsign-compare',
88
'-Wstrict-aliasing'),
99
native: false, language: 'c')
1010

11+
#### --- Begin LibAFL code ---
1112
keyval = import('keyval')
1213
config_host = keyval.load(meson.global_build_root() / 'config-host.mak')
14+
#### --- End LibAFL code ---
1315

1416
libvduse = static_library('vduse',
1517
files('libvduse.c'),
1618
c_args: '-D_GNU_SOURCE',
17-
pic: 'AS_SHARED_LIB' in config_host)
19+
#### --- Begin LibAFL code ---
20+
pic: 'AS_SHARED_LIB' in config_host
21+
#### --- End LibAFL code ---
22+
)
1823

1924
libvduse_dep = declare_dependency(link_with: libvduse,
2025
include_directories: include_directories('.'))

0 commit comments

Comments
 (0)