--- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -272,7 +272,7 @@ static int hidraw_open(struct inode *ino goto out; } - down_read(&minors_rwsem); + down_write(&minors_rwsem); if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { err = -ENODEV; goto out_unlock; @@ -301,7 +301,7 @@ static int hidraw_open(struct inode *ino spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags); file->private_data = list; out_unlock: - up_read(&minors_rwsem); + up_write(&minors_rwsem); out: if (err < 0) kfree(list); @@ -332,6 +332,7 @@ static void drop_ref(struct hidraw *hidr if (!hidraw->open) { if (!hidraw->exist) { hidraw_table[hidraw->minor] = NULL; + BUG_ON(!list_empty(&hidraw->list)); kfree(hidraw); } else { /* close device for last reader */