summaryrefslogtreecommitdiffstats
path: root/meta/recipes-graphics/wayland/wayland/CVE-2021-3782.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-graphics/wayland/wayland/CVE-2021-3782.patch')
-rw-r--r--meta/recipes-graphics/wayland/wayland/CVE-2021-3782.patch111
1 files changed, 111 insertions, 0 deletions
diff --git a/meta/recipes-graphics/wayland/wayland/CVE-2021-3782.patch b/meta/recipes-graphics/wayland/wayland/CVE-2021-3782.patch
new file mode 100644
index 0000000000..df204508e9
--- /dev/null
+++ b/meta/recipes-graphics/wayland/wayland/CVE-2021-3782.patch
@@ -0,0 +1,111 @@
1From 5eed6609619cc2e4eaa8618d11c15d442abf54be Mon Sep 17 00:00:00 2001
2From: Derek Foreman <derek.foreman@collabora.com>
3Date: Fri, 28 Jan 2022 13:18:37 -0600
4Subject: [PATCH] util: Limit size of wl_map
5
6Since server IDs are basically indistinguishable from really big client
7IDs at many points in the source, it's theoretically possible to overflow
8a map and either overflow server IDs into the client ID space, or grow
9client IDs into the server ID space. This would currently take a massive
10amount of RAM, but the definition of massive changes yearly.
11
12Prevent this by placing a ridiculous but arbitrary upper bound on the
13number of items we can put in a map: 0xF00000, somewhere over 15 million.
14This should satisfy pathological clients without restriction, but stays
15well clear of the 0xFF000000 transition point between server and client
16IDs. It will still take an improbable amount of RAM to hit this, and a
17client could still exhaust all RAM in this way, but our goal is to prevent
18overflow and undefined behaviour.
19
20Fixes #224
21
22Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
23
24Upstream-Status: Backport
25CVE: CVE-2021-3782
26
27Reference to upstream patch:
28https://gitlab.freedesktop.org/wayland/wayland/-/commit/b19488c7154b902354cb26a27f11415d7799b0b2
29
30[DP: adjust context for wayland version 1.20.0]
31Signed-off-by: Dragos-Marian Panait <dragos.panait@windriver.com>
32---
33 src/wayland-private.h | 1 +
34 src/wayland-util.c | 25 +++++++++++++++++++++++--
35 2 files changed, 24 insertions(+), 2 deletions(-)
36
37diff --git a/src/wayland-private.h b/src/wayland-private.h
38index 9bf8cb7..35dc40e 100644
39--- a/src/wayland-private.h
40+++ b/src/wayland-private.h
41@@ -45,6 +45,7 @@
42 #define WL_MAP_SERVER_SIDE 0
43 #define WL_MAP_CLIENT_SIDE 1
44 #define WL_SERVER_ID_START 0xff000000
45+#define WL_MAP_MAX_OBJECTS 0x00f00000
46 #define WL_CLOSURE_MAX_ARGS 20
47
48 struct wl_object {
49diff --git a/src/wayland-util.c b/src/wayland-util.c
50index d5973bf..3e45d19 100644
51--- a/src/wayland-util.c
52+++ b/src/wayland-util.c
53@@ -195,6 +195,7 @@ wl_map_insert_new(struct wl_map *map, uint32_t flags, void *data)
54 union map_entry *start, *entry;
55 struct wl_array *entries;
56 uint32_t base;
57+ uint32_t count;
58
59 if (map->side == WL_MAP_CLIENT_SIDE) {
60 entries = &map->client_entries;
61@@ -215,10 +216,25 @@ wl_map_insert_new(struct wl_map *map, uint32_t flags, void *data)
62 start = entries->data;
63 }
64
65+ /* wl_array only grows, so if we have too many objects at
66+ * this point there's no way to clean up. We could be more
67+ * pro-active about trying to avoid this allocation, but
68+ * it doesn't really matter because at this point there is
69+ * nothing to be done but disconnect the client and delete
70+ * the whole array either way.
71+ */
72+ count = entry - start;
73+ if (count > WL_MAP_MAX_OBJECTS) {
74+ /* entry->data is freshly malloced garbage, so we'd
75+ * better make it a NULL so wl_map_for_each doesn't
76+ * dereference it later. */
77+ entry->data = NULL;
78+ return 0;
79+ }
80 entry->data = data;
81 entry->next |= (flags & 0x1) << 1;
82
83- return (entry - start) + base;
84+ return count + base;
85 }
86
87 int
88@@ -235,6 +251,9 @@ wl_map_insert_at(struct wl_map *map, uint32_t flags, uint32_t i, void *data)
89 i -= WL_SERVER_ID_START;
90 }
91
92+ if (i > WL_MAP_MAX_OBJECTS)
93+ return -1;
94+
95 count = entries->size / sizeof *start;
96 if (count < i)
97 return -1;
98@@ -269,8 +288,10 @@ wl_map_reserve_new(struct wl_map *map, uint32_t i)
99 i -= WL_SERVER_ID_START;
100 }
101
102- count = entries->size / sizeof *start;
103+ if (i > WL_MAP_MAX_OBJECTS)
104+ return -1;
105
106+ count = entries->size / sizeof *start;
107 if (count < i)
108 return -1;
109
110--
1112.37.3