Skip to content

Commit ddaf098

Browse files
committed
driver core: class: properly reference count class_dev_iter()
When class_dev_iter is initialized, the reference count for the subsys private structure is incremented, but never decremented, causing a memory leak over time. To resolve this, save off a pointer to the internal structure into the class_dev_iter structure and then when the iterator is finished, drop the reference count. Reported-and-tested-by: syzbot+e7afd76ad060fa0d2605@syzkaller.appspotmail.com Fixes: 7b884b7 ("driver core: class.c: convert to only use class_to_subsys") Reported-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr> Cc: Alan Stern <stern@rowland.harvard.edu> Acked-by: Rafael J. Wysocki <rafael@kernel.org> Tested-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr> Link: https://lore.kernel.org/r/2023051610-stove-condense-9a77@gregkh Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 1e94be7 commit ddaf098

File tree

2 files changed

+3
-0
lines changed

2 files changed

+3
-0
lines changed

drivers/base/class.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class,
320320
start_knode = &start->p->knode_class;
321321
klist_iter_init_node(&sp->klist_devices, &iter->ki, start_knode);
322322
iter->type = type;
323+
iter->sp = sp;
323324
}
324325
EXPORT_SYMBOL_GPL(class_dev_iter_init);
325326

@@ -361,6 +362,7 @@ EXPORT_SYMBOL_GPL(class_dev_iter_next);
361362
void class_dev_iter_exit(struct class_dev_iter *iter)
362363
{
363364
klist_iter_exit(&iter->ki);
365+
subsys_put(iter->sp);
364366
}
365367
EXPORT_SYMBOL_GPL(class_dev_iter_exit);
366368

include/linux/device/class.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct class {
7474
struct class_dev_iter {
7575
struct klist_iter ki;
7676
const struct device_type *type;
77+
struct subsys_private *sp;
7778
};
7879

7980
int __must_check class_register(const struct class *class);

0 commit comments

Comments
 (0)