Hello Hiltjo, So i found the specific problem present in the code, it works as follows: Wenn surf gets started, it sets up the two communication pipes, the surf web extension gets initialized and 'initwebextensions' in surf.c gets called. This function sends the numbers for the two file descriptors to the extension. Afterwards, the web process gets forked off, the two file descriptors get copied and the extension code notifies surf through the pipes, so that surf can close the reading end of 'pipeout' and the writing end of 'pipein'.
So far so good, now the extension can use the pipes for communication. In some cases though, a new web process gets started, which again initializes the web extension and calls 'initwebextensions'. This web extension however, now receives the integers for the already closed file descriptors, which leads probably to undefined behaviour. My fix for this (see attachment for the patch) would be to just send a boolean value to the web extension, which tells it, if this is the first invocation or not. On the first invocation the extension can just do what it is used to and on the second it does nothing. This is more legit than to prevent the second invocation entirely, as webkit doesn't really provide any useful functions for this. Also, i closed all unnecesary file descriptors on the side of the web extension. It is kind of weird that no one did this before, given that you were going to the trouble of an extra communication step, just to close those on surf's side. Kind Regards, Jona
>From 4e1cdd8f58ca69091dc913b4d882c59756c7004f Mon Sep 17 00:00:00 2001 From: Jona Ackerschott <jona....@gmail.com> Date: Sat, 17 Oct 2020 18:59:51 +0200 Subject: [PATCH] Fix multiple extension inits. --- libsurf-webext.c | 28 +++++++++++++++++++--------- surf.c | 5 ++++- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/libsurf-webext.c b/libsurf-webext.c index ec9a235..2ae0eb8 100644 --- a/libsurf-webext.c +++ b/libsurf-webext.c @@ -114,15 +114,25 @@ webpagecreated(WebKitWebExtension *e, WebKitWebPage *wp, gpointer unused) G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e, GVariant *gv) { + int win, rout; + gboolean firstinit; GIOChannel *gchanpipe; - g_signal_connect(e, "page-created", G_CALLBACK(webpagecreated), NULL); - - g_variant_get(gv, "(ii)", &pipein, &pipeout); - msgsurf(NULL, "i"); - - gchanpipe = g_io_channel_unix_new(pipein); - g_io_channel_set_encoding(gchanpipe, NULL, NULL); - g_io_channel_set_close_on_unref(gchanpipe, TRUE); - g_io_add_watch(gchanpipe, G_IO_IN, readpipe, NULL); + g_variant_get(gv, "(biiii)", &firstinit, &pipein, &win, &rout, &pipeout); + close(win); + close(rout); + /* Only do something on first initialization */ + if (firstinit) { + msgsurf(NULL, "i"); + + g_signal_connect(e, "page-created", G_CALLBACK(webpagecreated), NULL); + + gchanpipe = g_io_channel_unix_new(pipein); + g_io_channel_set_encoding(gchanpipe, NULL, NULL); + g_io_channel_set_close_on_unref(gchanpipe, TRUE); + g_io_add_watch(gchanpipe, G_IO_IN, readpipe, NULL); + } else { + close(pipein); + close(pipeout); + } } diff --git a/surf.c b/surf.c index 2b54e3c..ea26849 100644 --- a/surf.c +++ b/surf.c @@ -253,6 +253,7 @@ static Parameter *curconfig; static int modparams[ParameterLast]; static int pipein[2], pipeout[2]; char *argv0; +static int firstextinit = 1; static ParamName loadtransient[] = { Certificate, @@ -1242,10 +1243,12 @@ initwebextensions(WebKitWebContext *wc, Client *c) if (!pipeout[0] || !pipein[1]) return; - gv = g_variant_new("(ii)", pipeout[0], pipein[1]); + gv = g_variant_new("(biiii)", firstextinit, pipeout[0], pipeout[1], pipein[0], pipein[1]); webkit_web_context_set_web_extensions_initialization_user_data(wc, gv); webkit_web_context_set_web_extensions_directory(wc, WEBEXTDIR); + + firstextinit = 0; } GtkWidget * -- 2.28.0