summarylogtreecommitdiffstats
path: root/0001-fontconfig-compat.patch
blob: 1ca34af046bd1cfb8837cd66796407a0dc193c75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
From 0f8dfa23744150b2aa91f6bd169b871308ecb43f Mon Sep 17 00:00:00 2001
Message-Id: <0f8dfa23744150b2aa91f6bd169b871308ecb43f.1589805773.git.maciej.zenon.borzecki@canonical.com>
In-Reply-To: <cover.1589805773.git.maciej.zenon.borzecki@canonical.com>
References: <cover.1589805773.git.maciej.zenon.borzecki@canonical.com>
From: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Date: Wed, 6 May 2020 10:45:38 +0200
Subject: [PATCH 1/3] interfaces/builtin/desktop: do not mount fonts cache on
 distros with quirks

There is a problem with compatibility of fontconfig cache files generated across
different versions of the fontconfig library. The cache files appear to be using
the same format, but when loaded by an older version of the library, they cause
instability, bad font rendering or plain segfaults.

The following versions of packages present on specific distros are known to
generate incompatible cache files:

- Arch: fontconfig 2:2.13.91+24+g75eadca-2
- Fedora 32: fontconfig-2.13.92-9.fc32.x86_64

More information is provided in the following post:
https://forum.snapcraft.io/t/snapped-app-not-loading-fonts-on-fedora-and-arch/12484/32
A bisect identified this commit where the problem first occurred:
https://gitlab.freedesktop.org/fontconfig/fontconfig/commit/0f9bbbcf8f6f8264efb0a2ded4d8d05f3b10f7a4

Until we work out a better solution, disable the fonts cache on distros that are
known to cause issues. This comes at the potential cost of slightly longer
application startup times, but a working app is better than a segfaulting one.

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
---
 interfaces/builtin/desktop.go      | 13 ++++++++
 interfaces/builtin/desktop_test.go | 52 +++++++++++++++++-------------
 2 files changed, 42 insertions(+), 23 deletions(-)

diff --git a/interfaces/builtin/desktop.go b/interfaces/builtin/desktop.go
index 05a97251f7fcad66a356ea7d77690dcb02f724d1..8e18a4fc4409e957b51f0763dc791c8e54eec09e 100644
--- a/interfaces/builtin/desktop.go
+++ b/interfaces/builtin/desktop.go
@@ -26,6 +26,7 @@ import (
 	"github.com/snapcore/snapd/interfaces/mount"
 	"github.com/snapcore/snapd/osutil"
 	"github.com/snapcore/snapd/release"
+	"github.com/snapcore/snapd/strutil"
 )
 
 const desktopSummary = `allows access to basic graphical desktop resources`
