Fix: Python bindings array access functions write out of bounds
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 16 Sep 2013 23:59:00 +0000 (19:59 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 13 Nov 2013 02:57:16 +0000 (21:57 -0500)
The array access functions in the Python complements are writing
past the last element to add a NULL pointer and then using it from the
Python code to detect the end of the array. This may cause stability
issues.

This changes the functions to return multiple values (array and length)
in Python using SWIG's built-in OUTPUT typemaps.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
bindings/python/babeltrace.i.in
bindings/python/python-complements.c
bindings/python/python-complements.h

index 725940c96ca8f9691f94c61abdd49483c79cba96..a2ba374db185067dca24b2a7d597b11a0f0d1ff4 100644 (file)
@@ -54,6 +54,36 @@ typedef unsigned long long uint64_t;
 typedef long long int64_t;
 typedef int bt_intern_str;
 
+/* =================================================================
+               PYTHON-COMPLEMENTS.H
+               ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+*/
+
+FILE *_bt_file_open(char *file_path, char *mode);
+void _bt_file_close(FILE *fp);
+struct bt_definition **_bt_python_field_listcaller(
+               const struct bt_ctf_event *ctf_event,
+               const struct bt_definition *scope,
+               unsigned int *OUTPUT);
+struct bt_definition *_bt_python_field_one_from_list(
+               struct bt_definition **list, int index);
+struct bt_ctf_event_decl **_bt_python_event_decl_listcaller(
+               int handle_id,
+               struct bt_context *ctx,
+               unsigned int *OUTPUT);
+struct bt_ctf_event_decl *_bt_python_decl_one_from_list(
+               struct bt_ctf_event_decl **list, int index);
+struct bt_ctf_field_decl **_by_python_field_decl_listcaller(
+               struct bt_ctf_event_decl *event_decl,
+               enum bt_ctf_scope scope,
+               unsigned int *OUTPUT);
+struct bt_ctf_field_decl *_bt_python_field_decl_one_from_list(
+               struct bt_ctf_field_decl **list, int index);
+struct definition_array *_bt_python_get_array_from_def(
+               struct bt_definition *field);
+struct definition_sequence *_bt_python_get_sequence_from_def(
+               struct bt_definition *field);
+
 /* =================================================================
                CONTEXT.H, CONTEXT-INTERNAL.H
                ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
@@ -816,7 +846,7 @@ class ctf:
                        Return None on error.
                        """
                        try:
-                               field_lc = _bt_python_field_listcaller(self._e, scope._d)
+                               field_lc, count = _bt_python_field_listcaller(self._e, scope._d)
                        except AttributeError:
                                raise TypeError("in get_field_list, argument 2 must be a "
                                        "Definition (scope) instance")
@@ -825,19 +855,12 @@ class ctf:
                                return None
 
                        def_list = []
-                       i = 0
-                       while True:
+                       for i in range(count):
                                tmp = ctf.Definition.__new__(ctf.Definition)
                                tmp._d = _bt_python_field_one_from_list(field_lc, i)
-
-                               if tmp._d is None:
-                                       #Last item of list is None, assured in
-                                       #_bt_python_field_listcaller
-                                       break
-
                                tmp._s = scope
                                def_list.append(tmp)
-                               i += 1
+
                        return def_list
 
                def get_field_list(self):
@@ -1201,7 +1224,7 @@ class ctf:
                                raise TypeError("in get_event_decl_list, "
                                        "argument 1 must be a TraceHandle instance")
                try:
-                       ptr_list = _bt_python_event_decl_listcaller(handle_id, context._c)
+                       ptr_list, count = _bt_python_event_decl_listcaller(handle_id, context._c)
                except AttributeError:
                                raise TypeError("in get_event_decl_list, "
                                        "argument 2 must be a Context instance")
@@ -1210,17 +1233,11 @@ class ctf:
                        return None
 
                decl_list = []
-               i = 0
-               while True:
+               for i in range(count):
                        tmp = ctf.EventDecl.__new__(ctf.EventDecl)
                        tmp._d =  _bt_python_decl_one_from_list(ptr_list, i)
-
-                       if tmp._d is None:
-                               #Last item of list is None
-                               break
-
                        decl_list.append(tmp)
-                       i += 1
+
                return decl_list
 
 %}
@@ -1233,8 +1250,6 @@ class ctf:
 //                        python-complements.h
 // =================================================================
 
-%include python-complements.c
-
 %pythoncode %{
 
 class File(object):
index 3ef0a23af284171bef5bb12bab540cd18c0aad1b..5c65fb0f0e37f2044a0518faf95d798fff364ffa 100644 (file)
@@ -46,19 +46,17 @@ void _bt_file_close(FILE *fp)
 /* ctf-field-list */
 struct bt_definition **_bt_python_field_listcaller(
                const struct bt_ctf_event *ctf_event,
-               const struct bt_definition *scope)
+               const struct bt_definition *scope,
+               unsigned int *len)
 {
        struct bt_definition **list;
-       unsigned int count;
        int ret;
 
        ret = bt_ctf_get_field_list(ctf_event, scope,
-               (const struct bt_definition * const **)&list, &count);
+               (const struct bt_definition * const **)&list, len);
 
        if (ret < 0)    /* For python to know an error occured */
                list = NULL;
