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

Reply via email to