diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-04-28 20:57:02 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-05-15 07:16:33 -0400 |
commit | 265624495f5acf6077f8f8d264f8170573d8d752 (patch) | |
tree | 76e1b8cce3ac0116ade7df91c0d64471cf7cc03d /fs/logfs/super.c | |
parent | d83c49f3e36cecd2e8823b6c48ffba083b8a5704 (diff) |
Fix double-free in logfs
iput() is needed *until* we'd done successful d_alloc_root()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/logfs/super.c')
-rw-r--r-- | fs/logfs/super.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/fs/logfs/super.c b/fs/logfs/super.c index 5866ee6e1327..d7c23ed8349a 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c | |||
@@ -333,27 +333,27 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt) | |||
333 | goto fail; | 333 | goto fail; |
334 | 334 | ||
335 | sb->s_root = d_alloc_root(rootdir); | 335 | sb->s_root = d_alloc_root(rootdir); |
336 | if (!sb->s_root) | 336 | if (!sb->s_root) { |
337 | goto fail2; | 337 | iput(rootdir); |
338 | goto fail; | ||
339 | } | ||
338 | 340 | ||
339 | super->s_erase_page = alloc_pages(GFP_KERNEL, 0); | 341 | super->s_erase_page = alloc_pages(GFP_KERNEL, 0); |
340 | if (!super->s_erase_page) | 342 | if (!super->s_erase_page) |
341 | goto fail2; | 343 | goto fail; |
342 | memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE); | 344 | memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE); |
343 | 345 | ||
344 | /* FIXME: check for read-only mounts */ | 346 | /* FIXME: check for read-only mounts */ |
345 | err = logfs_make_writeable(sb); | 347 | err = logfs_make_writeable(sb); |
346 | if (err) | 348 | if (err) |
347 | goto fail3; | 349 | goto fail1; |
348 | 350 | ||
349 | log_super("LogFS: Finished mounting\n"); | 351 | log_super("LogFS: Finished mounting\n"); |
350 | simple_set_mnt(mnt, sb); | 352 | simple_set_mnt(mnt, sb); |
351 | return 0; | 353 | return 0; |
352 | 354 | ||
353 | fail3: | 355 | fail1: |
354 | __free_page(super->s_erase_page); | 356 | __free_page(super->s_erase_page); |
355 | fail2: | ||
356 | iput(rootdir); | ||
357 | fail: | 357 | fail: |
358 | iput(logfs_super(sb)->s_master_inode); | 358 | iput(logfs_super(sb)->s_master_inode); |
359 | return -EIO; | 359 | return -EIO; |