Possible double free in iowarrior.ko

From: Anton Volkov
Date: Tue Aug 22 2017 - 10:51:21 EST


Hello.

While searching for races in the Linux kernel I've come across "drivers/usb/misc/iowarrior.ko" module. Here are questions that I came up with while analyzing results. Lines are given using the info from Linux v4.12.

Consider the following case:

Thread 1: Thread 2:
iowarrior_release iowarrior_disconnect
mutex_lock(&dev->mutex)
dev->present = 0
(iowarrior.c: line 889)
mutex_lock(&dev->mutex) mutex_unlock(&dev->mutex)
dev->opened = 0
(iowarrior.c: line 666) if(dev->opened){
if(dev->present){ //dev->opened == 0
//dev->present ==0
} else { } else {
mutex_unlock(&dev->mutex) iowarrior_delete(dev)
iowarrior_delete(dev) }
}

In this case double free of several pointers inside iowarrior_delete becomes possible and no calls to usb_kill_urb() and wake_up_interruptible() are present. Is this feasible from your point of view? If so, maybe it is a good idea to move mutex_unlock(&dev->mutex) in iowarrior_disconnect() further down like in iowarrior_release() in both 'if' branches?

Thank you for your time

-- Anton Volkov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org
e-mail: avolkov@xxxxxxxxx