Skip to content

Instantly share code, notes, and snippets.

@schkovich
Last active May 15, 2025 15:23
Show Gist options
  • Save schkovich/15775981875795f7beda31b2e57b0246 to your computer and use it in GitHub Desktop.
Save schkovich/15775981875795f7beda31b2e57b0246 to your computer and use it in GitHub Desktop.
A minimal example to reproduce UAF
#include <Arduino.h>
#include "pico/async_context_threadsafe_background.h"
bool core1_separate_stack = true;
volatile bool operational = false;
static async_context_threadsafe_background_t asyncCtx;
uint32_t doSomeWork(void* param) {
async_when_pending_worker* h = asyncCtx.core.when_pending_list;
auto* ptr = static_cast<uint32_t*>(param);
(*ptr) += 1; // Simple operation to demonstrate synchronous call
Serial1.printf("[INFO][%d][%llu] doSomeWork() worker: %p; myNumber: %d.\n",
get_core_num(),
to_us_since_boot(get_absolute_time()),
h,
*ptr);
h->user_data = ptr;
return *ptr;
}
void setup() {
Serial1.setRX(PIN_SERIAL1_RX);
Serial1.setTX(PIN_SERIAL1_TX);
Serial1.setPollingMode(true);
Serial1.begin(115200);
while (!Serial1) {
delay(10);
}
while (!operational) {
delay(10);
}
RP2040::enableDoubleResetBootloader();
pinMode(LED_BUILTIN, OUTPUT);
Serial1.printf("C0 ready...\n");
}
void setup1() {
async_context_threadsafe_background_config_t cfg = async_context_threadsafe_background_default_config();
operational = async_context_threadsafe_background_init(&asyncCtx, &cfg);
assert(operational);
Serial1.printf("C1 ready...\n");
}
void loop() {
delay(1);
static unsigned long c0_counter = 1;
static uint32_t myNumber = 0;
if (c0_counter % 333 == 0) {
const auto rc = async_context_execute_sync(&asyncCtx.core, doSomeWork, &myNumber);
assert(rc == myNumber);
}
c0_counter++;
delay(2);
}
void loop1() {
delay(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment