Subject: Re: bug#47576: [security] ibus-daemon launches ungrafted subprocesses

From: Ludovic Courtès <[email-masked]>
Date: Tue, 20 Apr 2021 23:26:14 +0200

Ricardo Wurmus <[email-masked]> skribis:

> Ludo, the patch looks good to me.  However, many ibus input methods
> are not provided by the ibus package itself, so for ibus-anthy or
> ibus-libpinyin we would need a different mechanism.

Right.

> Would it make sense to introduce another environment variable
> (e.g. GUIX_IBUS_COMPONENTS_PATH) that specifies a search path on 
> which components are looked up?  I feel that this partially defeats
> the purpose of having a cache, so perhaps this is nonsensical.

That makes sense to me.

Attached is a variant of the previous patch that supports
GUIX_IBUS_COMPONENTS_DIRECTORY (not PATH because… it’s complicated).
It would be set to $HOME/.guix-profile/libexec.

We then need to modify the XML files of ibus-anthy, ibus-libpinyin,
etc. so that their <exec> tags use relative file names.

Thoughts?

Ludo’.

PS: IBus still builds with the patch, but that’s all I can say.  :-)

diff --git a/conf/dconf/dconf.xml.in b/conf/dconf/dconf.xml.in
index 4205cb0..538f500 100644
--- a/conf/dconf/dconf.xml.in
+++ b/conf/dconf/dconf.xml.in
@@ -3,7 +3,7 @@
 <component>
 	<name>org.freedesktop.IBus.Config</name>
 	<description>Dconf Config Component</description>
-	<exec>@libexecdir@/ibus-dconf</exec>
+	<exec>ibus-dconf</exec>
 	<version>@VERSION@</version>
 	<author>Daiki Ueno &lt;[email-masked]&gt;</author>
 	<license>GPL</license>
diff --git a/conf/memconf/memconf.xml.in b/conf/memconf/memconf.xml.in
index d6ea690..9f51bcc 100644
--- a/conf/memconf/memconf.xml.in
+++ b/conf/memconf/memconf.xml.in
@@ -2,7 +2,7 @@
 <component>
 	<name>org.freedesktop.IBus.Config</name>
 	<description>On-memory Config Component</description>
-	<exec>@libexecdir@/ibus-memconf</exec>
+	<exec>ibus-memconf</exec>
 	<version>@VERSION@</version>
 	<author>Peng Huang &lt;[email-masked]&gt;, modified by the Chromium OS Authors</author>
 	<license>GPL</license>
diff --git a/engine/simple.xml.in b/engine/simple.xml.in
index fc1541e..47cbea1 100644
--- a/engine/simple.xml.in
+++ b/engine/simple.xml.in
@@ -2,7 +2,7 @@
 <component>
 	<name>org.freedesktop.IBus.Simple</name>
 	<description>A table based simple engine</description>
-	<exec>@libexecdir@/ibus-engine-simple</exec>
+	<exec>ibus-engine-simple</exec>
 	<version>@VERSION@</version>
 	<author>Peng Huang &lt;[email-masked]&gt;</author>
 	<license>GPL</license>
diff --git a/src/Makefile.am b/src/Makefile.am
index a8e3d07..2c461ee 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,6 +49,7 @@ AM_CPPFLAGS =                                           \
     @GLIB2_CFLAGS@                                      \
     @GOBJECT2_CFLAGS@                                   \
     @GIO2_CFLAGS@                                       \
