Fix use-after-free in nsigner_client_call error handling that caused segfaults on RPC error responses

This commit is contained in:
Laan Tungir
2026-08-06 18:30:03 -04:00
parent 4b7c04dc49
commit ff07264e8f
3 changed files with 16 additions and 5 deletions
+1 -1
View File
@@ -1 +1 @@
0.6.14
0.6.15
+2 -2
View File
@@ -2,10 +2,10 @@
#define NOSTR_CORE_H
// Version information (auto-updated by increment_and_push.sh)
#define VERSION "v0.6.14"
#define VERSION "v0.6.15"
#define VERSION_MAJOR 0
#define VERSION_MINOR 6
#define VERSION_PATCH 14
#define VERSION_PATCH 15
/*
* NOSTR Core Library - Complete API Reference
+13 -2
View File
@@ -339,7 +339,9 @@ int nsigner_client_call(nsigner_client_t* client,
error_item = cJSON_GetObjectItemCaseSensitive(res, "error");
if (cJSON_IsObject(error_item)) {
int rpc_code = 0;
char rpc_msg_buf[128];
const char* rpc_msg = "rpc_error";
int mapped_rc;
code_item = cJSON_GetObjectItemCaseSensitive(error_item, "code");
message_item = cJSON_GetObjectItemCaseSensitive(error_item, "message");
@@ -350,9 +352,18 @@ int nsigner_client_call(nsigner_client_t* client,
rpc_msg = message_item->valuestring;
}
nsigner_client_set_error(client, rpc_msg);
/* Copy the error message to a local buffer BEFORE freeing res,
* because rpc_msg points into the cJSON tree and would be a
* dangling pointer after cJSON_Delete(res). This was a
* use-after-free that caused segfaults on error responses
* (e.g. path_not_allowed). */
strncpy(rpc_msg_buf, rpc_msg, sizeof(rpc_msg_buf) - 1);
rpc_msg_buf[sizeof(rpc_msg_buf) - 1] = '\0';
nsigner_client_set_error(client, rpc_msg_buf);
mapped_rc = nsigner_client_map_rpc_error(rpc_code, rpc_msg_buf);
cJSON_Delete(res);
return nsigner_client_map_rpc_error(rpc_code, rpc_msg);
return mapped_rc;
}
result_item = cJSON_GetObjectItemCaseSensitive(res, "result");