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
|
From 345cae9c1aa7bf6752039225ef4c8d8d69fa8d76 Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Fri, 11 Aug 2023 04:09:12 +0000
Subject: [PATCH] gvariant-serialiser: Factor out code to get bounds of a tuple
member
This introduces no functional changes.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2121
CVE: CVE-2023-32665
Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/345cae9c1aa7bf6752039225ef4c8d8d69fa8d76]
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
glib/gvariant-serialiser.c | 73 ++++++++++++++++++++++++--------------
1 file changed, 46 insertions(+), 27 deletions(-)
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index fe0b1a4..6f9b366 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -942,6 +942,51 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
* for the tuple. See the notes in gvarianttypeinfo.h.
*/
+static void
+gvs_tuple_get_member_bounds (GVariantSerialised value,
+ gsize index_,
+ gsize offset_size,
+ gsize *out_member_start,
+ gsize *out_member_end)
+{
+ const GVariantMemberInfo *member_info;
+ gsize member_start, member_end;
+
+ member_info = g_variant_type_info_member_info (value.type_info, index_);
+
+ if (member_info->i + 1)
+ member_start = gvs_read_unaligned_le (value.data + value.size -
+ offset_size * (member_info->i + 1),
+ offset_size);
+ else
+ member_start = 0;
+
+ member_start += member_info->a;
+ member_start &= member_info->b;
+ member_start |= member_info->c;
+
+ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST)
+ member_end = value.size - offset_size * (member_info->i + 1);
+
+ else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED)
+ {
+ gsize fixed_size;
+
+ g_variant_type_info_query (member_info->type_info, NULL, &fixed_size);
+ member_end = member_start + fixed_size;
+ }
+
+ else /* G_VARIANT_MEMBER_ENDING_OFFSET */
+ member_end = gvs_read_unaligned_le (value.data + value.size -
+ offset_size * (member_info->i + 2),
+ offset_size);
+
+ if (out_member_start != NULL)
+ *out_member_start = member_start;
+ if (out_member_end != NULL)
+ *out_member_end = member_end;
+}
+
static gsize
gvs_tuple_n_children (GVariantSerialised value)
{
@@ -997,33 +1042,7 @@ gvs_tuple_get_child (GVariantSerialised value,
}
}
- if (member_info->i + 1)
- start = gvs_read_unaligned_le (value.data + value.size -
- offset_size * (member_info->i + 1),
- offset_size);
- else
- start = 0;
-
- start += member_info->a;
- start &= member_info->b;
- start |= member_info->c;
-
- if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST)
- end = value.size - offset_size * (member_info->i + 1);
-
- else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED)
- {
- gsize fixed_size;
-
- g_variant_type_info_query (child.type_info, NULL, &fixed_size);
- end = start + fixed_size;
- child.size = fixed_size;
- }
-
- else /* G_VARIANT_MEMBER_ENDING_OFFSET */
- end = gvs_read_unaligned_le (value.data + value.size -
- offset_size * (member_info->i + 2),
- offset_size);
+ gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end);
/* The child should not extend into the offset table. */
if (index_ != g_variant_type_info_n_members (value.type_info) - 1)
--
2.24.4
|