Subject: bug#34135: IceCat lacks WebGL support

From: Sarah Morgensen <[email-masked]>
Date: Sat, 25 Sep 2021 17:11:56 -0700

Hi Ludo,

I ran into this bug today, so I took a look through this...

Ludovic Courtès <[email-masked]> writes:

> Julien Lepiller <[email-masked]> skribis:
>
>> Le 21 janvier 2019 09:24:53 GMT+01:00, Ricardo Wurmus <[email-masked]> a écrit :
>>>
>>>Ludovic Courtès <[email-masked]> writes:
>>>
>>>> Hi Julien,
>>>>
>>>> Julien Lepiller <[email-masked]> skribis:
>>>>
>>>>> Try setting security.sandbox.content.read_path_whitelist to
>>>/gnu/store/
>>>>> (with a leading /) in about:config.
>>>>
>>>> Setting it to “/gnu/store/” (with a trailing slash) works, thank you!
>>>>
>>>> It turns out that setting LIBGL_DRIVERS_PATH is even unnecessary.
>>>>
>>>> I suppose we should patch the default value of
>>>> ‘security.sandbox.content.read_path_whitelist’ in our package.  What
>>>do
>>>> people think?
>>>
>>>It isn’t much of a sandbox if all of /gnu/store would be permitted. 
>>>Can
>>>this be reduced to the paths of store items that are known at build
>>>time?
>>
>> You'll have to list every library and there dependencies. Is that
>> possible?
>
> That would be possible, yes, though we’d have the build-time
> dependencies rather than the run-time dependencies (since we cannot know
> the run-time dependencies until IceCat is built.)
>
> That said putting all of /gnu/store wouldn’t be that bad I think—at
> least user data remains inaccessible, which is much better than exposing
> /usr on FHS distros.
>
> Thoughts?
>
> Ludo’.

While it looks like preliminary precise whitelisting was done for
ffmpeg, it seems that this approach may require excessive effort for
WebGL.  I've attached a security sandbox log generated with

  MOZ_SANDBOX_LOGGING=1 icecat https://get.webgl.org

using Guix's default value of security.sandbox.content.read_path_whitelist.

You see that it does whitelist paths from ld.so.conf, but that isn't
enough.  It seems some of the paths it tries to read (notably, the last)
aren't even in icecat's inputs.  For example, after whitelisting libxcb,
it needs

  /gnu/store/w68jrgqqbfcakm27wm4zf7hmpgw294my-libxxf86vm-1.1.4/lib/libXxf86vm.so.1

and after whitelisting that one,

  /gnu/store/jwga98k68l0h5c45jx7z4jdjzhfc34vm-libxshmfence-1.3/lib/libxshmfence.so.1

and so on.  Both the above are propagated-inputs in mesa.  So, it seems
to "properly" fix this, we would need to read *all* input libraries
recursively.  I've also attached a successful log (with
read_path_whitelist set to "/gnu/store/").

Until someone devises a method to do that, whitelisting "/gnu/store/"
seems like the best option.  I've attached a patch for that.

--
Sarah

>From 48e223d33746516010677197ce12b7bf3bb6637c Mon Sep 17 00:00:00 2001
Message-Id: <[email-masked]>
From: Sarah Morgensen <[email-masked]>
Date: Sat, 25 Sep 2021 17:05:24 -0700
Subject: [PATCH] gnu: icecat: Fix sandbox path whitelist.

Fixes <https://issues.guix.gnu.org/34136>.

* gnu/packages/gnuzilla.scm (icecat)[arguments]<#:phases>
{fix-ffmpeg-runtime-linker}: Move sandbox whitelist logic to...
{set-sandbox-whitelist}: ...here.  Set whitelist to "/gnu/store/".
---
 gnu/packages/gnuzilla.scm | 30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm
index 431b487fd0..e71df45966 100644
--- a/gnu/packages/gnuzilla.scm
+++ b/gnu/packages/gnuzilla.scm
@@ -1124,26 +1124,16 @@ from forcing GEXP-PROMISE."
                ;; Arrange to load libavcodec.so by its absolute file name.
                (substitute* "dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp"
                  (("libavcodec\\.so")
-                  libavcodec))
-               ;; Populate the sandbox read-path whitelist as needed by ffmpeg.
-               (let* ((mime-info (assoc-ref inputs "shared-mime-info"))
-                      (libavcodec-runpath (call-with-input-file libavcodec
-                                            (compose elf-dynamic-info-runpath
-                                                     elf-dynamic-info
-                                                     parse-elf
-                                                     get-bytevector-all)))
-                      (whitelist (cons (string-append mime-info "/share/mime/")
-                                       (map (lambda (dir)
-                                              (string-append dir "/"))
-                                            libavcodec-runpath)))
-                      (whitelist-string (string-join whitelist ","))
-                      (port (open-file "browser/app/profile/icecat.js" "a")))
-                 (format #t "setting 'security.sandbox.content.read_path_whitelist' to '~a'~%"
-                         whitelist-string)
-                 (format port "~%pref(\"security.sandbox.content.read_path_whitelist\", ~S);~%"
-                         whitelist-string)
-                 (close-output-port port))
-               #t)))
+                  libavcodec)))))
+         (add-after 'fix-ffmpeg-runtime-linker 'set-sandbox-whitelist
+           (lambda _
+             (let ((port (open-file "browser/app/profile/icecat.js" "a"))
+                   (whitelist-string "/gnu/store/"))
+               (format #t "setting 'security.sandbox.content.read_path_whitelist' to '~a'~%"
+                       whitelist-string)
+               (format port "~%pref(\"security.sandbox.content.read_path_whitelist\", ~S);~%"
+                       whitelist-string)
+               (close-output-port port))))
          (replace 'bootstrap
            (lambda _
              (invoke "sh" "-c" "autoconf old-configure.in > old-configure")

base-commit: 69f37702dfcda776a190d5c40fad8518469ce3c4
-- 
2.33.0