Fix and assert against some more unsafe cross-thread JSContext use.

This commit is contained in:
Cory McWilliams 2024-08-25 13:30:46 -04:00
parent 2523130fdc
commit ee0efa536a
3 changed files with 25 additions and 8 deletions

View File

@ -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.

View File

@ -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 _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 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 const char* _make_set_session_cookie_header(tf_http_request_t* request, const char* session_cookie);
static JSClassID _httpd_class_id; static JSClassID _httpd_class_id;
@ -334,7 +334,7 @@ static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_va
tf_free((void*)session); tf_free((void*)session);
JSValue name = !JS_IsUndefined(jwt) ? JS_GetPropertyStr(context, jwt, "name") : JS_UNDEFINED; 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* 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); const char* cookie = _make_set_session_cookie_header(request, session_token);
tf_free((void*)session_token); tf_free((void*)session_token);
JS_FreeCString(context, name_string); JS_FreeCString(context, name_string);
@ -1305,7 +1305,7 @@ static bool _is_name_valid(const char* name)
return true; 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) if (!name || !*name)
{ {
@ -1319,7 +1319,6 @@ static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
char header_base64[256]; char header_base64[256];
sodium_bin2base64(header_base64, sizeof(header_base64), (uint8_t*)header_json, strlen(header_json), sodium_base64_VARIANT_URLSAFE_NO_PADDING); 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); JSValue payload = JS_NewObject(context);
JS_SetPropertyStr(context, payload, "name", JS_NewString(context, name)); 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)); 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) if (registered)
{ {
tf_free((void*)send_session); 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; may_become_first_admin = true;
} }
} }
@ -1513,7 +1512,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data)
if (set) if (set)
{ {
tf_free((void*)send_session); tf_free((void*)send_session);
send_session = _make_session_jwt(ssb, account_name); send_session = _make_session_jwt(context, ssb, account_name);
} }
} }
if (!set) 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)) if (have_account && *account_passwd && _verify_password(password, account_passwd))
{ {
tf_free((void*)send_session); 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; may_become_first_admin = true;
} }
else else
@ -1538,7 +1537,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data)
else else
{ {
tf_free((void*)send_session); 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); tf_free(post_form_data);
} }

View File

@ -2402,6 +2402,14 @@ tf_trace_t* tf_ssb_get_trace(tf_ssb_t* ssb)
JSContext* tf_ssb_get_context(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; return ssb->context;
} }