You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
2.3 KiB
60 lines
2.3 KiB
From eb917d346bc8592924c5f6566b01841176c53c8c Mon Sep 17 00:00:00 2001 |
|
From: Tomas Bzatek <tbzatek@redhat.com> |
|
Date: Mon, 22 Aug 2022 16:27:11 +0200 |
|
Subject: [PATCH] udiskslinuxblock: Only permit ATA Secure Erase during |
|
Format() on a whole block device |
|
|
|
ATA Secure Erase requested as an option to the Format() method call used |
|
to perform the actual erase on a whole drive object it looked up. When |
|
Format() was called on a partition, this led to data loss on a whole drive. |
|
This commit adds a safeguard to check that the Format() is requested |
|
on a whole block device. |
|
|
|
Severity of this issue was slightly lowered by a failure to submit |
|
the ATA Secure erase command in case some filesystem was mounted |
|
at that point. |
|
--- |
|
src/udiskslinuxblock.c | 16 ++++++++++++++++ |
|
1 file changed, 16 insertions(+) |
|
|
|
diff --git a/src/udiskslinuxblock.c b/src/udiskslinuxblock.c |
|
index d1da94edf..db0ed2bf6 100644 |
|
--- a/src/udiskslinuxblock.c |
|
+++ b/src/udiskslinuxblock.c |
|
@@ -2354,6 +2354,7 @@ erase_ata_device (UDisksBlock *block, |
|
{ |
|
gboolean ret = FALSE; |
|
UDisksObject *drive_object = NULL; |
|
+ UDisksLinuxBlockObject *block_object = NULL; |
|
UDisksDriveAta *ata = NULL; |
|
|
|
drive_object = udisks_daemon_find_object (daemon, udisks_block_get_drive (block)); |
|
@@ -2369,6 +2370,20 @@ erase_ata_device (UDisksBlock *block, |
|
goto out; |
|
} |
|
|
|
+ /* Reverse check to ensure we're erasing whole block device and not a partition */ |
|
+ block_object = udisks_linux_drive_object_get_block (UDISKS_LINUX_DRIVE_OBJECT (drive_object), FALSE /* get_hw */); |
|
+ if (block_object == NULL) |
|
+ { |
|
+ g_set_error (error, UDISKS_ERROR, UDISKS_ERROR_FAILED, "Couldn't find a block device for the drive to erase"); |
|
+ goto out; |
|
+ } |
|
+ if (g_strcmp0 (g_dbus_object_get_object_path (G_DBUS_OBJECT (object)), |
|
+ g_dbus_object_get_object_path (G_DBUS_OBJECT (block_object))) != 0) |
|
+ { |
|
+ g_set_error (error, UDISKS_ERROR, UDISKS_ERROR_FAILED, "ATA secure erase needs to be performed on a whole block device"); |
|
+ goto out; |
|
+ } |
|
+ |
|
/* sleep a tiny bit here to avoid the secure erase code racing with |
|
* programs spawned by udev |
|
*/ |
|
@@ -2382,6 +2397,7 @@ erase_ata_device (UDisksBlock *block, |
|
out: |
|
g_clear_object (&ata); |
|
g_clear_object (&drive_object); |
|
+ g_clear_object (&block_object); |
|
return ret; |
|
} |
|
|
|
|