fix: improve error handling of snprintf() in send_thread_stop_status() (#4234)

Prevent `MAX_PACKET_SIZE - len` from overflowing.
This commit is contained in:
liang.he 2025-05-09 17:14:20 +08:00 committed by GitHub
parent 908838a5b5
commit 8f3961026e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -383,7 +383,7 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
if (status == 0) { if (status == 0) {
os_mutex_lock(&tmpbuf_lock); os_mutex_lock(&tmpbuf_lock);
snprintf(tmpbuf, MAX_PACKET_SIZE, "W%02" PRIx32, status); (void)snprintf(tmpbuf, MAX_PACKET_SIZE, "W%02" PRIx32, status);
write_packet(server, tmpbuf); write_packet(server, tmpbuf);
os_mutex_unlock(&tmpbuf_lock); os_mutex_unlock(&tmpbuf_lock);
return; return;
@ -399,18 +399,38 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
os_mutex_lock(&tmpbuf_lock); os_mutex_lock(&tmpbuf_lock);
// TODO: how name a wasm thread? // TODO: how name a wasm thread?
len += snprintf(tmpbuf, MAX_PACKET_SIZE, len = snprintf(tmpbuf, MAX_PACKET_SIZE,
"T%02" PRIx32 "thread:%" PRIx64 ";name:%s;", gdb_status, "T%02" PRIx32 "thread:%" PRIx64 ";name:%s;", gdb_status,
(uint64)(uintptr_t)tid, "nobody"); (uint64)(uintptr_t)tid, "nobody");
if (len < 0 || len >= MAX_PACKET_SIZE) {
os_mutex_unlock(&tmpbuf_lock);
return;
}
if (tids_count > 0) { if (tids_count > 0) {
len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, "threads:"); int n = snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, "threads:");
if (n < 0 || n >= MAX_PACKET_SIZE - len) {
os_mutex_unlock(&tmpbuf_lock);
return;
}
len += n;
while (i < tids_count) { while (i < tids_count) {
if (i == tids_count - 1) if (i == tids_count - 1) {
len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, n = snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
"%" PRIx64 ";", (uint64)(uintptr_t)tids[i]); "%" PRIx64 ";", (uint64)(uintptr_t)tids[i]);
else }
len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, else {
"%" PRIx64 ",", (uint64)(uintptr_t)tids[i]); n = snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
"%" PRIx64 ",", (uint64)(uintptr_t)tids[i]);
}
if (n < 0 || n >= MAX_PACKET_SIZE - len) {
os_mutex_unlock(&tmpbuf_lock);
return;
}
len += n;
i++; i++;
} }
} }
@ -427,32 +447,45 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
/* When exception occurs, use reason:exception so the description can be /* When exception occurs, use reason:exception so the description can be
* correctly processed by LLDB */ * correctly processed by LLDB */
uint32 exception_len = strlen(exception); uint32 exception_len = strlen(exception);
len += int n =
snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
"thread-pcs:%" PRIx64 ";00:%s;reason:%s;description:", pc, "thread-pcs:%" PRIx64 ";00:%s;reason:%s;description:", pc,
pc_string, "exception"); pc_string, "exception");
if (n < 0 || n >= MAX_PACKET_SIZE - len) {
os_mutex_unlock(&tmpbuf_lock);
return;
}
len += n;
/* The description should be encoded as HEX */ /* The description should be encoded as HEX */
for (i = 0; i < exception_len; i++) { for (i = 0; i < exception_len; i++) {
len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, "%02x", n = snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, "%02x",
exception[i]); exception[i]);
if (n < 0 || n >= MAX_PACKET_SIZE - len) {
os_mutex_unlock(&tmpbuf_lock);
return;
}
len += n;
} }
len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, ";");
(void)snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, ";");
} }
else { else {
if (status == WAMR_SIG_TRAP) { if (status == WAMR_SIG_TRAP) {
len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, (void)snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
"thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc, "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
pc_string, "breakpoint"); pc_string, "breakpoint");
} }
else if (status == WAMR_SIG_SINGSTEP) { else if (status == WAMR_SIG_SINGSTEP) {
len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, (void)snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
"thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc, "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
pc_string, "trace"); pc_string, "trace");
} }
else { /* status > 0 (== 0 is checked at the function beginning) */ else { /* status > 0 (== 0 is checked at the function beginning) */
len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, (void)snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
"thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc, "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
pc_string, "signal"); pc_string, "signal");
} }
} }
write_packet(server, tmpbuf); write_packet(server, tmpbuf);