From ee0efa536aca8abab3924f19bff2088b496ebe3f Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sun, 25 Aug 2024 13:30:46 -0400 Subject: [PATCH] Fix and assert against some more unsafe cross-thread JSContext use. --- metadata/en-US/changelogs/26.txt | 10 ++++++++++ src/httpd.js.c | 15 +++++++-------- src/ssb.c | 8 ++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 metadata/en-US/changelogs/26.txt diff --git a/metadata/en-US/changelogs/26.txt b/metadata/en-US/changelogs/26.txt new file mode 100644 index 00000000..a0c04677 --- /dev/null +++ b/metadata/en-US/changelogs/26.txt @@ -0,0 +1,10 @@ +* Took an initial whack at some plumbing to encourage internet-based discovery of open peers. +* Implemented prompt() on android so that the identities app works better. +* Fixed yet another incorrect use of the DB from the main thread, from an RPC that isn't ever hit. Hmm. +* Added c-ares for TXT record lookups. +* Added settings to control whether replication, room, peer exchange, and account registration are allowed. +* Latest libsodium-stable. +* Latest libbacktrace. +* Latest CodeMirror. +* Updated to Lit 3.2.0. +* Updated sqlite to 3.46.1. diff --git a/src/httpd.js.c b/src/httpd.js.c index aa849733..862d3073 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -39,7 +39,7 @@ const int64_t k_refresh_interval = 1ULL * 7 * 24 * 60 * 60 * 1000; static JSValue _authenticate_jwt(tf_ssb_t* ssb, JSContext* context, const char* jwt); static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); -static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name); +static const char* _make_session_jwt(JSContext* context, tf_ssb_t* ssb, const char* name); static const char* _make_set_session_cookie_header(tf_http_request_t* request, const char* session_cookie); static JSClassID _httpd_class_id; @@ -334,7 +334,7 @@ static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_va tf_free((void*)session); JSValue name = !JS_IsUndefined(jwt) ? JS_GetPropertyStr(context, jwt, "name") : JS_UNDEFINED; const char* name_string = !JS_IsUndefined(name) ? JS_ToCString(context, name) : NULL; - const char* session_token = _make_session_jwt(ssb, name_string); + const char* session_token = _make_session_jwt(tf_ssb_get_context(ssb), ssb, name_string); const char* cookie = _make_set_session_cookie_header(request, session_token); tf_free((void*)session_token); JS_FreeCString(context, name_string); @@ -1305,7 +1305,7 @@ static bool _is_name_valid(const char* name) return true; } -static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name) +static const char* _make_session_jwt(JSContext* context, tf_ssb_t* ssb, const char* name) { if (!name || !*name) { @@ -1319,7 +1319,6 @@ static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name) char header_base64[256]; sodium_bin2base64(header_base64, sizeof(header_base64), (uint8_t*)header_json, strlen(header_json), sodium_base64_VARIANT_URLSAFE_NO_PADDING); - JSContext* context = tf_ssb_get_context(ssb); JSValue payload = JS_NewObject(context); JS_SetPropertyStr(context, payload, "name", JS_NewString(context, name)); JS_SetPropertyStr(context, payload, "exp", JS_NewInt64(context, now.tv_sec * 1000 + now.tv_nsec / 1000000LL + k_refresh_interval)); @@ -1493,7 +1492,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data) if (registered) { tf_free((void*)send_session); - send_session = _make_session_jwt(ssb, account_name); + send_session = _make_session_jwt(context, ssb, account_name); may_become_first_admin = true; } } @@ -1513,7 +1512,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data) if (set) { tf_free((void*)send_session); - send_session = _make_session_jwt(ssb, account_name); + send_session = _make_session_jwt(context, ssb, account_name); } } if (!set) @@ -1526,7 +1525,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data) if (have_account && *account_passwd && _verify_password(password, account_passwd)) { tf_free((void*)send_session); - send_session = _make_session_jwt(ssb, account_name); + send_session = _make_session_jwt(context, ssb, account_name); may_become_first_admin = true; } else @@ -1538,7 +1537,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data) else { tf_free((void*)send_session); - send_session = _make_session_jwt(ssb, "guest"); + send_session = _make_session_jwt(context, ssb, "guest"); } tf_free(post_form_data); } diff --git a/src/ssb.c b/src/ssb.c index 51c6e89b..b9d7970f 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -2402,6 +2402,14 @@ tf_trace_t* tf_ssb_get_trace(tf_ssb_t* ssb) JSContext* tf_ssb_get_context(tf_ssb_t* ssb) { + if (ssb->thread_self && uv_thread_self() != ssb->thread_self) + { + const char* bt = tf_util_backtrace_string(); + tf_printf("Acquiring JS context from non-main thread:\n%s\n", bt); + tf_free((void*)bt); + abort(); + } + return ssb->context; }