Skip to content

fix: memory leaks and input validation in i2c, spi, xxtea, and base modules#126

Open
Copilot wants to merge 2 commits intofix/malloc-null-checkfrom
copilot/sub-pr-123-another-one
Open

fix: memory leaks and input validation in i2c, spi, xxtea, and base modules#126
Copilot wants to merge 2 commits intofix/malloc-null-checkfrom
copilot/sub-pr-123-another-one

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 27, 2026

Several malloc/calloc null-check additions in PR #123 introduced or exposed secondary issues: missing free on alternate return paths, a variable shadowing bug that silently zeroed the tx length, missing input validation allowing size_t underflow, and a NULL dereference via strtok.

Memory leaks on early-return paths

  • luat_base.c / luat_cbcwait_cb: msg->ptr was not freed when sys_pub was not a function, leaking every queued callback allocation on that path.
  • xxtea2.c / PUB_XxTEADecrypt: out_data was not freed and returned 0 (not NULL) when real_data_size > data_size.
  • luat_lib_spi.c / l_spi_device_transfer: send_buff (heap-allocated when arg is a table) was not freed on the recv_length == 0 early return or on recv_buff allocation failure.

Variable shadowing causing silent data corruption

luat_lib_i2c.c / l_i2c_transfer: A const int tx_len was re-declared inside the table branch, shadowing the outer size_t tx_len. The outer variable remained 0, causing subsequent luat_i2c_transfer / i2c_soft_send calls to transmit 0 bytes.

// Before — shadows outer tx_len; outer stays 0
else if (lua_istable(L, 3)) {
    const int tx_len = lua_rawlen(L, 3);

// After — assigns to outer tx_len
else if (lua_istable(L, 3)) {
    tx_len = lua_rawlen(L, 3);

Missing input validation

  • luat_lib_i2c.c / l_i2c_recv: A negative Lua integer passed as len would silently wrap to a huge size_t for malloc. Added len <= 0 guard with empty-string return.
  • i2c_tools.c / i2c_tools: No minimum length check meant len - 8 / len - 9 could underflow as size_t. Added len < 9 early return. Also added a NULL check on the strtok result before passing it to memcmp.

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: wendal <589819+wendal@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix null pointer checks for malloc/calloc in LuatOS fix: memory leaks and input validation in i2c, spi, xxtea, and base modules Feb 27, 2026
@sonarqubecloud
Copy link
Copy Markdown

@wendal wendal marked this pull request as ready for review March 19, 2026 14:32
Copilot AI review requested due to automatic review settings March 19, 2026 14:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes memory leaks and hardens input validation across multiple low-level modules, addressing regressions/secondary issues introduced by earlier malloc/calloc NULL checks.

Changes:

  • Free heap allocations on early-return/error paths in SPI transfer, base callback dispatch, and XXTEA decrypt.
  • Fix I2C transfer variable shadowing that previously caused 0-length transmissions.
  • Add input validation to prevent size_t underflow and NULL dereferences in I2C receive and i2c-tools.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
luat/modules/luat_lib_spi.c Frees heap-allocated send buffer on additional early-return/error paths in SPI transfer.
luat/modules/luat_lib_i2c.c Guards against non-positive recv lengths and fixes tx_len shadowing in I2C transfer.
luat/modules/luat_base.c Frees queued callback allocation when sys_pub is not callable.
components/xxtea/src/xxtea2.c Frees out_data and returns NULL on decrypt size mismatch.
components/i2c-tools/i2c_tools.c Adds minimum length guard and checks strtok result before memcmp.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 381 to 387
int addr = luaL_checkinteger(L, 2);
int len = luaL_checkinteger(L, 3);
if (len <= 0) {
lua_pushlstring(L, NULL, 0);
return 1;
}
char *buff = (char *)luat_heap_malloc(len);
Comment on lines 20 to 27
char *command = strtok(i2c_tools_data, " ");
if (command == NULL) {
luat_heap_free(i2c_tools_data);
return;
}
if (memcmp("send", command, 4) == 0){
int i2c_id = atoi(strtok(NULL, " "));
i2c_init(i2c_id,0);
Comment on lines 650 to +660
if(recv_length == 0){
if (send_mode == LUA_TTABLE) luat_heap_free(send_buff);
lua_pushlstring(L,NULL,0);
return 1;
}
if (recv_length > 0) {
recv_buff = luat_heap_malloc(recv_length);
if(recv_buff == NULL)
if(recv_buff == NULL) {
if (send_mode == LUA_TTABLE) luat_heap_free(send_buff);
return 0;
}
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.

3 participants