Describe the Bug
A mutex leak in remove_from_front() causes permanent deadlock when an exception is thrown while holding the lock. When compiled with CONSISTENCY_CHECKING defined, the function acquires a mutex but throws std::runtime_error without releasing it, as C++ exception unwinding bypasses the pthread_mutex_unlock() call.
Location: src/prioque.cpp (lines 222-247)
void remove_from_front(Queue * q, void *element)
{
Queue_element temp;
// lock entire queue
pthread_mutex_lock(&(q->lock)); // Line 222: Lock acquired
#if defined(CONSISTENCY_CHECKING)
if(q->queue == 0) {
std::string msg("Malloc failed in function remove_from_front()\n");
fprintf(stderr, "%s", msg.c_str());
throw std::runtime_error(msg); // Line 228: BUG - exception with lock held!
}
else
#endif
{
memcpy(element, q->queue->info, q->elementsize);
free(q->queue->info);
q->queue->info = NULL;
temp = q->queue;
q->queue = q->queue->next;
free(temp);
(q->queuelength)--;
}
nolock_rewind_queue(q);
// release lock on queue
pthread_mutex_unlock(&(q->lock)); // Line 247: Never reached on exception
}
Impact:
- Queue mutex
q->lock remains permanently locked when exception is thrown
- All subsequent queue operations block permanently on
pthread_mutex_lock()
- File carving operations completely stall → Denial of Service
- Forensic analysis process becomes unresponsive
Execution Flow:
Thread 1:
→ pthread_mutex_lock(&(q->lock)) // Lock acquired
→ Check: q->queue == 0 // Condition TRUE (NULL queue)
→ throw std::runtime_error(msg) // Exception thrown
→ C++ stack unwinding begins
→ pthread_mutex_unlock() SKIPPED // BUG: lock never released
→ q->lock remains locked forever
Thread 2, 3, ...N:
→ Attempt any queue operation
→ pthread_mutex_lock(&(q->lock)) // BLOCKS permanently
→ All carving threads frozen
→ Scalpel becomes unresponsive
This occurs when Scalpel is compiled with CONSISTENCY_CHECKING defined and q->queue is NULL. The C++ exception mechanism unwinds the stack but does not call pthread_mutex_unlock(), leaving the mutex permanently locked.
I would appreciate it if you could review and confirm this potential issue. Thank you for your time and for maintaining this project!
Describe the Bug
A mutex leak in
remove_from_front()causes permanent deadlock when an exception is thrown while holding the lock. When compiled withCONSISTENCY_CHECKINGdefined, the function acquires a mutex but throwsstd::runtime_errorwithout releasing it, as C++ exception unwinding bypasses thepthread_mutex_unlock()call.Location: src/prioque.cpp (lines 222-247)
Impact:
q->lockremains permanently locked when exception is thrownpthread_mutex_lock()Execution Flow:
This occurs when Scalpel is compiled with
CONSISTENCY_CHECKINGdefined andq->queueis NULL. The C++ exception mechanism unwinds the stack but does not callpthread_mutex_unlock(), leaving the mutex permanently locked.I would appreciate it if you could review and confirm this potential issue. Thank you for your time and for maintaining this project!