diff options
Diffstat (limited to 'meta/recipes-graphics/wayland/wayland/CVE-2021-3782.patch')
-rw-r--r-- | meta/recipes-graphics/wayland/wayland/CVE-2021-3782.patch | 111 |
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 @@ | |||
1 | From 5eed6609619cc2e4eaa8618d11c15d442abf54be Mon Sep 17 00:00:00 2001 | ||
2 | From: Derek Foreman <derek.foreman@collabora.com> | ||
3 | Date: Fri, 28 Jan 2022 13:18:37 -0600 | ||
4 | Subject: [PATCH] util: Limit size of wl_map | ||
5 | |||
6 | Since server IDs are basically indistinguishable from really big client | ||
7 | IDs at many points in the source, it's theoretically possible to overflow | ||
8 | a map and either overflow server IDs into the client ID space, or grow | ||
9 | client IDs into the server ID space. This would currently take a massive | ||
10 | amount of RAM, but the definition of massive changes yearly. | ||
11 | |||
12 | Prevent this by placing a ridiculous but arbitrary upper bound on the | ||
13 | number of items we can put in a map: 0xF00000, somewhere over 15 million. | ||
14 | This should satisfy pathological clients without restriction, but stays | ||
15 | well clear of the 0xFF000000 transition point between server and client | ||
16 | IDs. It will still take an improbable amount of RAM to hit this, and a | ||
17 | client could still exhaust all RAM in this way, but our goal is to prevent | ||
18 | overflow and undefined behaviour. | ||
19 | |||
20 | Fixes #224 | ||
21 | |||
22 | Signed-off-by: Derek Foreman <derek.foreman@collabora.com> | ||
23 | |||
24 | Upstream-Status: Backport | ||
25 | CVE: CVE-2021-3782 | ||
26 | |||
27 | Reference to upstream patch: | ||
28 | https://gitlab.freedesktop.org/wayland/wayland/-/commit/b19488c7154b902354cb26a27f11415d7799b0b2 | ||
29 | |||
30 | [DP: adjust context for wayland version 1.20.0] | ||
31 | Signed-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 | |||
37 | diff --git a/src/wayland-private.h b/src/wayland-private.h | ||
38 | index 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 { | ||
49 | diff --git a/src/wayland-util.c b/src/wayland-util.c | ||
50 | index 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 | -- | ||
111 | 2.37.3 | ||