summaryrefslogtreecommitdiffstats
path: root/src/vpp-api/vapi/vapi_c_gen.py
diff options
context:
space:
mode:
authorKlement Sekera <ksekera@cisco.com>2021-11-15 15:52:37 +0100
committerOle Tr�an <otroan@employees.org>2021-11-16 10:30:50 +0000
commita25ce96ba35f001b974cb32e008efb7ef46710e4 (patch)
tree9171af550df796acd68a25801fae7ec02ced5cb6 /src/vpp-api/vapi/vapi_c_gen.py
parent5f07b6bd5478d7ee6e7a7c60df922552913d9618 (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-xsrc/vpp-api/vapi/vapi_c_gen.py43
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("")