-
Notifications
You must be signed in to change notification settings - Fork 192
Description
Hi
I am looking at node.c and arguments.c code, and there is part that, in my understanding, should cause a segfault (but I guess it doesn't?)
If you look from line 286 (node.c in master branch):
...
node->impl->options = rcl_node_get_default_options();
node->context = context;
// Initialize node impl.
ret = rcl_node_options_copy(options, &(node->impl->options));
...
node->impl->options is filled with 0, and then it is copied to options with the following function (from line 562):
...
options_out->domain_id = options->domain_id;
options_out->allocator = options->allocator;
options_out->use_global_arguments = options->use_global_arguments;
if (NULL != options->arguments.impl) {
rcl_ret_t ret = rcl_arguments_copy(&(options->arguments), &(options_out->arguments));
...
and the arguments are copied by rcl_arguments_copy as defined in arguments.c from line 479:
...
args_out->impl = allocator.allocate(sizeof(rcl_arguments_impl_t), allocator.state);
if (NULL == args_out->impl) {
return RCL_RET_BAD_ALLOC;
}
args_out->impl->allocator = allocator;
// Zero so it's safe to call rcl_arguments_fini() if an error occurrs while copying.
args_out->impl->num_remap_rules = 0;
args_out->impl->num_unparsed_args = 0;
args_out->impl->num_param_files_args = 0;
// Copy unparsed args
args_out->impl->unparsed_args = allocator.allocate(
sizeof(int) * args->impl->num_unparsed_args, allocator.state);
if (NULL == args_out->impl->unparsed_args) {
if (RCL_RET_OK != rcl_arguments_fini(args_out)) {
RCL_SET_ERROR_MSG("Error while finalizing arguments due to another error");
}
return RCL_RET_BAD_ALLOC;
}
...
So args_out->impl is allocated. Since the allocation here is just a malloc, args_out->impl
may contain any kind of value.
Since at this point args->impl->num_unparsed_args is 0, this line:
allocator.allocate(
sizeof(int) * args->impl->num_unparsed_args, allocator.state);
is just a malloc(0), which returns NULL. So the if statement is triggered and we call rcl_arguments_fini(args_out) (from line 567). At this point args->impl->remap_rules may contain anything (it has not been initialized yet), so the code may then enter the if statement at line 574:
if (args->impl->remap_rules) {
...
args->impl->allocator.deallocate(args->impl->remap_rules, args->impl->allocator.state);
...
}
and then call free on the uninitialized pointer, resulting in a SegFault
Is my understanding correct?