-       else            /* For python to know the end is reached */
-               list[count] = NULL;
 
        return list;
 }
@@ -71,19 +69,18 @@ struct bt_definition *_bt_python_field_one_from_list(
 
 /* event_decl_list */
 struct bt_ctf_event_decl **_bt_python_event_decl_listcaller(
-               int handle_id, struct bt_context *ctx)
+               int handle_id,
+               struct bt_context *ctx,
+               unsigned int *len)
 {
        struct bt_ctf_event_decl **list;
-       unsigned int count;
        int ret;
 
        ret = bt_ctf_get_event_decl_list(handle_id, ctx,
-               (struct bt_ctf_event_decl * const **)&list, &count);
+               (struct bt_ctf_event_decl * const **)&list, len);
 
        if (ret < 0)    /* For python to know an error occured */
                list = NULL;
-       else            /* For python to know the end is reached */
-               list[count] = NULL;
 
        return list;
 }
@@ -97,19 +94,17 @@ struct bt_ctf_event_decl *_bt_python_decl_one_from_list(
 /* decl_fields */
 struct bt_ctf_field_decl **_by_python_field_decl_listcaller(
                struct bt_ctf_event_decl *event_decl,
-               enum bt_ctf_scope scope)
+               enum bt_ctf_scope scope,
+               unsigned int *len)
 {
        struct bt_ctf_field_decl **list;
-       unsigned int count;
        int ret;
 
        ret = bt_ctf_get_decl_fields(event_decl, scope,
-               (const struct bt_ctf_field_decl * const **)&list, &count);
+               (const struct bt_ctf_field_decl * const **)&list, len);
 
        if (ret < 0)    /* For python to know an error occured */
                list = NULL;
-       else            /* For python to know the end is reached */
-               list[count] = NULL;
 
        return list;
 }
index eb778f55bbda977b1d2029912fe74569540242ff..a85f3e52c578b6c9961c4913da9f2a8fb52c5794 100644 (file)
@@ -34,20 +34,24 @@ void _bt_file_close(FILE *fp);
 /* ctf-field-list */
 struct bt_definition **_bt_python_field_listcaller(
                const struct bt_ctf_event *ctf_event,
-               const struct bt_definition *scope);
+               const struct bt_definition *scope,
+               unsigned int *len);
 struct bt_definition *_bt_python_field_one_from_list(
                struct bt_definition **list, int index);
 
 /* event_decl_list */
 struct bt_ctf_event_decl **_bt_python_event_decl_listcaller(
-               int handle_id, struct bt_context *ctx);
+               int handle_id,
+               struct bt_context *ctx,
+               unsigned int *len);
 struct bt_ctf_event_decl *_bt_python_decl_one_from_list(
                struct bt_ctf_event_decl **list, int index);
 
 /* decl_fields */
 struct bt_ctf_field_decl **_by_python_field_decl_listcaller(
                struct bt_ctf_event_decl *event_decl,
-               enum bt_ctf_scope scope);
+               enum bt_ctf_scope scope,
+               unsigned int *len);
 struct bt_ctf_field_decl *_bt_python_field_decl_one_from_list(
                struct bt_ctf_field_decl **list, int index);
 
This page took 0.028407 seconds and 4 git commands to generate.