From 3daf73a01b6c2853c0f12d8c7b0e17cfee952971 Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Sat, 4 Jun 2016 13:03:16 +0100 Subject: [PATCH] Prevent assert failure from OperationDelete::get_partition_new() (#767233) Composing these operations caused GParted to abort on an assert failure: (1) Delete an existing partition, (2) Create a new partition, (3) Delete new partition. This is the equivalent issue as fixed in the previous commit, except with the delete operation rather than the check operation: Prevent assert failure from OperationCheck::get_partition_new() (#767233) # ./gpartedbin ====================== libparted : 2.4 ====================== ** ERROR:OperationDelete.cc:41:virtual GParted::Partition& GParted::OperationDelete::get_partition_new(): assertion failed: (false) Aborted (core dumped) # gdb ./gpartedbin core.19232 --batch --quiet --ex backtrace -ex quit [New Thread 19232] [New Thread 19234] [Thread debugging using libthread_db enabled] Core was generated by `./gpartedbin'. Program terminated with signal 6, Aborted. #0 0x000000361f2325e5 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 64 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig); #0 0x000000361f2325e5 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 #1 0x000000361f233dc5 in abort () at abort.c:92 #2 0x0000003620a67324 in g_assertion_message (domain=, file=, line=, func=0x50fcc0 "virtual GParted::Partition& GParted::OperationDelete::get_partition_new()", message=0x1b55f60 "assertion failed: (false)") at gtestutils.c:1358 #3 0x0000003620a678f0 in g_assertion_message_expr (domain=0x0, file=0x50fa68 "OperationDelete.cc", line=41, func=0x50fcc0 "virtual GParted::Partition& GParted::OperationDelete::get_partition_new()", expr=) at gtestutils.c:1369 #4 0x000000000049aa0d in GParted::OperationDelete::get_partition_new (this=0x1b321b0) at OperationDelete.cc:41 #5 0x00000000004c6700 in GParted::Win_GParted::activate_delete (this=0x7ffc91403670) at Win_GParted.cc:2068 ... As before the crash is happened in Win_GParted::activate_delete() as it was going through the list of operations removing those which applied to the never created partition. It came across the delete operation of an existing partition and called get_partition_new(). As partition_new was not set or used by the delete operation this asserted false and crashed GParted. Unlike the check operation case, the delete operation doesn't have a partition afterwards. (As GParted represents unallocated space with partition objects then the delete operation could be populated with a new partition by constructing the correctly merged unallocated space partition object, but that is what OperationDelete::apply_to_visual() does and having a place holder doesn't seem like the right thing to do). Instead exclude delete operations, on existing partitions, when looking for operations applying to this not yet created partition as they are mutually exclusive. Bug 767233 - GParted core dump on assert failure in OperationDelete::get_partition_new() --- src/Win_GParted.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc index 27bd45bc..57b1df52 100644 --- a/src/Win_GParted.cc +++ b/src/Win_GParted.cc @@ -2065,14 +2065,16 @@ void Win_GParted::activate_delete() { //remove all operations done on this new partition (this includes creation) for ( int t = 0 ; t < static_cast( operations .size() ) ; t++ ) - if ( operations[t]->get_partition_new().get_path() == selected_partition_ptr->get_path() ) + if ( operations[t]->type != OPERATION_DELETE && + operations[t]->get_partition_new().get_path() == selected_partition_ptr->get_path() ) remove_operation( t-- ) ; //determine lowest possible new_count new_count = 0 ; for ( unsigned int t = 0 ; t < operations .size() ; t++ ) - if ( operations[t]->get_partition_new().status == STAT_NEW && - operations[t]->get_partition_new().partition_number > new_count ) + if ( operations[t]->type != OPERATION_DELETE && + operations[t]->get_partition_new().status == STAT_NEW && + operations[t]->get_partition_new().partition_number > new_count ) new_count = operations[t]->get_partition_new().partition_number; new_count += 1 ;