Linux kernel loop Device NULL Pointer Dereference

Another one from the ChangeLog file of 2.6.32-rc6 I noticed was this really interesting bug. The bug was discovered and reported by Alexey Dobriyan and it was fixed in 2.6.32-rc6 release of the Linux kernel.
Here is the susceptible code as seen in 2.6.31’s drivers/block/loop.c source code file…

And its second argument is the block device to be work on. However, it’s not really hard to see that if for some reason mount of that device fails, the block device pointer represented by ‘bdev’ will be set to NULL.
If we move back to loop_clr_fd() we’ll see that bd_set_size() checks that the ‘bdev’ is not NULL but the subsequent call to ioctl_by_bdev() is issued based entirely on the ‘max_part’ (maximum number of partitions per loop device) being greater than zero. This call to ioctl_by_bdev() located at fs/block_dev.c will result in a NULL pointer dereference since it will invoke blkdev_ioctl() with no checks on the NULL block device pointer like this:

Interesting bug… rescan_partitions() from fs/partitions/check.c looks very interesting knowing that you can control both of its arguments. This was fixed by adding the missing NULL check in the block device pointer before issuing the IOCTL call like this: