summaryrefslogtreecommitdiff
path: root/python_modules
diff options
context:
space:
mode:
authorFrediano Ziglio <fziglio@redhat.com>2019-08-13 17:42:49 +0100
committerFrediano Ziglio <fziglio@redhat.com>2019-10-10 12:33:42 +0100
commitd4248885e83d20180b965070383584977e46d682 (patch)
treea30dd1016355a1fece6bdb6387d558ea8e480fcd /python_modules
parenta5a86a1caf271f460e2b2f8eb55c07c6ab6f680b (diff)
codegen: Check validity of array members
Check that combination of fields for an array does not lead to unsafe code. check_valid method came from generate_c_declaration with some more check and it's use in demarshaller to validate the array if the structure is not generated. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
Diffstat (limited to 'python_modules')
-rw-r--r--python_modules/demarshal.py2
-rw-r--r--python_modules/ptypes.py31
2 files changed, 32 insertions, 1 deletions
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
index acd4b6f..3736976 100644
--- a/python_modules/demarshal.py
+++ b/python_modules/demarshal.py
@@ -315,6 +315,8 @@ def write_validate_pointer_item(writer, container, item, scope, parent_scope, st
def write_validate_array_item(writer, container, item, scope, parent_scope, start,
want_nw_size, want_mem_size, want_extra_size):
array = item.type
+ if item.member:
+ array.check_valid(item.member)
is_byte_size = False
element_type = array.element_type
if array.is_bytes_length():
diff --git a/python_modules/ptypes.py b/python_modules/ptypes.py
index 32dae21..796a436 100644
--- a/python_modules/ptypes.py
+++ b/python_modules/ptypes.py
@@ -485,7 +485,36 @@ class ArrayType(Type):
def c_type(self):
return self.element_type.c_type()
+ def check_valid(self, member):
+ # These attribute corresponds to specific structure size
+ if member.has_attr("chunk") or member.has_attr("as_ptr"):
+ return
+ # These attribute indicate that the array is stored in the structure
+ # as a pointer of the array. If there's no way to retrieve the length
+ # of the array give error, as the user has no way to do bound checks
+ if member.has_attr("to_ptr") or member.has_attr("ptr_array"):
+ if not (self.is_identifier_length() or self.is_constant_length()):
+ raise Exception("Unsecure, no length of array")
+ return
+ # This attribute indicate that the array is store at the end
+ # of the structure, the user will compute the length from the
+ # entire message size
+ if member.has_end_attr():
+ return
+ # Avoid bug, the array has no length specified and no space
+ # would be allocated
+ if self.is_remaining_length():
+ raise Exception('C output array is not allocated')
+ # For constant length (like "foo[5]") the field is a sized array
+ # For identifier automatically a pointer to allocated data is store,
+ # in this case user can read the size using the other field specified
+ # by the identifier
+ if self.is_constant_length() or self.is_identifier_length():
+ return
+ raise NotImplementedError('unknown array %s' % str(self))
+
def generate_c_declaration(self, writer, member):
+ self.check_valid(member)
name = member.name
if member.has_attr("chunk"):
return writer.writeln('SpiceChunks *%s;' % name)
@@ -497,7 +526,7 @@ class ArrayType(Type):
return writer.writeln('%s *%s;' % (self.c_type(), name))
if member.has_attr("ptr_array"):
return writer.writeln('%s *%s[0];' % (self.c_type(), name))
- if member.has_end_attr() or self.is_remaining_length():
+ if member.has_end_attr():
return writer.writeln('%s %s[0];' % (self.c_type(), name))
if self.is_constant_length():
return writer.writeln('%s %s[%s];' % (self.c_type(), name, self.size))