From e0c24bddf07c7735860fe654061938218732c92d Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 12 Feb 2018 15:45:47 +1030 Subject: fsi: master: Clarify master lifetimes & fix use-after-free in hub master Once we call fsi_master_unregister, the core will put_device, potentially freeing the hub master. This change adds a comment explaining the lifetime of an allocated fsi_master. We then add a reference from the driver to the hub master, so it stays around until we've finished ->remove(). Signed-off-by: Jeremy Kerr Tested-by: Christopher Bostic Signed-off-by: Joel Stanley Signed-off-by: Greg Kroah-Hartman --- drivers/fsi/fsi-master.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/fsi/fsi-master.h') diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h index 18bd4ad79356..ee0b46086026 100644 --- a/drivers/fsi/fsi-master.h +++ b/drivers/fsi/fsi-master.h @@ -37,6 +37,21 @@ struct fsi_master { #define dev_to_fsi_master(d) container_of(d, struct fsi_master, dev) +/** + * fsi_master registration & lifetime: the fsi_master_register() and + * fsi_master_unregister() functions will take ownership of the master, and + * ->dev in particular. The registration path performs a get_device(), which + * takes the first reference on the device. Similarly, the unregistration path + * performs a put_device(), which may well drop the last reference. + * + * This means that master implementations *may* need to hold their own + * reference (via get_device()) on master->dev. In particular, if the device's + * ->release callback frees the fsi_master, then fsi_master_unregister will + * invoke this free if no other reference is held. + * + * The same applies for the error path of fsi_master_register; if the call + * fails, dev->release will have been invoked. + */ extern int fsi_master_register(struct fsi_master *master); extern void fsi_master_unregister(struct fsi_master *master); -- cgit v1.2.3