Skip to content

fix: P0 safety fixes — OSAL header leak and const-cast UB#48

Merged
zevorn merged 4 commits intomainfrom
fix/p0-safety-fixes
Mar 16, 2026
Merged

fix: P0 safety fixes — OSAL header leak and const-cast UB#48
zevorn merged 4 commits intomainfrom
fix/p0-safety-fixes

Conversation

@zevorn
Copy link
Copy Markdown
Owner

@zevorn zevorn commented Mar 16, 2026

Summary

  • osal: remove platform-specific socket includes from claw_net.h — the OSAL network header was leaking lwip/sockets.h / sys/socket.h via #ifdef CLAW_PLATFORM_*, breaking the abstraction boundary. Moved BSD socket includes directly into swarm.c (the only non-OSAL consumer).
  • feishu, telegram: fix undefined behavior in message chunkingsend_reply() cast away const on a const char * parameter to temporarily insert '\0' for chunk splitting. This is UB per C99. Replaced with heap-allocated chunk buffers (claw_malloc + memcpy). Also added missing cJSON_IsString() check in feishu handle_message_event().

Test plan

  • ESP32-C3 QEMU build passes (0 errors, 0 warnings)
  • vexpress-a9 QEMU build passes (RT-Thread backend)
  • scripts/check-patch.sh style check passes
  • QEMU boot test: make run-esp32c3-qemu
  • Feishu/Telegram long message (>4KB) chunking still works correctly

zevorn added 4 commits March 16, 2026 23:02
claw_net.h is the OSAL network abstraction header and should not
contain platform-conditional socket includes (lwip/sockets.h,
sys/socket.h, etc.).  This leaked platform details into any
translation unit that included the header.

Move the BSD socket includes directly into swarm.c, which is the
only consumer outside the OSAL implementation files that needs
them.  The OSAL backends (claw_net_freertos.c, claw_net_rtthread.c)
already include their own platform socket headers.

Signed-off-by: Chao Liu <chao.liu.zevorn@gmail.com>
send_reply() splits long messages by temporarily inserting '\0'
into a const char * parameter via (char *)p cast.  This is
undefined behavior per C99 — the underlying memory may be in a
read-only segment.

Replace the const-cast pattern with a heap-allocated chunk buffer
(claw_malloc + memcpy) that is safely null-terminated and freed
after each chunk is sent.

Also add missing cJSON_IsString() check for message_type in
feishu handle_message_event() to prevent NULL dereference if
the field is not a string.

Signed-off-by: Chao Liu <chao.liu.zevorn@gmail.com>
The message chunking algorithm (split at last newline before the
length limit) was duplicated between feishu.c and telegram.c.

Extract it into im_find_chunk_end() in a platform-independent
im_util.c, and refactor both IM backends to call it.

Add 14 unit tests covering:
- no split needed (fits in max_chunk)
- exact boundary
- hard split when no newline found
- split at last newline in scan range
- multiple newlines (pick last before limit)
- newline at max_chunk position (included)
- newline in first half (outside scan, ignored)
- single byte / zero remaining
- full multi-round chunking simulation
- degenerate max_chunk (1, 2)

All 39 tests pass (make test-unit).

Signed-off-by: Chao Liu <chao.liu.zevorn@gmail.com>
ESP32-S3 Xtensa QEMU emulation is 3-5x slower than ESP32-C3
RISC-V, causing the S3 smoke job to take 30+ minutes on GitHub
Actions shared runners.  Since C3 already covers the full
ESP-IDF + FreeRTOS + OSAL path, the S3 difference is only in
hardware peripherals which QEMU does not emulate anyway.

Remove esp32s3-qemu from the per-PR ci-qemu-correctness matrix
and create a dedicated ci-nightly.yml that runs it daily at
04:00 UTC.  This cuts PR CI wall time from ~45 min to ~5 min.

Signed-off-by: Chao Liu <chao.liu.zevorn@gmail.com>
@zevorn zevorn merged commit 8c3f979 into main Mar 16, 2026
8 checks passed
@zevorn zevorn deleted the fix/p0-safety-fixes branch March 16, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant