Fixed qemu usermode snapshot (#66)
* Fixed qemu usermode snapshot --------- Co-authored-by: Romain Malmain <romain.malmain@pm.me>
This commit is contained in:
parent
c6d56fc94c
commit
43302cdc39
@ -153,6 +153,12 @@ static PageFlagsNode *pageflags_find(target_ulong start, target_ulong last)
|
|||||||
return n ? container_of(n, PageFlagsNode, itree) : NULL;
|
return n ? container_of(n, PageFlagsNode, itree) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//// --- Begin LibAFL code ---
|
||||||
|
IntervalTreeRoot * pageflags_get_root(void) {
|
||||||
|
return &pageflags_root;
|
||||||
|
}
|
||||||
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
static PageFlagsNode *pageflags_next(PageFlagsNode *p, target_ulong start,
|
static PageFlagsNode *pageflags_next(PageFlagsNode *p, target_ulong start,
|
||||||
target_ulong last)
|
target_ulong last)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
#include "qemu/rcu.h"
|
#include "qemu/rcu.h"
|
||||||
|
|
||||||
|
//// --- Begin LibAFL code ---
|
||||||
|
#include "qemu/interval-tree.h"
|
||||||
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
/* some important defines:
|
/* some important defines:
|
||||||
*
|
*
|
||||||
* HOST_BIG_ENDIAN : whether the host cpu is big endian and
|
* HOST_BIG_ENDIAN : whether the host cpu is big endian and
|
||||||
@ -192,6 +196,10 @@ int page_get_flags(target_ulong address);
|
|||||||
void page_set_flags(target_ulong start, target_ulong last, int flags);
|
void page_set_flags(target_ulong start, target_ulong last, int flags);
|
||||||
void page_reset_target_data(target_ulong start, target_ulong last);
|
void page_reset_target_data(target_ulong start, target_ulong last);
|
||||||
|
|
||||||
|
//// --- Begin LibAFL code ---
|
||||||
|
IntervalTreeRoot* pageflags_get_root(void);
|
||||||
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* page_check_range
|
* page_check_range
|
||||||
* @start: first byte of range
|
* @start: first byte of range
|
||||||
|
@ -14,4 +14,4 @@ struct libafl_mapinfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
IntervalTreeNode * libafl_maps_first(IntervalTreeRoot * map_info);
|
IntervalTreeNode * libafl_maps_first(IntervalTreeRoot * map_info);
|
||||||
IntervalTreeNode * libafl_maps_next(IntervalTreeNode *node, struct libafl_mapinfo* ret);
|
IntervalTreeNode * libafl_maps_next(IntervalTreeNode *pageflags_maps_node, IntervalTreeRoot *proc_maps_node, struct libafl_mapinfo* ret);
|
||||||
|
@ -13806,27 +13806,33 @@ IntervalTreeNode * libafl_maps_first(IntervalTreeRoot * map_info) {
|
|||||||
return interval_tree_iter_first(map_info, 0, -1);
|
return interval_tree_iter_first(map_info, 0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
IntervalTreeNode * libafl_maps_next(IntervalTreeNode *node, struct libafl_mapinfo* ret) {
|
IntervalTreeNode * libafl_maps_next(IntervalTreeNode *pageflags_maps_node, IntervalTreeRoot *proc_maps_root, struct libafl_mapinfo* ret) {
|
||||||
ret->is_valid = false;
|
ret->is_valid = false;
|
||||||
|
|
||||||
if (!node || !ret) {
|
if (!pageflags_maps_node || !ret) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapInfo *e = container_of(node, MapInfo, itree);
|
MapInfo *e;
|
||||||
|
IntervalTreeNode *proc_map_interval_node;
|
||||||
|
|
||||||
if (h2g_valid(e->itree.start)) {
|
if (h2g_valid(pageflags_maps_node->start)) {
|
||||||
unsigned long min = e->itree.start;
|
unsigned long min = pageflags_maps_node->start;
|
||||||
unsigned long max = e->itree.last + 1;
|
unsigned long max = pageflags_maps_node->last + 1;
|
||||||
int flags = page_get_flags(h2g(min));
|
int flags = page_get_flags(h2g(min));
|
||||||
|
|
||||||
max = h2g_valid(max - 1) ?
|
max = h2g_valid(max - 1) ?
|
||||||
max : (uintptr_t) g2h_untagged(GUEST_ADDR_MAX) + 1;
|
max : (uintptr_t) g2h_untagged(GUEST_ADDR_MAX) + 1;
|
||||||
|
|
||||||
|
// I guess this is useless? we are walking the entire pageflags_root tree, so we should always have a valid node
|
||||||
if (!page_check_range(h2g(min), max - min, flags)) {
|
if (!page_check_range(h2g(min), max - min, flags)) {
|
||||||
return libafl_maps_next(interval_tree_iter_next(node, 0, -1), ret);
|
return libafl_maps_next(interval_tree_iter_next(pageflags_maps_node, 0, -1), proc_maps_root, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should we check for NULL? Not sure, but if an inteval is in pageflags, then it should be in proc_maps too
|
||||||
|
proc_map_interval_node = interval_tree_iter_first(proc_maps_root, min, min);
|
||||||
|
e = container_of(proc_map_interval_node, MapInfo, itree);
|
||||||
|
|
||||||
int libafl_flags = 0;
|
int libafl_flags = 0;
|
||||||
if (flags & PAGE_READ) libafl_flags |= PROT_READ;
|
if (flags & PAGE_READ) libafl_flags |= PROT_READ;
|
||||||
if (flags & PAGE_WRITE_ORG) libafl_flags |= PROT_WRITE;
|
if (flags & PAGE_WRITE_ORG) libafl_flags |= PROT_WRITE;
|
||||||
@ -13840,9 +13846,9 @@ IntervalTreeNode * libafl_maps_next(IntervalTreeNode *node, struct libafl_mapinf
|
|||||||
ret->flags = libafl_flags;
|
ret->flags = libafl_flags;
|
||||||
ret->is_priv = e->is_priv;
|
ret->is_priv = e->is_priv;
|
||||||
|
|
||||||
return interval_tree_iter_next(node, 0, -1);
|
return interval_tree_iter_next(pageflags_maps_node, 0, -1);
|
||||||
} else {
|
} else {
|
||||||
return libafl_maps_next(interval_tree_iter_next(node, 0, -1), ret);
|
return libafl_maps_next(interval_tree_iter_next(pageflags_maps_node, 0, -1), proc_maps_root, ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user