diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2014-11-05 11:14:26 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-11-05 11:14:26 -0500 |
commit | beec19ff21d41c84dbbc2ab8d0df25147912ff59 (patch) | |
tree | cad291d270eeea37b474fb2d034c31f732051f72 /e2fsck/dirinfo.c | |
parent | ea9085c711e92c3727538a0637bc805141333d83 (diff) | |
download | e2fsprogs-beec19ff21d41c84dbbc2ab8d0df25147912ff59.tar.gz |
e2fsck: fix dangling pointer when dir_info array is resized
e2fsck uses an array to store directory usage information during pass
3; the usage context also contains a pointer to the last directory
looked up. When expanding the dir_info array, this cache pointer
needs to be cleared if the array resize changed the pointer location,
or else we'll later walk off the end of this dead pointer.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reported-by: Sami Liedes <sami.liedes@iki.fi>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'e2fsck/dirinfo.c')
-rw-r--r-- | e2fsck/dirinfo.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/e2fsck/dirinfo.c b/e2fsck/dirinfo.c index 4a9019b5..dab5a13f 100644 --- a/e2fsck/dirinfo.c +++ b/e2fsck/dirinfo.c @@ -121,7 +121,7 @@ static void setup_db(e2fsck_t ctx) void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent) { struct dir_info_db *db; - struct dir_info *dir, ent; + struct dir_info *dir, ent, *old_array; int i, j; errcode_t retval; unsigned long old_size; @@ -136,6 +136,7 @@ void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent) if (ctx->dir_info->count >= ctx->dir_info->size) { old_size = ctx->dir_info->size * sizeof(struct dir_info); ctx->dir_info->size += 10; + old_array = ctx->dir_info->array; retval = ext2fs_resize_mem(old_size, ctx->dir_info->size * sizeof(struct dir_info), &ctx->dir_info->array); @@ -147,6 +148,8 @@ void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent) ctx->dir_info->size -= 10; return; } + if (old_array != ctx->dir_info->array) + ctx->dir_info->last_lookup = NULL; } ent.ino = ino; |