+    -DLIBEXECDIR=\"$(libexecdir)\"			\
     -DIBUS_CACHE_DIR=\""$(localstatedir)/cache/ibus"\"  \
     -DIBUS_DATA_DIR=\"$(pkgdatadir)\"                   \
     -DIBUS_DISABLE_DEPRECATION_WARNINGS                 \
diff --git a/src/Makefile.in b/src/Makefile.in
index 2a9c2ab..c3dfd87 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -613,6 +613,7 @@ CLEANFILES = $(am__append_2) $(BUILT_SOURCES) stamp-ibusmarshalers.h \
 # C preprocessor flags
 AM_CPPFLAGS = -DG_LOG_DOMAIN=\"IBUS\" @GLIB2_CFLAGS@ @GOBJECT2_CFLAGS@ \
 	@GIO2_CFLAGS@ \
+	-DLIBEXECDIR=\"$(libexecdir)\" \
 	-DIBUS_CACHE_DIR=\""$(localstatedir)/cache/ibus"\" \
 	-DIBUS_DATA_DIR=\"$(pkgdatadir)\" \
 	-DIBUS_DISABLE_DEPRECATION_WARNINGS -DIBUS_COMPILATION \
diff --git a/src/ibuscomponent.c b/src/ibuscomponent.c
index 9837f47..ca875bd 100644
--- a/src/ibuscomponent.c
+++ b/src/ibuscomponent.c
@@ -613,16 +613,45 @@ ibus_component_parse_engines (IBusComponent *component,
     }
 
     if (exec != NULL) {
-        gchar *output = NULL;
-        if (g_spawn_command_line_sync (exec, &output, NULL, NULL, NULL)) {
-            engines_node = ibus_xml_parse_buffer (output);
-            g_free (output);
-
-            if (engines_node) {
-                if (g_strcmp0 (engines_node->name, "engines") == 0) {
-                    node = engines_node;
+        gint argc;
+        gchar **argv;
+
+        if (g_shell_parse_argv (exec, &argc, &argv, NULL)) {
+            gchar *output = NULL;
+            gchar *program = argv[0];
+
+            if (program[0] != '/') {
+                /* PROGRAM is a relative file name, so assume it's the name
+                   of an executable in LIBEXECDIR or
+                   $GUIX_IBUS_COMPONENTS_DIRECTORY and expand it.  */
+                const gchar *directory;
+                gchar *absolute;
+
+                directory = g_getenv ("GUIX_IBUS_COMPONENTS_DIRECTORY") ?: LIBEXECDIR;
+                absolute = g_malloc (strlen (directory) + strlen (program) + 2);
+                strcpy (absolute, directory);
+                strcat (absolute, "/");
+                strcat (absolute, program);
+
+                g_free (program);
+                argv[0] = absolute;
+            }
+
+            if (g_spawn_sync (NULL, argv, NULL,
+                              G_SPAWN_DEFAULT, NULL, NULL,
+                              &output, NULL,         /* stdout, stderr */
+                              NULL, NULL)) {
+                engines_node = ibus_xml_parse_buffer (output);
+                g_free (output);
+
+                if (engines_node) {
+                    if (g_strcmp0 (engines_node->name, "engines") == 0) {
+                        node = engines_node;
+                    }
                 }
             }
+
+            g_strfreev (argv);
         }
     }
 
diff --git a/ui/gtk3/gtkextension.xml.in b/ui/gtk3/gtkextension.xml.in
index b8157c9..fc945ab 100644
--- a/ui/gtk3/gtkextension.xml.in
+++ b/ui/gtk3/gtkextension.xml.in
@@ -3,7 +3,7 @@
 <component>
 	<name>org.freedesktop.IBus.Panel.Extension</name>
 	<description>Gtk Panel Extension Component</description>
-	<exec>@libexecdir@/ibus-extension-gtk3</exec>
+	<exec>ibus-extension-gtk3</exec>
 	<version>@VERSION@</version>
 	<author>Takao Fujiwara &lt;[email-masked]&gt;</author>
 	<license>GPL</license>
diff --git a/ui/gtk3/gtkpanel.xml.in b/ui/gtk3/gtkpanel.xml.in
index b61f400..2175b93 100644
--- a/ui/gtk3/gtkpanel.xml.in
+++ b/ui/gtk3/gtkpanel.xml.in
@@ -3,7 +3,7 @@
 <component>
 	<name>org.freedesktop.IBus.Panel</name>
 	<description>Gtk Panel Component</description>
-	<exec>@libexecdir@/ibus-ui-gtk3</exec>
+	<exec>ibus-ui-gtk3</exec>
 	<version>@VERSION@</version>
 	<author>Peng Huang &lt;[email-masked]&gt;</author>
 	<license>GPL</license>