Cast via guintptr when adding/removing bitsflags on pointers

Round-tripping pointers via gsize is not guaranteed to work (the C standard
only requires this for (u)inptr_t) and in fact breaks on CHERI-enabled
systems such as Arm Morello where pointers are 128-bits but size_t is 64.
This means the current casts would strip the high bits of the pointer and
return a non-dereferenceable value. Fix this by casting the operand that
holds the pointer to guintptr instead of gsize.

Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842
This commit is contained in:
Alex Richardson
2022-12-14 23:55:18 +00:00
parent c762d51134
commit ab7e584e9f
3 changed files with 6 additions and 6 deletions

View File

@@ -3447,7 +3447,7 @@ object_floating_flag_handler (GObject *object,
oldvalue = g_atomic_pointer_get (&object->qdata);
while (!g_atomic_pointer_compare_and_exchange_full (
(void**) &object->qdata, oldvalue,
(void *) ((gsize) oldvalue | OBJECT_FLOATING_FLAG),
(void *) ((guintptr) oldvalue | OBJECT_FLOATING_FLAG),
&oldvalue))
;
return (gsize) oldvalue & OBJECT_FLOATING_FLAG;
@@ -3455,7 +3455,7 @@ object_floating_flag_handler (GObject *object,
oldvalue = g_atomic_pointer_get (&object->qdata);
while (!g_atomic_pointer_compare_and_exchange_full (
(void**) &object->qdata, oldvalue,
(void *) ((gsize) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG),
(void *) ((guintptr) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG),
&oldvalue))
;
return (gsize) oldvalue & OBJECT_FLOATING_FLAG;