diff options
| -rw-r--r-- | meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32636.patch | 50 | ||||
| -rw-r--r-- | meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch | 155 | ||||
| -rw-r--r-- | meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb | 2 |
3 files changed, 207 insertions, 0 deletions
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32636.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32636.patch new file mode 100644 index 0000000000..311993625a --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32636.patch | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | From 21a204147b16539b3eda3143b32844c49e29f4d4 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Philip Withnall <pwithnall@endlessos.org> | ||
| 3 | Date: Thu, 17 Aug 2023 11:33:49 +0000 | ||
| 4 | Subject: [PATCH] gvariant: Propagate trust when getting a child of a | ||
| 5 | serialised variant | ||
| 6 | |||
| 7 | If a variant is trusted, that means all its children are trusted, so | ||
| 8 | ensure that their checked offsets are set as such. | ||
| 9 | |||
| 10 | This allows a lot of the offset table checks to be avoided when getting | ||
| 11 | children from trusted serialised tuples, which speeds things up. | ||
| 12 | |||
| 13 | No unit test is included because this is just a performance fix. If | ||
| 14 | there are other slownesses, or regressions, in serialised `GVariant` | ||
| 15 | performance, the fuzzing setup will catch them like it did this one. | ||
| 16 | |||
| 17 | This change does reduce the time to run the oss-fuzz reproducer from 80s | ||
| 18 | to about 0.7s on my machine. | ||
| 19 | |||
| 20 | Signed-off-by: Philip Withnall <pwithnall@endlessos.org> | ||
| 21 | |||
| 22 | Fixes: #2841 | ||
| 23 | oss-fuzz#54314 | ||
| 24 | |||
| 25 | CVE: CVE-2023-32636 | ||
| 26 | |||
| 27 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/21a204147b16539b3eda3143b32844c49e29f4d4] | ||
| 28 | |||
| 29 | Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> | ||
| 30 | --- | ||
| 31 | glib/gvariant-core.c | 4 ++-- | ||
| 32 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
| 33 | |||
| 34 | diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c | ||
| 35 | index 7b71efc..a2c7d2d 100644 | ||
| 36 | --- a/glib/gvariant-core.c | ||
| 37 | +++ b/glib/gvariant-core.c | ||
| 38 | @@ -1195,8 +1195,8 @@ g_variant_get_child_value (GVariant *value, | ||
| 39 | child->contents.serialised.bytes = | ||
| 40 | g_bytes_ref (value->contents.serialised.bytes); | ||
| 41 | child->contents.serialised.data = s_child.data; | ||
| 42 | - child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to; | ||
| 43 | - child->contents.serialised.checked_offsets_up_to = s_child.checked_offsets_up_to; | ||
| 44 | + child->contents.serialised.ordered_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.ordered_offsets_up_to; | ||
| 45 | + child->contents.serialised.checked_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.checked_offsets_up_to; | ||
| 46 | |||
| 47 | return child; | ||
| 48 | } | ||
| 49 | -- | ||
| 50 | 2.40.0 | ||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch new file mode 100644 index 0000000000..b5cb4273b6 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch | |||
| @@ -0,0 +1,155 @@ | |||
| 1 | From 78da5faccb3e065116b75b3ff87ff55381da6c76 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Philip Withnall <pwithnall@endlessos.org> | ||
| 3 | Date: Thu, 17 Aug 2023 11:24:43 +0000 | ||
| 4 | Subject: [PATCH] gvariant: Check offset table doesn't fall outside variant | ||
| 5 | bounds | ||
| 6 | |||
| 7 | When dereferencing the first entry in the offset table for a tuple, | ||
| 8 | check that it doesn’t fall outside the bounds of the variant first. | ||
| 9 | |||
| 10 | This prevents an out-of-bounds read from some non-normal tuples. | ||
| 11 | |||
| 12 | This bug was introduced in commit 73d0aa81c2575a5c9ae77d. | ||
| 13 | |||
| 14 | Includes a unit test, although the test will likely only catch the | ||
| 15 | original bug if run with asan enabled. | ||
| 16 | |||
| 17 | Signed-off-by: Philip Withnall <pwithnall@endlessos.org> | ||
| 18 | |||
| 19 | Fixes: #2840 | ||
| 20 | oss-fuzz#54302 | ||
| 21 | |||
| 22 | CVE: CVE-2023-32643 | ||
| 23 | |||
| 24 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/78da5faccb3e065116b75b3ff87ff55381da6c76] | ||
| 25 | |||
| 26 | Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> | ||
| 27 | --- | ||
| 28 | glib/gvariant-serialiser.c | 12 ++++++-- | ||
| 29 | glib/tests/gvariant.c | 63 ++++++++++++++++++++++++++++++++++++++ | ||
| 30 | 2 files changed, 72 insertions(+), 3 deletions(-) | ||
| 31 | |||
| 32 | diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c | ||
| 33 | index 3d6e7b8..5abb87e 100644 | ||
| 34 | --- a/glib/gvariant-serialiser.c | ||
| 35 | +++ b/glib/gvariant-serialiser.c | ||
| 36 | @@ -979,7 +979,8 @@ gvs_tuple_get_member_bounds (GVariantSerialised value, | ||
| 37 | |||
| 38 | member_info = g_variant_type_info_member_info (value.type_info, index_); | ||
| 39 | |||
| 40 | - if (member_info->i + 1) | ||
| 41 | + if (member_info->i + 1 && | ||
| 42 | + offset_size * (member_info->i + 1) <= value.size) | ||
| 43 | member_start = gvs_read_unaligned_le (value.data + value.size - | ||
| 44 | offset_size * (member_info->i + 1), | ||
| 45 | offset_size); | ||
| 46 | @@ -990,7 +991,8 @@ gvs_tuple_get_member_bounds (GVariantSerialised value, | ||
| 47 | member_start &= member_info->b; | ||
| 48 | member_start |= member_info->c; | ||
| 49 | |||
| 50 | - if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST) | ||
| 51 | + if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST && | ||
| 52 | + offset_size * (member_info->i + 1) <= value.size) | ||
| 53 | member_end = value.size - offset_size * (member_info->i + 1); | ||
| 54 | |||
| 55 | else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) | ||
| 56 | @@ -1001,11 +1003,15 @@ gvs_tuple_get_member_bounds (GVariantSerialised value, | ||
| 57 | member_end = member_start + fixed_size; | ||
| 58 | } | ||
| 59 | |||
| 60 | - else /* G_VARIANT_MEMBER_ENDING_OFFSET */ | ||
| 61 | + else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET && | ||
| 62 | + offset_size * (member_info->i + 2) <= value.size) | ||
| 63 | member_end = gvs_read_unaligned_le (value.data + value.size - | ||
| 64 | offset_size * (member_info->i + 2), | ||
| 65 | offset_size); | ||
| 66 | |||
| 67 | + else /* invalid */ | ||
| 68 | + member_end = G_MAXSIZE; | ||
| 69 | + | ||
| 70 | if (out_member_start != NULL) | ||
| 71 | *out_member_start = member_start; | ||
| 72 | if (out_member_end != NULL) | ||
| 73 | diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c | ||
| 74 | index 43091f2..ab0361a 100644 | ||
| 75 | --- a/glib/tests/gvariant.c | ||
| 76 | +++ b/glib/tests/gvariant.c | ||
| 77 | @@ -5416,6 +5416,67 @@ test_normal_checking_tuple_offsets4 (void) | ||
| 78 | g_variant_unref (variant); | ||
| 79 | } | ||
| 80 | |||
| 81 | +/* This is a regression test that dereferencing the first element in the offset | ||
| 82 | + * table doesn’t dereference memory before the start of the GVariant. The first | ||
| 83 | + * element in the offset table gives the offset of the final member in the | ||
| 84 | + * tuple (the offset table is stored in reverse), and the position of this final | ||
| 85 | + * member is needed to check that none of the tuple members overlap with the | ||
| 86 | + * offset table | ||
| 87 | + * | ||
| 88 | + * See https://gitlab.gnome.org/GNOME/glib/-/issues/2840 */ | ||
| 89 | +static void | ||
| 90 | +test_normal_checking_tuple_offsets5 (void) | ||
| 91 | +{ | ||
| 92 | + /* A tuple of type (sss) in normal form would have an offset table with two | ||
| 93 | + * entries: | ||
| 94 | + * - The first entry (lowest index in the table) gives the offset of the | ||
| 95 | + * third `s` in the tuple, as the offset table is reversed compared to the | ||
| 96 | + * tuple members. | ||
| 97 | + * - The second entry (highest index in the table) gives the offset of the | ||
| 98 | + * second `s` in the tuple. | ||
| 99 | + * - The offset of the first `s` in the tuple is always 0. | ||
| 100 | + * | ||
| 101 | + * See §2.5.4 (Structures) of the GVariant specification for details, noting | ||
| 102 | + * that the table is only layed out this way because all three members of the | ||
| 103 | + * tuple have non-fixed sizes. | ||
| 104 | + * | ||
| 105 | + * It’s not clear whether the 0xaa data of this variant is part of the strings | ||
| 106 | + * in the tuple, or part of the offset table. It doesn’t really matter. This | ||
| 107 | + * is a regression test to check that the code to validate the offset table | ||
| 108 | + * doesn’t unconditionally try to access the first entry in the offset table | ||
| 109 | + * by subtracting the table size from the end of the GVariant data. | ||
| 110 | + * | ||
| 111 | + * In this non-normal case, that would result in an address off the start of | ||
| 112 | + * the GVariant data, and an out-of-bounds read, because the GVariant is one | ||
| 113 | + * byte long, but the offset table is calculated as two bytes long (with 1B | ||
| 114 | + * sized entries) from the tuple’s type. | ||
| 115 | + */ | ||
| 116 | + const GVariantType *data_type = G_VARIANT_TYPE ("(sss)"); | ||
| 117 | + const guint8 data[] = { 0xaa }; | ||
| 118 | + gsize size = sizeof (data); | ||
| 119 | + GVariant *variant = NULL; | ||
| 120 | + GVariant *normal_variant = NULL; | ||
| 121 | + GVariant *expected = NULL; | ||
| 122 | + | ||
| 123 | + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2840"); | ||
| 124 | + | ||
| 125 | + variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL); | ||
| 126 | + g_assert_nonnull (variant); | ||
| 127 | + | ||
| 128 | + g_assert_false (g_variant_is_normal_form (variant)); | ||
| 129 | + | ||
| 130 | + normal_variant = g_variant_get_normal_form (variant); | ||
| 131 | + g_assert_nonnull (normal_variant); | ||
| 132 | + | ||
| 133 | + expected = g_variant_new_parsed ("('', '', '')"); | ||
| 134 | + g_assert_cmpvariant (expected, variant); | ||
| 135 | + g_assert_cmpvariant (expected, normal_variant); | ||
| 136 | + | ||
| 137 | + g_variant_unref (expected); | ||
| 138 | + g_variant_unref (normal_variant); | ||
| 139 | + g_variant_unref (variant); | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | /* Test that an otherwise-valid serialised GVariant is considered non-normal if | ||
| 143 | * its offset table entries are too wide. | ||
| 144 | * | ||
| 145 | @@ -5663,6 +5724,8 @@ main (int argc, char **argv) | ||
| 146 | test_normal_checking_tuple_offsets3); | ||
| 147 | g_test_add_func ("/gvariant/normal-checking/tuple-offsets4", | ||
| 148 | test_normal_checking_tuple_offsets4); | ||
| 149 | + g_test_add_func ("/gvariant/normal-checking/tuple-offsets5", | ||
| 150 | + test_normal_checking_tuple_offsets5); | ||
| 151 | g_test_add_func ("/gvariant/normal-checking/tuple-offsets/minimal-sized", | ||
| 152 | test_normal_checking_tuple_offsets_minimal_sized); | ||
| 153 | g_test_add_func ("/gvariant/normal-checking/empty-object-path", | ||
| 154 | -- | ||
| 155 | 2.40.0 | ||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb b/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb index 3545e6675a..24c590a714 100644 --- a/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb +++ b/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb | |||
| @@ -29,6 +29,8 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \ | |||
| 29 | file://CVE-2023-29499.patch \ | 29 | file://CVE-2023-29499.patch \ |
| 30 | file://CVE-2023-32611-0001.patch \ | 30 | file://CVE-2023-32611-0001.patch \ |
| 31 | file://CVE-2023-32611-0002.patch \ | 31 | file://CVE-2023-32611-0002.patch \ |
| 32 | file://CVE-2023-32643.patch \ | ||
| 33 | file://CVE-2023-32636.patch \ | ||
| 32 | " | 34 | " |
| 33 | SRC_URI:append:class-native = " file://relocate-modules.patch" | 35 | SRC_URI:append:class-native = " file://relocate-modules.patch" |
| 34 | 36 | ||
