In ss_create_invocation(), it is necessary to check whether
returned by malloc is a null pointer.
Signed-off-by: Wu Guanghao <[email protected]>
Signed-off-by: Zhiqiang Liu <[email protected]>
---
lib/ss/invocation.c | 38 ++++++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/lib/ss/invocation.c b/lib/ss/invocation.c
index 457e7a2c..cfc180a5 100644
--- a/lib/ss/invocation.c
+++ b/lib/ss/invocation.c
@@ -29,26 +29,31 @@ int ss_create_invocation(const char *subsystem_name, const char *version_string,
register int sci_idx;
register ss_data *new_table;
register ss_data **table;
+ register ss_data **realloc_table;
*code_ptr = 0;
table = _ss_table;
new_table = (ss_data *) malloc(sizeof(ss_data));
+ if (new_table == NULL)
+ goto out;
if (table == (ss_data **) NULL) {
table = (ss_data **) malloc(2 * size);
+ if (table == NULL)
+ goto free_new_table;
table[0] = table[1] = (ss_data *)NULL;
}
initialize_ss_error_table ();
for (sci_idx = 1; table[sci_idx] != (ss_data *)NULL; sci_idx++)
;
- table = (ss_data **) realloc((char *)table,
+ realloc_table = (ss_data **) realloc((char *)table,
((unsigned)sci_idx+2)*size);
- if (table == NULL) {
- *code_ptr = ENOMEM;
- free(new_table);
- return 0;
- }
+ if (realloc_table == NULL)
+ goto free_table;
+
+ table = realloc_table;
+
table[sci_idx+1] = (ss_data *) NULL;
table[sci_idx] = new_table;
@@ -57,9 +62,15 @@ int ss_create_invocation(const char *subsystem_name, const char *version_string,
new_table->argv = (char **)NULL;
new_table->current_request = (char *)NULL;
new_table->info_dirs = (char **)malloc(sizeof(char *));
+ if (new_table->info_dirs == NULL)
+ goto free_table;
+
*new_table->info_dirs = (char *)NULL;
new_table->info_ptr = info_ptr;
new_table->prompt = malloc((unsigned)strlen(subsystem_name)+4);
+ if (new_table->prompt == NULL)
+ goto free_info_dirs;
+
strcpy(new_table->prompt, subsystem_name);
strcat(new_table->prompt, ": ");
#ifdef silly
@@ -71,6 +82,9 @@ int ss_create_invocation(const char *subsystem_name, const char *version_string,
new_table->flags.abbrevs_disabled = 0;
new_table->rqt_tables =
(ss_request_table **) calloc(2, sizeof(ss_request_table *));
+ if (new_table->rqt_tables == NULL)
+ goto free_prompt;
+
*(new_table->rqt_tables) = request_table_ptr;
*(new_table->rqt_tables+1) = (ss_request_table *) NULL;
@@ -85,6 +99,18 @@ int ss_create_invocation(const char *subsystem_name, const char *version_string,
ss_get_readline(sci_idx);
#endif
return(sci_idx);
+
+free_prompt:
+ free(new_table->prompt);
+free_info_dirs:
+ free(new_table->info_dirs);
+free_table:
+ free(table);
+free_new_table:
+ free(new_table);
+out:
+ *code_ptr = ENOMEM;
+ return 0;
}
void
--
2.19.1
On Wed, Jun 30, 2021 at 04:27:17PM +0800, wuguanghao wrote:
> In ss_create_invocation(), it is necessary to check whether
> returned by malloc is a null pointer.
>
> Signed-off-by: Wu Guanghao <[email protected]>
> Signed-off-by: Zhiqiang Liu <[email protected]>
> ---
> lib/ss/invocation.c | 38 ++++++++++++++++++++++++++++++++------
> 1 file changed, 32 insertions(+), 6 deletions(-)
>
Instead of adding all of these goto targets (which is fragile if for
some reason the code gets rearranged), it would be better to make sure
everything that we might want to free is initialized, i.e.:
register ss_data *new_table = NULL;
register ss_data **table = NULL;
new_table = (ss_data *) malloc(sizeof(ss_data));
if (!new_table)
goto out;
memset(new_table, 0, sizeof(ss_data));
and then exit path can just look like this:
out:
if (new_table) {
free(new_table->prompt);
free(new_table->info_dirs);
}
free(new_table);
free(table);
*code_ptr = ENOMEM;
return 0;
... which is much cleaner, and means in the future, you don't need to
figure out which goto label you might need to jump to.
Cheers,
- Ted
P.S. And if we are making all of these changes to the function's
initializers, it might be a good time to zap the "register" keywords
for any lines we are changing, or are nearby, while we're at it.
On 2021/7/16 11:34, Theodore Y. Ts'o wrote:
> On Wed, Jun 30, 2021 at 04:27:17PM +0800, wuguanghao wrote:
>> In ss_create_invocation(), it is necessary to check whether
>> returned by malloc is a null pointer.
>>
>> Signed-off-by: Wu Guanghao <[email protected]>
>> Signed-off-by: Zhiqiang Liu <[email protected]>
>> ---
>> lib/ss/invocation.c | 38 ++++++++++++++++++++++++++++++++------
>> 1 file changed, 32 insertions(+), 6 deletions(-)
>>
> Instead of adding all of these goto targets (which is fragile if for
> some reason the code gets rearranged), it would be better to make sure
> everything that we might want to free is initialized, i.e.:
>
> register ss_data *new_table = NULL;
> register ss_data **table = NULL;
>
> new_table = (ss_data *) malloc(sizeof(ss_data));
> if (!new_table)
> goto out;
> memset(new_table, 0, sizeof(ss_data));
>
> and then exit path can just look like this:
>
> out:
> if (new_table) {
> free(new_table->prompt);
> free(new_table->info_dirs);
> }
> free(new_table);
> free(table);
> *code_ptr = ENOMEM;
> return 0;
>
> ... which is much cleaner, and means in the future, you don't need to
> figure out which goto label you might need to jump to.
>
> Cheers,
>
> - Ted
>
> P.S. And if we are making all of these changes to the function's
> initializers, it might be a good time to zap the "register" keywords
> for any lines we are changing, or are nearby, while we're at it.
>
> .
Thanks for your suggestion.
We will rewrite the patch and remove the "register" keywords.
Regards
Zhiqiang Liu
.