diff options
author | Klement Sekera <ksekera@cisco.com> | 2021-11-15 15:52:37 +0100 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2021-11-16 10:30:50 +0000 |
commit | a25ce96ba35f001b974cb32e008efb7ef46710e4 (patch) | |
tree | 9171af550df796acd68a25801fae7ec02ced5cb6 /src/vpp-api/vapi/vapi_c_gen.py | |
parent | 5f07b6bd5478d7ee6e7a7c60df922552913d9618 (diff) |
vapi: verify message size when received
Verifying message size including VLA size allows to dismiss some
coverity warnings in generated code.
Type: improvement
Signed-off-by: Klement Sekera <ksekera@cisco.com>
Change-Id: I824658881254b3e7a9bfca228a266cfee448cc2e
Diffstat (limited to 'src/vpp-api/vapi/vapi_c_gen.py')
-rwxr-xr-x | src/vpp-api/vapi/vapi_c_gen.py | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py index 1a5665e5500..100263ccbc3 100755 --- a/src/vpp-api/vapi/vapi_c_gen.py +++ b/src/vpp-api/vapi/vapi_c_gen.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import argparse +import inspect import os import sys import logging @@ -20,7 +21,8 @@ class CField(Field): return "vl_api_string_t %s;" % (self.name) else: if self.len is not None and type(self.len) != dict: - return "%s %s[%d];" % (self.type.get_c_name(), self.name, self.len) + return "%s %s[%d];" % (self.type.get_c_name(), self.name, + self.len) else: return "%s %s;" % (self.type.get_c_name(), self.name) @@ -366,6 +368,37 @@ class CMessage (Message): "}", ]) + def get_verify_msg_size_func_name(self): + return f"vapi_verify_{self.name}_msg_size" + + def get_verify_msg_size_func_decl(self): + return "int %s(%s *msg, uword buf_size)" % ( + self.get_verify_msg_size_func_name(), + self.get_c_name()) + + def get_verify_msg_size_func_def(self): + return inspect.cleandoc( + f""" + {self.get_verify_msg_size_func_decl()} + {{ + if (sizeof({self.get_c_name()}) > buf_size) + {{ + VAPI_ERR("Truncated '{self.name}' msg received, received %lu" + "bytes, expected %lu bytes.", buf_size, + sizeof({self.get_c_name()})); + return -1; + }} + if ({self.get_calc_msg_size_func_name()}(msg) > buf_size) + {{ + VAPI_ERR("Truncated '{self.name}' msg received, received %lu" + "bytes, expected %lu bytes.", buf_size, + sizeof({self.get_calc_msg_size_func_name()})); + return -1; + }} + return 0; + }} + """) + def get_c_def(self): if self.has_payload(): return "\n".join([ @@ -600,7 +633,8 @@ class CMessage (Message): if has_context else ' 0,', (' offsetof(%s, payload),' % self.get_c_name()) if self.has_payload() else ' VAPI_INVALID_MSG_ID,', - ' sizeof(%s),' % self.get_c_name(), + ' (verify_msg_size_fn_t)%s,' % + self.get_verify_msg_size_func_name(), ' (generic_swap_fn_t)%s,' % self.get_swap_to_be_func_name(), ' (generic_swap_fn_t)%s,' % self.get_swap_to_host_func_name(), ' VAPI_INVALID_MSG_ID,', @@ -666,6 +700,8 @@ def emit_definition(parser, json_file, emitted, o): print("%s%s" % (function_attrs, o.get_swap_to_host_func_def())) print("") print("%s%s" % (function_attrs, o.get_calc_msg_size_func_def())) + print("") + print("%s%s" % (function_attrs, o.get_verify_msg_size_func_def())) if not o.is_reply and not o.is_event: print("") print("%s%s" % (function_attrs, o.get_alloc_func_def())) @@ -691,7 +727,8 @@ def gen_json_unified_header(parser, logger, j, io, name): orig_stdout = sys.stdout sys.stdout = io include_guard = "__included_%s" % ( - j.replace(".", "_").replace("/", "_").replace("-", "_").replace("+", "_")) + j.replace(".", "_").replace("/", "_").replace("-", "_").replace( + "+", "_")) print("#ifndef %s" % include_guard) print("#define %s" % include_guard) print("") |