[PATCH 1/3] fix code generation for emit_size_read() to check for buffer overflow

Thomas Haller thaller at redhat.com
Mon Oct 6 06:15:32 PDT 2014


Code generation via emit_size_read() creates the _validate() functions.
The generated code for strings and arrays used to read the length prefix
without checking that the provided buffer is large enough.

https://bugzilla.redhat.com/show_bug.cgi?id=1031738

Reported-by: Florian Weimer <fweimer at redhat.com>
Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 build-aux/qmi-codegen/VariableArray.py  | 22 ++++++++++++++--------
 build-aux/qmi-codegen/VariableString.py | 22 ++++++++++++++--------
 2 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/build-aux/qmi-codegen/VariableArray.py b/build-aux/qmi-codegen/VariableArray.py
index c402da1..4a9f770 100644
--- a/build-aux/qmi-codegen/VariableArray.py
+++ b/build-aux/qmi-codegen/VariableArray.py
@@ -235,7 +235,8 @@ class VariableArray(Variable):
             translations['fixed_size'] = self.fixed_size
 
             template = (
-                '${lp}    guint16 ${common_var_prefix}_n_items = ${fixed_size};\n')
+                '${lp}    {\n'
+                '${lp}        guint16 ${common_var_prefix}_n_items = ${fixed_size};\n')
             f.write(string.Template(template).substitute(translations))
         else:
             translations['array_size_element_format'] = self.array_size_element.public_format
@@ -250,10 +251,14 @@ class VariableArray(Variable):
 
             template = (
                 '${lp}    ${array_size_element_format} ${common_var_prefix}_n_items;\n'
-                '${lp}    const guint8 *${common_var_prefix}_aux_buffer = &${buffer_name}[${variable_name}];\n'
-                '${lp}    guint16 ${common_var_prefix}_aux_buffer_len = ${buffer_len} - ${variable_name};\n'
                 '\n'
-                '${lp}    ${variable_name} += ${array_size_element_size};\n')
+                '${lp}    if ((${variable_name} >= ${buffer_len}) || (${buffer_len} - ${variable_name} < ${array_size_element_size})) {\n'
+                '${lp}        ${variable_name} += ${array_size_element_size};\n'
+                '${lp}    } else {\n'
+                '${lp}        const guint8 *${common_var_prefix}_aux_buffer = &${buffer_name}[${variable_name}];\n'
+                '${lp}        guint16 ${common_var_prefix}_aux_buffer_len = ${buffer_len} - ${variable_name};\n'
+                '\n'
+                '${lp}        ${variable_name} += ${array_size_element_size};\n')
 
             if self.array_sequence_element != '':
                 if self.array_sequence_element.public_format == 'guint8':
@@ -266,21 +271,22 @@ class VariableArray(Variable):
                     translations['array_sequence_element_size'] = '0'
                 template += (
                     '\n'
-                    '${lp}    ${variable_name} += ${array_sequence_element_size};\n')
+                    '${lp}        ${variable_name} += ${array_sequence_element_size};\n')
 
             f.write(string.Template(template).substitute(translations))
 
-            self.array_size_element.emit_buffer_read(f, line_prefix + '    ', common_var_prefix + '_n_items', common_var_prefix + '_aux_buffer', common_var_prefix + '_aux_buffer_len')
+            self.array_size_element.emit_buffer_read(f, line_prefix + '        ', common_var_prefix + '_n_items', common_var_prefix + '_aux_buffer', common_var_prefix + '_aux_buffer_len')
 
         template = (
             '\n'
-            '${lp}    for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${common_var_prefix}_n_items; ${common_var_prefix}_i++) {\n'
+            '${lp}        for (${common_var_prefix}_i = 0; ${common_var_prefix}_i < ${common_var_prefix}_n_items; ${common_var_prefix}_i++) {\n'
             '\n')
         f.write(string.Template(template).substitute(translations))
 
-        self.array_element.emit_size_read(f, line_prefix + '        ', variable_name, buffer_name, buffer_len)
+        self.array_element.emit_size_read(f, line_prefix + '            ', variable_name, buffer_name, buffer_len)
 
         template = (
+            '${lp}        }\n'
             '${lp}    }\n'
             '${lp}}\n')
         f.write(string.Template(template).substitute(translations))
diff --git a/build-aux/qmi-codegen/VariableString.py b/build-aux/qmi-codegen/VariableString.py
index faa2085..a813a6f 100644
--- a/build-aux/qmi-codegen/VariableString.py
+++ b/build-aux/qmi-codegen/VariableString.py
@@ -120,21 +120,27 @@ class VariableString(Variable):
         elif self.length_prefix_size == 8:
             template = (
                 '${lp}{\n'
-                '${lp}    guint8 size8;\n'
-                '${lp}    const guint8 *aux_buffer = &${buffer_name}[${variable_name}];\n'
-                '${lp}    guint16 aux_buffer_len = ${buffer_len} - ${variable_name};\n'
+                '${lp}    guint8 size8 = 0;\n'
                 '\n'
-                '${lp}    qmi_utils_read_guint8_from_buffer (&aux_buffer, &aux_buffer_len, &size8);\n'
+                '${lp}    if (${variable_name} < ${buffer_len}) {\n'
+                '${lp}        const guint8 *aux_buffer = &${buffer_name}[${variable_name}];\n'
+                '${lp}        guint16 aux_buffer_len = ${buffer_len} - ${variable_name};\n'
+                '\n'
+                '${lp}        qmi_utils_read_guint8_from_buffer (&aux_buffer, &aux_buffer_len, &size8);\n'
+                '${lp}    }\n'
                 '${lp}    ${variable_name} += (1 + size8);\n'
                 '${lp}}\n')
         elif self.length_prefix_size == 16:
             template = (
                 '${lp}{\n'
-                '${lp}    guint16 size16;\n'
-                '${lp}    const guint8 *aux_buffer = &${buffer_name}[${variable_name}];\n'
-                '${lp}    guint16 aux_buffer_len = ${buffer_len} - ${variable_name};\n'
+                '${lp}    guint16 size16 = 0;\n'
+                '\n'
+                '${lp}    if (${variable_name} < ${buffer_len}) {\n'
+                '${lp}        const guint8 *aux_buffer = &${buffer_name}[${variable_name}];\n'
+                '${lp}        guint16 aux_buffer_len = ${buffer_len} - ${variable_name};\n'
                 '\n'
-                '${lp}    qmi_utils_read_guint16_from_buffer (&aux_buffer, &aux_buffer_len, QMI_ENDIAN_LITTLE, &size16);\n'
+                '${lp}        qmi_utils_read_guint16_from_buffer (&aux_buffer, &aux_buffer_len, QMI_ENDIAN_LITTLE, &size16);\n'
+                '${lp}    }\n'
                 '${lp}    ${variable_name} += (2 + size16);\n'
                 '${lp}}\n')
         f.write(string.Template(template).substitute(translations))
-- 
1.9.3



More information about the libqmi-devel mailing list