fix(espnow): compteur peers reel + alias UAF

scenario_mesh_peer_count() cable sur le stub sante (espnow_peers
restait a 0) ; reponse POST /game/peers construite avant
cJSON_Delete (use-after-free observe sur carte : alias illisible).
Teste sur FNK0102H : register live + NVS recharge au boot
(espnow_peers=2), relay -> timeout/unknown_peer attendus.
This commit is contained in:
Claude Worker claude2
2026-06-11 05:18:55 +02:00
parent f5d8134cee
commit 31dcb28c62
4 changed files with 16 additions and 3 deletions
@@ -595,12 +595,13 @@ static esp_err_t handle_peers_post(httpd_req_t *req) {
ESP_LOGI(TAG, "peers: \"%s\" -> %02X:%02X:%02X:%02X:%02X:%02X (%s)",
alias, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
reg == ESP_OK ? "live" : "reboot needed");
cJSON_Delete(root);
// Build the response BEFORE deleting root: `alias` points into the cJSON
// tree (use-after-free observed on-device as a garbled alias echo).
char resp[128];
snprintf(resp, sizeof(resp),
"{\"ok\":true,\"alias\":\"%s\",\"live\":%s}",
alias, reg == ESP_OK ? "true" : "false");
cJSON_Delete(root);
return send_json(req, "200 OK", resp);
}
+1 -1
View File
@@ -89,7 +89,7 @@ int puzzle_get_battery_pct(void) {
}
int puzzle_get_espnow_peer_count(void) {
return 0;
return scenario_mesh_peer_count();
}
// Slice 6: wake-word callback. Runs on the voice_pipeline capture task,
@@ -73,6 +73,10 @@ esp_err_t scenario_mesh_register_peer(const char *alias, const uint8_t mac[6]);
// ESP_ERR_NOT_FOUND otherwise.
esp_err_t scenario_mesh_mac_for_alias(const char *alias, uint8_t mac_out[6]);
// Number of peers currently registered in the live table (broadcast peer
// excluded). Backs the espnow_peers health counter.
int scenario_mesh_peer_count(void);
// Chunk `data` (len bytes) into frames and send them all sequentially to
// `dest_mac`, awaiting the per-frame ack. Returns ESP_OK only if every frame
// was acked; ESP_ERR_TIMEOUT if any frame ack timed out, or the underlying
+8
View File
@@ -93,6 +93,14 @@ static void apply_worker_task(void *arg) {
// ─── peer table helpers ─────────────────────────────────────────────────────
int scenario_mesh_peer_count(void) {
int n = 0;
for (int i = 0; i < MESH_PEERS_MAX; i++) {
if (s_peers[i].used) n++;
}
return n;
}
esp_err_t scenario_mesh_register_peer(const char *alias, const uint8_t mac[6]) {
if (!alias || !mac) return ESP_ERR_INVALID_ARG;