mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-30 08:30:50 +09:00
fs/squashfs: sqfs_search_dir: fix memory leaks
path, target, res, rem and sym_tokens were not free on error nor success. Reviewed-by: Joao Marcos Costa <jmcosta944@gmail.com> Signed-off-by: Richard Genoud <richard.genoud@posteo.net>
This commit is contained in:
parent
01e71ec61a
commit
cd54591afd
@ -434,7 +434,7 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list,
|
|||||||
{
|
{
|
||||||
struct squashfs_super_block *sblk = ctxt.sblk;
|
struct squashfs_super_block *sblk = ctxt.sblk;
|
||||||
char *path, *target, **sym_tokens, *res, *rem;
|
char *path, *target, **sym_tokens, *res, *rem;
|
||||||
int j, ret, new_inode_number, offset;
|
int j, ret = 0, new_inode_number, offset;
|
||||||
struct squashfs_symlink_inode *sym;
|
struct squashfs_symlink_inode *sym;
|
||||||
struct squashfs_ldir_inode *ldir;
|
struct squashfs_ldir_inode *ldir;
|
||||||
struct squashfs_dir_inode *dir;
|
struct squashfs_dir_inode *dir;
|
||||||
@ -442,6 +442,12 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list,
|
|||||||
struct fs_dirent *dent;
|
struct fs_dirent *dent;
|
||||||
unsigned char *table;
|
unsigned char *table;
|
||||||
|
|
||||||
|
res = NULL;
|
||||||
|
rem = NULL;
|
||||||
|
path = NULL;
|
||||||
|
target = NULL;
|
||||||
|
sym_tokens = NULL;
|
||||||
|
|
||||||
dirsp = (struct fs_dir_stream *)dirs;
|
dirsp = (struct fs_dir_stream *)dirs;
|
||||||
|
|
||||||
/* Start by root inode */
|
/* Start by root inode */
|
||||||
@ -477,7 +483,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list,
|
|||||||
for (j = 0; j < token_count; j++) {
|
for (j = 0; j < token_count; j++) {
|
||||||
if (!sqfs_is_dir(get_unaligned_le16(&dir->inode_type))) {
|
if (!sqfs_is_dir(get_unaligned_le16(&dir->inode_type))) {
|
||||||
printf("** Cannot find directory. **\n");
|
printf("** Cannot find directory. **\n");
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!sqfs_readdir(dirsp, &dent)) {
|
while (!sqfs_readdir(dirsp, &dent)) {
|
||||||
@ -490,7 +497,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list,
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("** Cannot find directory. **\n");
|
printf("** Cannot find directory. **\n");
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redefine inode as the found token */
|
/* Redefine inode as the found token */
|
||||||
@ -507,40 +515,63 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list,
|
|||||||
sym = (struct squashfs_symlink_inode *)table;
|
sym = (struct squashfs_symlink_inode *)table;
|
||||||
/* Get first j + 1 tokens */
|
/* Get first j + 1 tokens */
|
||||||
path = sqfs_concat_tokens(token_list, j + 1);
|
path = sqfs_concat_tokens(token_list, j + 1);
|
||||||
|
if (!path) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
/* Resolve for these tokens */
|
/* Resolve for these tokens */
|
||||||
target = sqfs_resolve_symlink(sym, path);
|
target = sqfs_resolve_symlink(sym, path);
|
||||||
|
if (!target) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
/* Join remaining tokens */
|
/* Join remaining tokens */
|
||||||
rem = sqfs_concat_tokens(token_list + j + 1, token_count -
|
rem = sqfs_concat_tokens(token_list + j + 1, token_count -
|
||||||
j - 1);
|
j - 1);
|
||||||
|
if (!rem) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
/* Concatenate remaining tokens and symlink's target */
|
/* Concatenate remaining tokens and symlink's target */
|
||||||
res = malloc(strlen(rem) + strlen(target) + 1);
|
res = malloc(strlen(rem) + strlen(target) + 1);
|
||||||
|
if (!res) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
strcpy(res, target);
|
strcpy(res, target);
|
||||||
res[strlen(target)] = '/';
|
res[strlen(target)] = '/';
|
||||||
strcpy(res + strlen(target) + 1, rem);
|
strcpy(res + strlen(target) + 1, rem);
|
||||||
token_count = sqfs_count_tokens(res);
|
token_count = sqfs_count_tokens(res);
|
||||||
|
|
||||||
if (token_count < 0)
|
if (token_count < 0) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
sym_tokens = malloc(token_count * sizeof(char *));
|
sym_tokens = malloc(token_count * sizeof(char *));
|
||||||
if (!sym_tokens)
|
if (!sym_tokens) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fill tokens list */
|
/* Fill tokens list */
|
||||||
ret = sqfs_tokenize(sym_tokens, token_count, res);
|
ret = sqfs_tokenize(sym_tokens, token_count, res);
|
||||||
if (ret)
|
if (ret) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
free(dirs->entry);
|
free(dirs->entry);
|
||||||
dirs->entry = NULL;
|
dirs->entry = NULL;
|
||||||
|
|
||||||
ret = sqfs_search_dir(dirs, sym_tokens, token_count,
|
ret = sqfs_search_dir(dirs, sym_tokens, token_count,
|
||||||
m_list, m_count);
|
m_list, m_count);
|
||||||
return ret;
|
goto out;
|
||||||
} else if (!sqfs_is_dir(get_unaligned_le16(&dir->inode_type))) {
|
} else if (!sqfs_is_dir(get_unaligned_le16(&dir->inode_type))) {
|
||||||
printf("** Cannot find directory. **\n");
|
printf("** Cannot find directory. **\n");
|
||||||
free(dirs->entry);
|
free(dirs->entry);
|
||||||
dirs->entry = NULL;
|
dirs->entry = NULL;
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if it is an extended dir. */
|
/* Check if it is an extended dir. */
|
||||||
@ -560,7 +591,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list,
|
|||||||
printf("Empty directory.\n");
|
printf("Empty directory.\n");
|
||||||
free(dirs->entry);
|
free(dirs->entry);
|
||||||
dirs->entry = NULL;
|
dirs->entry = NULL;
|
||||||
return SQFS_EMPTY_DIR;
|
ret = SQFS_EMPTY_DIR;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirs->table += SQFS_DIR_HEADER_SIZE;
|
dirs->table += SQFS_DIR_HEADER_SIZE;
|
||||||
@ -579,7 +611,13 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list,
|
|||||||
else
|
else
|
||||||
memcpy(&dirs->i_ldir, ldir, sizeof(*ldir));
|
memcpy(&dirs->i_ldir, ldir, sizeof(*ldir));
|
||||||
|
|
||||||
return 0;
|
out:
|
||||||
|
free(res);
|
||||||
|
free(rem);
|
||||||
|
free(path);
|
||||||
|
free(target);
|
||||||
|
free(sym_tokens);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user