[pygobject/pygobject-3-26] closure: Fix unaligned and out-of-bounds access
- From: Christoph Reiter <creiter src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/pygobject-3-26] closure: Fix unaligned and out-of-bounds access
- Date: Sun, 15 Oct 2017 19:28:55 +0000 (UTC)
commit 5f0f3b330cfa1eb11db4f376d141445847cb9d16
Author: James Clarke <jrtc27 jrtc27 com>
Date: Fri Oct 13 18:04:45 2017 +0100
closure: Fix unaligned and out-of-bounds access
When the direction is FROM_PYTHON, a whole GIArgument was being loaded
from the address given by the argument, but like any other case, this
could point to different types, and so could run off the end of the
pointed-to value, and, more importantly, be performing an unaligned
access, causing it to crash with SIGBUS on sparc64 when running
test_callback_scope_call_array_inout. Instead, reuse the existing code
for the TO_PYTHON case to do the copying into arg_value based on the
type.
https://bugzilla.gnome.org/show_bug.cgi?id=788894
gi/pygi-closure.c | 40 +++++++++++++++++++++-------------------
1 files changed, 21 insertions(+), 19 deletions(-)
---
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index 03bd050..b51c04c 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -208,6 +208,7 @@ _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
+ gpointer arg_pointer;
if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
state[i].arg_value.v_pointer = * (gpointer *) args[i];
@@ -216,46 +217,47 @@ _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
continue;
state[i].arg_pointer.v_pointer = state[i].arg_value.v_pointer;
- state[i].arg_value = *(GIArgument *) state[i].arg_value.v_pointer;
- continue;
+ arg_pointer = state[i].arg_value.v_pointer;
+ } else {
+ arg_pointer = args[i];
}
switch (arg_cache->type_tag) {
case GI_TYPE_TAG_BOOLEAN:
- state[i].arg_value.v_boolean = * (gboolean *) args[i];
+ state[i].arg_value.v_boolean = * (gboolean *) arg_pointer;
break;
case GI_TYPE_TAG_INT8:
- state[i].arg_value.v_int8 = * (gint8 *) args[i];
+ state[i].arg_value.v_int8 = * (gint8 *) arg_pointer;
break;
case GI_TYPE_TAG_UINT8:
- state[i].arg_value.v_uint8 = * (guint8 *) args[i];
+ state[i].arg_value.v_uint8 = * (guint8 *) arg_pointer;
break;
case GI_TYPE_TAG_INT16:
- state[i].arg_value.v_int16 = * (gint16 *) args[i];
+ state[i].arg_value.v_int16 = * (gint16 *) arg_pointer;
break;
case GI_TYPE_TAG_UINT16:
- state[i].arg_value.v_uint16 = * (guint16 *) args[i];
+ state[i].arg_value.v_uint16 = * (guint16 *) arg_pointer;
break;
case GI_TYPE_TAG_INT32:
- state[i].arg_value.v_int32 = * (gint32 *) args[i];
+ state[i].arg_value.v_int32 = * (gint32 *) arg_pointer;
break;
case GI_TYPE_TAG_UINT32:
- state[i].arg_value.v_uint32 = * (guint32 *) args[i];
+ state[i].arg_value.v_uint32 = * (guint32 *) arg_pointer;
break;
case GI_TYPE_TAG_INT64:
- state[i].arg_value.v_int64 = * (glong *) args[i];
+ state[i].arg_value.v_int64 = * (glong *) arg_pointer;
break;
case GI_TYPE_TAG_UINT64:
- state[i].arg_value.v_uint64 = * (glong *) args[i];
+ state[i].arg_value.v_uint64 = * (glong *) arg_pointer;
break;
case GI_TYPE_TAG_FLOAT:
- state[i].arg_value.v_float = * (gfloat *) args[i];
+ state[i].arg_value.v_float = * (gfloat *) arg_pointer;
break;
case GI_TYPE_TAG_DOUBLE:
- state[i].arg_value.v_double = * (gdouble *) args[i];
+ state[i].arg_value.v_double = * (gdouble *) arg_pointer;
break;
case GI_TYPE_TAG_UTF8:
- state[i].arg_value.v_string = * (gchar **) args[i];
+ state[i].arg_value.v_string = * (gchar **) arg_pointer;
break;
case GI_TYPE_TAG_INTERFACE:
{
@@ -266,16 +268,16 @@ _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
interface_type = g_base_info_get_type (interface);
if (interface_type == GI_INFO_TYPE_ENUM) {
- state[i].arg_value.v_int = * (gint *) args[i];
+ state[i].arg_value.v_int = * (gint *) arg_pointer;
} else if (interface_type == GI_INFO_TYPE_FLAGS) {
- state[i].arg_value.v_uint = * (guint *) args[i];
+ state[i].arg_value.v_uint = * (guint *) arg_pointer;
} else {
- state[i].arg_value.v_pointer = * (gpointer *) args[i];
+ state[i].arg_value.v_pointer = * (gpointer *) arg_pointer;
}
break;
}
case GI_TYPE_TAG_UNICHAR:
- state[i].arg_value.v_uint32 = * (guint32 *) args[i];
+ state[i].arg_value.v_uint32 = * (guint32 *) arg_pointer;
break;
case GI_TYPE_TAG_ERROR:
case GI_TYPE_TAG_GHASH:
@@ -283,7 +285,7 @@ _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
case GI_TYPE_TAG_GSLIST:
case GI_TYPE_TAG_ARRAY:
case GI_TYPE_TAG_VOID:
- state[i].arg_value.v_pointer = * (gpointer *) args[i];
+ state[i].arg_value.v_pointer = * (gpointer *) arg_pointer;
break;
default:
g_warning ("Unhandled type tag %s",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]