mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
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:
parent
c762d51134
commit
ab7e584e9f
@ -142,13 +142,13 @@
|
||||
|
||||
/* datalist pointer accesses have to be carried out atomically */
|
||||
#define G_DATALIST_GET_POINTER(datalist) \
|
||||
((GData*) ((gsize) g_atomic_pointer_get (datalist) & ~(gsize) G_DATALIST_FLAGS_MASK_INTERNAL))
|
||||
((GData*) ((guintptr) g_atomic_pointer_get (datalist) & ~(gsize) G_DATALIST_FLAGS_MASK_INTERNAL))
|
||||
|
||||
#define G_DATALIST_SET_POINTER(datalist, pointer) G_STMT_START { \
|
||||
gpointer _oldv = g_atomic_pointer_get (datalist); \
|
||||
gpointer _newv; \
|
||||
do { \
|
||||
_newv = (gpointer) (((gsize) _oldv & G_DATALIST_FLAGS_MASK_INTERNAL) | (gsize) pointer); \
|
||||
_newv = (gpointer) (((gsize) _oldv & G_DATALIST_FLAGS_MASK_INTERNAL) | (guintptr) pointer); \
|
||||
} while (!g_atomic_pointer_compare_and_exchange_full ((void**) datalist, _oldv, \
|
||||
_newv, &_oldv)); \
|
||||
} G_STMT_END
|
||||
|
@ -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;
|
||||
|
@ -257,7 +257,7 @@ g_param_spec_unref (GParamSpec *pspec)
|
||||
void
|
||||
g_param_spec_sink (GParamSpec *pspec)
|
||||
{
|
||||
gsize oldvalue;
|
||||
guintptr oldvalue;
|
||||
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
|
||||
|
||||
oldvalue = g_atomic_pointer_and (&pspec->qdata, ~(gsize)PARAM_FLOATING_FLAG);
|
||||
@ -277,7 +277,7 @@ g_param_spec_sink (GParamSpec *pspec)
|
||||
GParamSpec*
|
||||
g_param_spec_ref_sink (GParamSpec *pspec)
|
||||
{
|
||||
gsize oldvalue;
|
||||
guintptr oldvalue;
|
||||
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
|
||||
|
||||
oldvalue = g_atomic_pointer_and (&pspec->qdata, ~(gsize)PARAM_FLOATING_FLAG);
|
||||
|
Loading…
Reference in New Issue
Block a user