glib2/SOURCES/CVE-2025-4373.patch

434 lines
16 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 6c2178a3bc216a6cc765fc6ba3b0e6d22ce5af7e Mon Sep 17 00:00:00 2001
From: Emmanuel Fleury <emmanuel.fleury@u-bordeaux.fr>
Date: Mon, 4 Feb 2019 13:31:28 +0100
Subject: [PATCH 1/3] Fixing various warnings in glib/gstring.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gstring.c: In function g_string_insert_len:
glib/gstring.c:441:31: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
g_return_val_if_fail (pos <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro G_LIKELY
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:441:5: note: in expansion of macro g_return_val_if_fail
g_return_val_if_fail (pos <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:458:15: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
if (pos < string->len)
^
glib/gstring.c:462:18: error: comparison of integer expressions of different signedness: gsize {aka long unsigned int} and gssize {aka long int} [-Werror=sign-compare]
if (offset < pos)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gmacros.h:351:26: error: comparison of integer expressions of different signedness: gssize {aka long int} and long unsigned int [-Werror=sign-compare]
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
^
glib/gstring.c:464:22: note: in expansion of macro MIN
precount = MIN (len, pos - offset);
^~~
glib/gmacros.h:351:35: error: operand of ?: changes signedness from gssize {aka long int} to long unsigned int due to unsignedness of other operand [-Werror=sign-compare]
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
^~~
glib/gstring.c:464:22: note: in expansion of macro MIN
precount = MIN (len, pos - offset);
^~~
glib/gstring.c:469:15: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
if (len > precount)
^
glib/gstring.c:481:15: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
if (pos < string->len)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gstring.c: In function g_string_insert_c:
glib/gstring.c:782:31: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
g_return_val_if_fail (pos <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro G_LIKELY
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:782:5: note: in expansion of macro g_return_val_if_fail
g_return_val_if_fail (pos <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:785:11: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
if (pos < string->len)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gstring.c: In function g_string_insert_unichar:
glib/gstring.c:857:31: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
g_return_val_if_fail (pos <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro G_LIKELY
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:857:5: note: in expansion of macro g_return_val_if_fail
g_return_val_if_fail (pos <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:860:11: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
if (pos < string->len)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gstring.c: In function g_string_erase:
glib/gstring.c:969:29: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
g_return_val_if_fail (pos <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro G_LIKELY
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:969:3: note: in expansion of macro g_return_val_if_fail
g_return_val_if_fail (pos <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:975:39: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
g_return_val_if_fail (pos + len <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro G_LIKELY
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:975:7: note: in expansion of macro g_return_val_if_fail
g_return_val_if_fail (pos + len <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:977:21: error: comparison of integer expressions of different signedness: gssize {aka long int} and gsize {aka long unsigned int} [-Werror=sign-compare]
if (pos + len < string->len)
^
---
glib/gstring.c | 82 +++++++++++++++++++++++++++++++-------------------
1 file changed, 51 insertions(+), 31 deletions(-)
diff --git a/glib/gstring.c b/glib/gstring.c
index 966502019..f5bfeb0ed 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -426,6 +426,8 @@ g_string_insert_len (GString *string,
const gchar *val,
gssize len)
{
+ gsize len_unsigned, pos_unsigned;
+
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (len == 0 || val != NULL, string);
@@ -434,11 +436,15 @@ g_string_insert_len (GString *string,
if (len < 0)
len = strlen (val);
+ len_unsigned = len;
if (pos < 0)
- pos = string->len;
+ pos_unsigned = string->len;
else
- g_return_val_if_fail (pos <= string->len, string);
+ {
+ pos_unsigned = pos;
+ g_return_val_if_fail (pos_unsigned <= string->len, string);
+ }
/* Check whether val represents a substring of string.
* This test probably violates chapter and verse of the C standards,
@@ -450,45 +456,48 @@ g_string_insert_len (GString *string,
gsize offset = val - string->str;
gsize precount = 0;
- g_string_maybe_expand (string, len);
+ g_string_maybe_expand (string, len_unsigned);
val = string->str + offset;
/* At this point, val is valid again. */
/* Open up space where we are going to insert. */
- if (pos < string->len)
- memmove (string->str + pos + len, string->str + pos, string->len - pos);
+ if (pos_unsigned < string->len)
+ memmove (string->str + pos_unsigned + len_unsigned,
+ string->str + pos_unsigned, string->len - pos_unsigned);
/* Move the source part before the gap, if any. */
- if (offset < pos)
+ if (offset < pos_unsigned)
{
- precount = MIN (len, pos - offset);
- memcpy (string->str + pos, val, precount);
+ precount = MIN (len_unsigned, pos_unsigned - offset);
+ memcpy (string->str + pos_unsigned, val, precount);
}
/* Move the source part after the gap, if any. */
- if (len > precount)
- memcpy (string->str + pos + precount,
- val + /* Already moved: */ precount + /* Space opened up: */ len,
- len - precount);
+ if (len_unsigned > precount)
+ memcpy (string->str + pos_unsigned + precount,
+ val + /* Already moved: */ precount +
+ /* Space opened up: */ len_unsigned,
+ len_unsigned - precount);
}
else
{
- g_string_maybe_expand (string, len);
+ g_string_maybe_expand (string, len_unsigned);
/* If we aren't appending at the end, move a hunk
* of the old string to the end, opening up space
*/
- if (pos < string->len)
- memmove (string->str + pos + len, string->str + pos, string->len - pos);
+ if (pos_unsigned < string->len)
+ memmove (string->str + pos_unsigned + len_unsigned,
+ string->str + pos_unsigned, string->len - pos_unsigned);
/* insert the new string */
- if (len == 1)
- string->str[pos] = *val;
+ if (len_unsigned == 1)
+ string->str[pos_unsigned] = *val;
else
- memcpy (string->str + pos, val, len);
+ memcpy (string->str + pos_unsigned, val, len_unsigned);
}
- string->len += len;
+ string->len += len_unsigned;
string->str[string->len] = 0;
@@ -772,6 +781,8 @@ g_string_insert_c (GString *string,
gssize pos,
gchar c)
{
+ gsize pos_unsigned;
+
g_return_val_if_fail (string != NULL, NULL);
g_string_maybe_expand (string, 1);
@@ -779,13 +790,15 @@ g_string_insert_c (GString *string,
if (pos < 0)
pos = string->len;
else
- g_return_val_if_fail (pos <= string->len, string);
+ g_return_val_if_fail ((gsize) pos <= string->len, string);
+ pos_unsigned = pos;
/* If not just an append, move the old stuff */
- if (pos < string->len)
- memmove (string->str + pos + 1, string->str + pos, string->len - pos);
+ if (pos_unsigned < string->len)
+ memmove (string->str + pos_unsigned + 1,
+ string->str + pos_unsigned, string->len - pos_unsigned);
- string->str[pos] = c;
+ string->str[pos_unsigned] = c;
string->len += 1;
@@ -854,10 +867,10 @@ g_string_insert_unichar (GString *string,
if (pos < 0)
pos = string->len;
else
- g_return_val_if_fail (pos <= string->len, string);
+ g_return_val_if_fail ((gsize) pos <= string->len, string);
/* If not just an append, move the old stuff */
- if (pos < string->len)
+ if ((gsize) pos < string->len)
memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
dest = string->str + pos;
@@ -964,21 +977,28 @@ g_string_erase (GString *string,
gssize pos,
gssize len)
{
+ gsize len_unsigned, pos_unsigned;
+
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (pos >= 0, string);
- g_return_val_if_fail (pos <= string->len, string);
+ pos_unsigned = pos;
+
+ g_return_val_if_fail (pos_unsigned <= string->len, string);
if (len < 0)
- len = string->len - pos;
+ len_unsigned = string->len - pos_unsigned;
else
{
- g_return_val_if_fail (pos + len <= string->len, string);
+ len_unsigned = len;
+ g_return_val_if_fail (pos_unsigned + len_unsigned <= string->len, string);
- if (pos + len < string->len)
- memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
+ if (pos_unsigned + len_unsigned < string->len)
+ memmove (string->str + pos_unsigned,
+ string->str + pos_unsigned + len_unsigned,
+ string->len - (pos_unsigned + len_unsigned));
}
- string->len -= len;
+ string->len -= len_unsigned;
string->str[string->len] = 0;
--
2.50.0
From 101afb01778659cb7051b3cb33d55dc965c8dc7e Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@redhat.com>
Date: Thu, 10 Apr 2025 10:57:20 -0500
Subject: [PATCH 2/3] gstring: carefully handle gssize parameters
Wherever we use gssize to allow passing -1, we need to ensure we don't
overflow the value by assigning a gsize to it without checking if the
size exceeds the maximum gssize. The safest way to do this is to just
use normal gsize everywhere instead and use gssize only for the
parameter.
Our computers don't have enough RAM to write tests for this. I tried
forcing string->len to high values for test purposes, but this isn't
valid and will just cause out of bounds reads/writes due to
string->allocated_len being unexpectedly small, so I don't think we can
test this easily.
---
glib/gstring.c | 36 +++++++++++++++++++++++-------------
1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/glib/gstring.c b/glib/gstring.c
index f5bfeb0ed..84a98da25 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -435,8 +435,9 @@ g_string_insert_len (GString *string,
return string;
if (len < 0)
- len = strlen (val);
- len_unsigned = len;
+ len_unsigned = strlen (val);
+ else
+ len_unsigned = len;
if (pos < 0)
pos_unsigned = string->len;
@@ -788,10 +789,12 @@ g_string_insert_c (GString *string,
g_string_maybe_expand (string, 1);
if (pos < 0)
- pos = string->len;
+ pos_unsigned = string->len;
else
- g_return_val_if_fail ((gsize) pos <= string->len, string);
- pos_unsigned = pos;
+ {
+ pos_unsigned = pos;
+ g_return_val_if_fail (pos_unsigned <= string->len, string);
+ }
/* If not just an append, move the old stuff */
if (pos_unsigned < string->len)
@@ -824,6 +827,7 @@ g_string_insert_unichar (GString *string,
gssize pos,
gunichar wc)
{
+ gsize pos_unsigned;
gint charlen, first, i;
gchar *dest;
@@ -865,15 +869,18 @@ g_string_insert_unichar (GString *string,
g_string_maybe_expand (string, charlen);
if (pos < 0)
- pos = string->len;
+ pos_unsigned = string->len;
else
- g_return_val_if_fail ((gsize) pos <= string->len, string);
+ {
+ pos_unsigned = pos;
+ g_return_val_if_fail (pos_unsigned <= string->len, string);
+ }
/* If not just an append, move the old stuff */
- if ((gsize) pos < string->len)
- memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
+ if (pos_unsigned < string->len)
+ memmove (string->str + pos_unsigned + charlen, string->str + pos_unsigned, string->len - pos_unsigned);
- dest = string->str + pos;
+ dest = string->str + pos_unsigned;
/* Code copied from g_unichar_to_utf() */
for (i = charlen - 1; i > 0; --i)
{
@@ -931,6 +938,7 @@ g_string_overwrite_len (GString *string,
const gchar *val,
gssize len)
{
+ gssize len_unsigned;
gsize end;
g_return_val_if_fail (string != NULL, NULL);
@@ -942,14 +950,16 @@ g_string_overwrite_len (GString *string,
g_return_val_if_fail (pos <= string->len, string);
if (len < 0)
- len = strlen (val);
+ len_unsigned = strlen (val);
+ else
+ len_unsigned = len;
- end = pos + len;
+ end = pos + len_unsigned;
if (end > string->len)
g_string_maybe_expand (string, end - string->len);
- memcpy (string->str + pos, val, len);
+ memcpy (string->str + pos, val, len_unsigned);
if (end > string->len)
{
--
2.50.0
From 789c240db9738cae37ee77f7e135e5dbc39ab3ca Mon Sep 17 00:00:00 2001
From: Peter Bloomfield <peterbloomfield@bellsouth.net>
Date: Fri, 11 Apr 2025 05:52:33 +0000
Subject: [PATCH 3/3] gstring: Make len_unsigned unsigned
---
glib/gstring.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/glib/gstring.c b/glib/gstring.c
index 84a98da25..7379517f5 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -938,7 +938,7 @@ g_string_overwrite_len (GString *string,
const gchar *val,
gssize len)
{
- gssize len_unsigned;
+ gsize len_unsigned;
gsize end;
g_return_val_if_fail (string != NULL, NULL);
--
2.50.0