mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
tools: ynl: check alloc fails in generated getter code
Generated YNL getter code does not check the return value of malloc() and calloc() before passing the resulting pointer to memcpy(). This could lead to a NULL pointer dereference on memory allocation failure. Updated the C code generator to check for allocation failures and to return an error code in getters. Signed-off-by: Thaison Phan <thaisonphan@google.com> Link: https://patch.msgid.link/20260807171500.7188-3-thaisonphan@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
7c62c481bb
commit
153f709c86
|
|
@ -526,8 +526,10 @@ class TypeString(Type):
|
|||
|
||||
def _attr_get(self, ri, var):
|
||||
len_mem = var + '->_len.' + self.c_name
|
||||
return [f"{len_mem} = len;",
|
||||
f"{var}->{self.c_name} = malloc(len + 1);",
|
||||
return [f"{var}->{self.c_name} = malloc(len + 1);",
|
||||
f"if (!{var}->{self.c_name})",
|
||||
"return YNL_PARSE_CB_ERROR;",
|
||||
f"{len_mem} = len;",
|
||||
f"memcpy({var}->{self.c_name}, ynl_attr_get_str(attr), len);",
|
||||
f"{var}->{self.c_name}[len] = 0;"], \
|
||||
['len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr));'], \
|
||||
|
|
@ -582,8 +584,10 @@ class TypeBinary(Type):
|
|||
|
||||
def _attr_get(self, ri, var):
|
||||
len_mem = var + '->_len.' + self.c_name
|
||||
return [f"{len_mem} = len;",
|
||||
f"{var}->{self.c_name} = malloc(len);",
|
||||
return [f"{var}->{self.c_name} = malloc(len);",
|
||||
f"if (!{var}->{self.c_name})",
|
||||
"return YNL_PARSE_CB_ERROR;",
|
||||
f"{len_mem} = len;",
|
||||
f"memcpy({var}->{self.c_name}, ynl_attr_data(attr), len);"], \
|
||||
['len = ynl_attr_data_len(attr);'], \
|
||||
['unsigned int len;']
|
||||
|
|
@ -601,11 +605,13 @@ class TypeBinaryStruct(TypeBinary):
|
|||
def _attr_get(self, ri, var):
|
||||
struct_sz = 'sizeof(struct ' + c_lower(self.get("struct")) + ')'
|
||||
len_mem = var + '->_' + self.presence_type() + '.' + self.c_name
|
||||
return [f"{len_mem} = len;",
|
||||
f"if (len < {struct_sz})",
|
||||
return [f"if (len < {struct_sz})",
|
||||
f"{var}->{self.c_name} = calloc(1, {struct_sz});",
|
||||
"else",
|
||||
f"{var}->{self.c_name} = malloc(len);",
|
||||
f"if (!{var}->{self.c_name})",
|
||||
"return YNL_PARSE_CB_ERROR;",
|
||||
f"{len_mem} = len;",
|
||||
f"memcpy({var}->{self.c_name}, ynl_attr_data(attr), len);"], \
|
||||
['len = ynl_attr_data_len(attr);'], \
|
||||
['unsigned int len;']
|
||||
|
|
@ -631,9 +637,11 @@ class TypeBinaryScalarArray(TypeBinary):
|
|||
|
||||
def _attr_get(self, ri, var):
|
||||
len_mem = var + '->_count.' + self.c_name
|
||||
return [f"{len_mem} = len / sizeof(__{self.get('sub-type')});",
|
||||
f"len = {len_mem} * sizeof(__{self.get('sub-type')});",
|
||||
return [f"len = (len / sizeof(__{self.get('sub-type')})) * sizeof(__{self.get('sub-type')});",
|
||||
f"{var}->{self.c_name} = malloc(len);",
|
||||
f"if (!{var}->{self.c_name})",
|
||||
"return YNL_PARSE_CB_ERROR;",
|
||||
f"{len_mem} = len / sizeof(__{self.get('sub-type')});",
|
||||
f"memcpy({var}->{self.c_name}, ynl_attr_data(attr), len);"], \
|
||||
['len = ynl_attr_data_len(attr);'], \
|
||||
['unsigned int len;']
|
||||
|
|
@ -2227,6 +2235,8 @@ def _multi_parse(ri, struct, init_lines, local_vars):
|
|||
|
||||
ri.cw.block_start(line=f"if (n_{aspec.c_name})")
|
||||
ri.cw.p(f"dst->{aspec.c_name} = calloc(n_{aspec.c_name}, sizeof(*dst->{aspec.c_name}));")
|
||||
ri.cw.p(f"if (!dst->{aspec.c_name})")
|
||||
ri.cw.p("return YNL_PARSE_CB_ERROR;")
|
||||
ri.cw.p(f"dst->_count.{aspec.c_name} = n_{aspec.c_name};")
|
||||
ri.cw.p('i = 0;')
|
||||
if 'nested-attributes' in aspec:
|
||||
|
|
@ -2252,6 +2262,8 @@ def _multi_parse(ri, struct, init_lines, local_vars):
|
|||
aspec = struct[arg]
|
||||
ri.cw.block_start(line=f"if (n_{aspec.c_name})")
|
||||
ri.cw.p(f"dst->{aspec.c_name} = calloc(n_{aspec.c_name}, sizeof(*dst->{aspec.c_name}));")
|
||||
ri.cw.p(f"if (!dst->{aspec.c_name})")
|
||||
ri.cw.p("return YNL_PARSE_CB_ERROR;")
|
||||
ri.cw.p(f"dst->_count.{aspec.c_name} = n_{aspec.c_name};")
|
||||
ri.cw.p('i = 0;')
|
||||
if 'nested-attributes' in aspec:
|
||||
|
|
@ -2275,6 +2287,8 @@ def _multi_parse(ri, struct, init_lines, local_vars):
|
|||
ri.cw.nl()
|
||||
ri.cw.p('len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr));')
|
||||
ri.cw.p(f'dst->{aspec.c_name}[i] = malloc(sizeof(struct ynl_string) + len + 1);')
|
||||
ri.cw.p(f"if (!dst->{aspec.c_name}[i])")
|
||||
ri.cw.p("return YNL_PARSE_CB_ERROR;")
|
||||
ri.cw.p(f"dst->{aspec.c_name}[i]->len = len;")
|
||||
ri.cw.p(f"memcpy(dst->{aspec.c_name}[i]->str, ynl_attr_get_str(attr), len);")
|
||||
ri.cw.p(f"dst->{aspec.c_name}[i]->str[len] = 0;")
|
||||
|
|
@ -2434,6 +2448,8 @@ def print_req(ri):
|
|||
|
||||
if 'reply' in ri.op[ri.op_mode]:
|
||||
ri.cw.p('rsp = calloc(1, sizeof(*rsp));')
|
||||
ri.cw.p('if (!rsp)')
|
||||
ri.cw.p(f'return {ret_err};')
|
||||
ri.cw.p('yrs.yarg.data = rsp;')
|
||||
ri.cw.p(f"yrs.cb = {op_prefix(ri, 'reply')}_parse;")
|
||||
if ri.op.value is not None:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user