mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-19 04:14:49 +08:00
NTFS: Fix invalid pointer dereference in ntfs_mft_record_alloc().
In ntfs_mft_record_alloc() when mapping the new extent mft record with map_extent_mft_record() we overwrite @m with the return value and on error, we then try to use the old @m but that is no longer there as @m now contains an error code instead so we crash when dereferencing the error code as if it were a pointer. The simple fix is to use a temporary variable to store the return value thus preserving the original @m for later use. This is a backport from the commercial Tuxera-NTFS driver and is well tested... Thanks go to Julia Lawall for pointing this out (whilst I had fixed it in the commercial driver I had failed to fix it in the Linux kernel). Signed-off-by: Anton Altaparmakov <anton@tuxera.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
9fbf0c08d4
commit
af5eb745ef
@ -460,6 +460,8 @@ Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
|
|||||||
2.1.30:
|
2.1.30:
|
||||||
- Fix writev() (it kept writing the first segment over and over again
|
- Fix writev() (it kept writing the first segment over and over again
|
||||||
instead of moving onto subsequent segments).
|
instead of moving onto subsequent segments).
|
||||||
|
- Fix crash in ntfs_mft_record_alloc() when mapping the new extent mft
|
||||||
|
record failed.
|
||||||
2.1.29:
|
2.1.29:
|
||||||
- Fix a deadlock when mounting read-write.
|
- Fix a deadlock when mounting read-write.
|
||||||
2.1.28:
|
2.1.28:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
|
* mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2006 Anton Altaparmakov
|
* Copyright (c) 2001-2011 Anton Altaparmakov and Tuxera Inc.
|
||||||
* Copyright (c) 2002 Richard Russon
|
* Copyright (c) 2002 Richard Russon
|
||||||
*
|
*
|
||||||
* This program/include file is free software; you can redistribute it and/or
|
* This program/include file is free software; you can redistribute it and/or
|
||||||
@ -2576,6 +2576,8 @@ mft_rec_already_initialized:
|
|||||||
flush_dcache_page(page);
|
flush_dcache_page(page);
|
||||||
SetPageUptodate(page);
|
SetPageUptodate(page);
|
||||||
if (base_ni) {
|
if (base_ni) {
|
||||||
|
MFT_RECORD *m_tmp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the base mft record in the extent mft record. This
|
* Setup the base mft record in the extent mft record. This
|
||||||
* completes initialization of the allocated extent mft record
|
* completes initialization of the allocated extent mft record
|
||||||
@ -2588,11 +2590,11 @@ mft_rec_already_initialized:
|
|||||||
* attach it to the base inode @base_ni and map, pin, and lock
|
* attach it to the base inode @base_ni and map, pin, and lock
|
||||||
* its, i.e. the allocated, mft record.
|
* its, i.e. the allocated, mft record.
|
||||||
*/
|
*/
|
||||||
m = map_extent_mft_record(base_ni, bit, &ni);
|
m_tmp = map_extent_mft_record(base_ni, bit, &ni);
|
||||||
if (IS_ERR(m)) {
|
if (IS_ERR(m_tmp)) {
|
||||||
ntfs_error(vol->sb, "Failed to map allocated extent "
|
ntfs_error(vol->sb, "Failed to map allocated extent "
|
||||||
"mft record 0x%llx.", (long long)bit);
|
"mft record 0x%llx.", (long long)bit);
|
||||||
err = PTR_ERR(m);
|
err = PTR_ERR(m_tmp);
|
||||||
/* Set the mft record itself not in use. */
|
/* Set the mft record itself not in use. */
|
||||||
m->flags &= cpu_to_le16(
|
m->flags &= cpu_to_le16(
|
||||||
~le16_to_cpu(MFT_RECORD_IN_USE));
|
~le16_to_cpu(MFT_RECORD_IN_USE));
|
||||||
@ -2603,6 +2605,7 @@ mft_rec_already_initialized:
|
|||||||
ntfs_unmap_page(page);
|
ntfs_unmap_page(page);
|
||||||
goto undo_mftbmp_alloc;
|
goto undo_mftbmp_alloc;
|
||||||
}
|
}
|
||||||
|
BUG_ON(m != m_tmp);
|
||||||
/*
|
/*
|
||||||
* Make sure the allocated mft record is written out to disk.
|
* Make sure the allocated mft record is written out to disk.
|
||||||
* No need to set the inode dirty because the caller is going
|
* No need to set the inode dirty because the caller is going
|
||||||
|
Loading…
Reference in New Issue
Block a user