@@ -288,6 +289,18 @@ func (iface *desktopInterface) MountConnectedPlug(spec *mount.Specification, plu
 		if !osutil.IsDirectory(dir) {
 			continue
 		}
+		if release.DistroLike("arch", "fedora") {
+			// XXX: on Arch and Fedora 32+ there is a known
+			// incompatibility between the binary fonts cache files
+			// and ones expected by desktop snaps; even though the
+			// cache format level is same for both, the host
+			// generated cache files cause instability, segfaults or
+			// incorrect rendering of fonts, for this reason do not
+			// mount the cache directories on those distributions
+			if strutil.ListContains(dirs.SystemFontconfigCacheDirs, dir) {
+				continue
+			}
+		}
 		// Since /etc/fonts/fonts.conf in the snap mount ns is the same
 		// as on the host, we need to preserve the original directory
 		// paths for the fontconfig runtime to poke the correct
diff --git a/interfaces/builtin/desktop_test.go b/interfaces/builtin/desktop_test.go
index d30af78ddea39f874eb2f4d8b765c82adab6872b..e0f995fd7633b06f81d4439c700fab34a59264d5 100644
--- a/interfaces/builtin/desktop_test.go
+++ b/interfaces/builtin/desktop_test.go
@@ -154,6 +154,8 @@ func (s *DesktopInterfaceSuite) TestMountSpec(c *C) {
 	// are bind mounted from the host system if they exist.
 	restore = release.MockOnClassic(true)
 	defer restore()
+	restore = release.MockReleaseInfo(&release.OS{ID: "ubuntu"})
+	defer restore()
 	spec = &mount.Specification{}
 	c.Assert(spec.AddConnectedPlug(s.iface, s.plug, s.coreSlot), IsNil)
 
@@ -177,29 +179,33 @@ func (s *DesktopInterfaceSuite) TestMountSpec(c *C) {
 	c.Assert(entries, HasLen, 1)
 	c.Check(entries[0].Dir, Equals, "$XDG_RUNTIME_DIR/doc")
 
-	// Fedora is a little special with their fontconfig cache location(s)
-	restore = release.MockReleaseInfo(&release.OS{ID: "fedora"})
-	defer restore()
-
-	tmpdir = c.MkDir()
-	dirs.SetRootDir(tmpdir)
-	c.Assert(dirs.SystemFontconfigCacheDirs, DeepEquals, []string{filepath.Join(tmpdir, "/var/cache/fontconfig"), filepath.Join(tmpdir, "/usr/lib/fontconfig/cache")})
-	c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/usr/share/fonts"), 0777), IsNil)
-	c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/usr/local/share/fonts"), 0777), IsNil)
-	c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/usr/lib/fontconfig/cache"), 0777), IsNil)
-	c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/var/cache/fontconfig"), 0777), IsNil)
-	spec = &mount.Specification{}
-	c.Assert(spec.AddConnectedPlug(s.iface, s.plug, s.coreSlot), IsNil)
-	entries = spec.MountEntries()
-	c.Assert(entries, HasLen, 4)
-
-	c.Check(entries[2].Name, Equals, hostfs+dirs.SystemFontconfigCacheDirs[0])
-	c.Check(entries[2].Dir, Equals, "/var/cache/fontconfig")
-	c.Check(entries[2].Options, DeepEquals, []string{"bind", "ro"})
-
-	c.Check(entries[3].Name, Equals, hostfs+dirs.SystemFontconfigCacheDirs[1])
-	c.Check(entries[3].Dir, Equals, "/usr/lib/fontconfig/cache")
-	c.Check(entries[3].Options, DeepEquals, []string{"bind", "ro"})
+	for _, distroWithQuirks := range []string{"fedora", "arch"} {
+		restore = release.MockReleaseInfo(&release.OS{ID: distroWithQuirks})
+		defer restore()
+
+		tmpdir = c.MkDir()
+		dirs.SetRootDir(tmpdir)
+		if distroWithQuirks == "fedora" {
+			// Fedora is a little special with their fontconfig cache location(s) and how we handle them
+			c.Assert(dirs.SystemFontconfigCacheDirs, DeepEquals, []string{filepath.Join(tmpdir, "/var/cache/fontconfig"), filepath.Join(tmpdir, "/usr/lib/fontconfig/cache")})
+		} else {
+			c.Assert(dirs.SystemFontconfigCacheDirs, DeepEquals, []string{filepath.Join(tmpdir, "/var/cache/fontconfig")})
+		}
+		c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/usr/share/fonts"), 0777), IsNil)
+		c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/usr/local/share/fonts"), 0777), IsNil)
+		c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/usr/lib/fontconfig/cache"), 0777), IsNil)
+		c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/var/cache/fontconfig"), 0777), IsNil)
+		spec = &mount.Specification{}
+		c.Assert(spec.AddConnectedPlug(s.iface, s.plug, s.coreSlot), IsNil)
+		entries = spec.MountEntries()
+		c.Assert(entries, HasLen, 2)
+
+		for _, en := range entries {
+			if en.Dir == "/var/cache/fontconfig" || en.Dir == "/usr/lib/fontconfig/cache" {
+				c.Fatalf("unpexected cache mount entry: %q", en.Dir)
+			}
+		}
+	}
 }
 
 func (s *DesktopInterfaceSuite) TestStaticInfo(c *C) {
-- 
2.26.2

From b1183c5ed448e61f7da7ec518682a00ca4cb9161 Mon Sep 17 00:00:00 2001
Message-Id: <b1183c5ed448e61f7da7ec518682a00ca4cb9161.1589805773.git.maciej.zenon.borzecki@canonical.com>
In-Reply-To: <cover.1589805773.git.maciej.zenon.borzecki@canonical.com>
References: <cover.1589805773.git.maciej.zenon.borzecki@canonical.com>
From: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Date: Wed, 6 May 2020 15:39:48 +0200
Subject: [PATCH 2/3] interfaces/builtin/desktop: mention the fonts bug report
 in comments

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
---
 interfaces/builtin/desktop.go | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/interfaces/builtin/desktop.go b/interfaces/builtin/desktop.go
index 8e18a4fc4409e957b51f0763dc791c8e54eec09e..950c02c2463879bd997ddd5ff95f35051912b26a 100644
--- a/interfaces/builtin/desktop.go
+++ b/interfaces/builtin/desktop.go
@@ -296,7 +296,8 @@ func (iface *desktopInterface) MountConnectedPlug(spec *mount.Specification, plu
 			// cache format level is same for both, the host
 			// generated cache files cause instability, segfaults or
 			// incorrect rendering of fonts, for this reason do not
-			// mount the cache directories on those distributions
+			// mount the cache directories on those distributions,
+			// see https://bugs.launchpad.net/snapd/+bug/1877109
 			if strutil.ListContains(dirs.SystemFontconfigCacheDirs, dir) {
 				continue
 			}
-- 
2.26.2

From c73b5879d78f10b16f7b3168948299dacd6da40c Mon Sep 17 00:00:00 2001
Message-Id: <c73b5879d78f10b16f7b3168948299dacd6da40c.1589805773.git.maciej.zenon.borzecki@canonical.com>
In-Reply-To: <cover.1589805773.git.maciej.zenon.borzecki@canonical.com>
References: <cover.1589805773.git.maciej.zenon.borzecki@canonical.com>
From: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Date: Wed, 6 May 2020 15:40:58 +0200
Subject: [PATCH 3/3] tests/main/interfaces-desktop-host-fonts: update fonts
 cache test

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
---
 tests/main/interfaces-desktop-host-fonts/task.yaml | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/tests/main/interfaces-desktop-host-fonts/task.yaml b/tests/main/interfaces-desktop-host-fonts/task.yaml
index c61dbf83b37331537a8d2c36cff2c844330540f0..02f2aa120b80c71c80ed20c4ceb772e8df63cb9a 100644
--- a/tests/main/interfaces-desktop-host-fonts/task.yaml
+++ b/tests/main/interfaces-desktop-host-fonts/task.yaml
@@ -49,7 +49,16 @@ execute: |
     test-snapd-desktop.check-files /usr/local/share/fonts/local-font.txt | MATCH "Local font"
 
     echo "Checking access to host $cache_dir"
-    test-snapd-desktop.check-files "$cache_dir"/cache.txt | MATCH "Cache file"
+    case "$SPREAD_SYSTEM" in
+        fedora-*|centos-*|amazon-linux-*|arch-linux-*)
+            # system fonts cache is inaccessible due to
+            # https://bugs.launchpad.net/snapd/+bug/1877109
+            test-snapd-desktop.sh -c "test ! -e $cache_dir/cache.txt"
+            ;;
+        *)
+            test-snapd-desktop.check-files "$cache_dir"/cache.txt | MATCH "Cache file"
+            ;;
+    esac
 
     echo "Checking access to host ~/.fonts"
     test-snapd-desktop.check-files "$HOME"/.fonts/user-font1.txt | MATCH "User font 1"
-- 
2.26.2