Fix use after free when closing log/rt devices
PATCH 1/1 Fix use after free when closing log/rt devices
The call to xfs_free_buftarg() will free the memory used by it's argument so we need to save the bdev to pass to xfs_blkdev_put()
Lachlan
xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +0 -0
@@ -781,13 +781,17 @@ STATIC void
xfs_close_devices(
struct xfs_mount *mp)
{
+ struct block_device *bdev;
+
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
+ bdev = mp->m_logdev_targp->bt_bdev;
xfs_free_buftarg(mp->m_logdev_targp);
- xfs_blkdev_put(mp->m_logdev_targp->bt_bdev);
+ xfs_blkdev_put(bdev);
}
if (mp->m_rtdev_targp) {
+ bdev = mp->m_rtdev_targp->bt_bdev;
xfs_free_buftarg(mp->m_rtdev_targp);
- xfs_blkdev_put(mp->m_rtdev_targp->bt_bdev);
+ xfs_blkdev_put(bdev);
}
xfs_free_buftarg(mp->m_ddev_targp);
}Quoted 24 lines · Lachlan McIlroy
The call to
xfs_free_buftarg()will free the memory used by it's argument so we need to save the bdev to pass toxfs_blkdev_put()Lachlan
xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +0
-0@@ -781,13 +781,17 @@ STATIC voidxfs_close_devices(
structxfs_mount*mp)
{xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +2
-0+struct block_device *bdev; +if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-0+ bdev = mp->m_logdev_targp->bt_bdev;xfs_free_buftarg(mp->m_logdev_targp);xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-1-xfs_blkdev_put (mp->m_logdev_targp->bt_bdev); +xfs_blkdev_put (bdev);} if (mp->m_rtdev_targp) {xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-0+ bdev = mp->m_rtdev_targp->bt_bdev;xfs_free_buftarg(mp->m_rtdev_targp);xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-1-xfs_blkdev_put (mp->m_rtdev_targp->bt_bdev); +xfs_blkdev_put (bdev);
Quoted 1 line
}
Looks good, alhough two local variables inside the ifs might be cleaner:
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
xfs_free_buftarg(mp->m_logdev_targp);
xfs_blkdev_put(logdev);
}
...Quoted 29 lines · Christoph Hellwig
Quoted 24 lines · Lachlan McIlroy
The call to
xfs_free_buftarg()will free the memory used by it's argument so we need to save the bdev to pass toxfs_blkdev_put()Lachlan
xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +0
-0@@ -781,13 +781,17 @@ STATIC voidxfs_close_devices(
structxfs_mount*mp)
{xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +2
-0+struct block_device *bdev; +if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-0+ bdev = mp->m_logdev_targp->bt_bdev;xfs_free_buftarg(mp->m_logdev_targp);xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-1-xfs_blkdev_put (mp->m_logdev_targp->bt_bdev); +xfs_blkdev_put (bdev);} if (mp->m_rtdev_targp) {xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-0+ bdev = mp->m_rtdev_targp->bt_bdev;xfs_free_buftarg(mp->m_rtdev_targp);xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-1-xfs_blkdev_put (mp->m_rtdev_targp->bt_bdev); +xfs_blkdev_put (bdev);Quoted 1 line
}Looks good, alhough two local variables inside the ifs might be cleaner:
Quoted 8 lines
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
xfs_free_buftarg(mp->m_logdev_targp);
xfs_blkdev_put(logdev);
}
...do we have any QA tests that test external log?
-- Mark
Quoted 1 line · Mark Goodwin
do we have any QA tests that test external log?
Most QA tests will use the external log if you set it up that way. But ithout slab poisoning this won't be noticed either.
Quoted 29 lines · Christoph Hellwig
Quoted 24 lines · Lachlan McIlroy
The call to
xfs_free_buftarg()will free the memory used by it's argument so we need to save the bdev to pass toxfs_blkdev_put()Lachlan
xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +0
-0@@ -781,13 +781,17 @@ STATIC voidxfs_close_devices(
structxfs_mount*mp)
{xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +2
-0+struct block_device *bdev; +if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-0+ bdev = mp->m_logdev_targp->bt_bdev;xfs_free_buftarg(mp->m_logdev_targp);xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-1-xfs_blkdev_put (mp->m_logdev_targp->bt_bdev); +xfs_blkdev_put (bdev);} if (mp->m_rtdev_targp) {xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-0+ bdev = mp->m_rtdev_targp->bt_bdev;xfs_free_buftarg(mp->m_rtdev_targp);xfs/linux-2.6/xfs_super.c renamed from xfs/linux-2.6/xfs_super.c_1.432 +1
-1-xfs_blkdev_put (mp->m_rtdev_targp->bt_bdev); +xfs_blkdev_put (bdev);Quoted 1 line
}Looks good, alhough two local variables inside the ifs might be cleaner:
Quoted 9 lines
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
xfs_free_buftarg(mp->m_logdev_targp);
xfs_blkdev_put(logdev);
}
...Thought someone might suggest that. I'll make the changes, thanks.
Quoted 5 lines · Christoph Hellwig
Quoted 1 line · Mark Goodwin
do we have any QA tests that test external log?
Most QA tests will use the external log if you set it up that way. But ithout slab poisoning this won't be noticed either.
I think you need:
USE_EXTERNAL=yes
SCRATCH_LOGDEV=somelogdevice TEST_LOGDEV=somelogdevice
to get the scratch and test mounts using an external log.
There are no explicit external log tests (logdev=) that I can see.
--Tim
Quoted 4 lines · Timothy Shimmin
Quoted 3 lines · Christoph Hellwig
Quoted 1 line · Mark Goodwin
do we have any QA tests that test external log?
Quoted 8 lines
Quoted 2 lines
Most QA tests will use the external log if you set it up that way. But ithout slab poisoning this won't be noticed either.
I think you need:
USE_EXTERNAL=yes
SCRATCH_LOGDEV=somelogdevice TEST_LOGDEV=somelogdevice
to get the scratch and test mounts using an external log.
Yes. Typically I used to use SCRATCH_LOGDEV=/dev/ram0 so I didn't need another block device on the machine just for an external log on a throw-away filesystem....
Quoted 1 line
There are no explicit external log tests (logdev=) that I can see.
It should be easy to write one using files and multiple loopback devices.
Cheers,
Dave.
Signature · 2 lines
Dave Chinner [email protected]