Message ID | 20220610092924.754942-35-maxime@cerno.tech (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/vc4: Fix hotplug for vc4 | expand |
Am 10.06.22 um 11:28 schrieb Maxime Ripard: > Our internal structure that stores the DRM entities structure is allocated > through a device-managed kzalloc. > > This means that this will eventually be freed whenever the device is > removed. In our case, the most like source of removal is that the main 'most likely source' > device is going to be unbound, and component_unbind_all() is being run. > > However, it occurs while the DRM device is still registered, which will > create dangling pointers, eventually resulting in use-after-free. > > Switch to a DRM-managed allocation to keep our structure until the DRM > driver doesn't need it anymore. > > Signed-off-by: Maxime Ripard <maxime@cerno.tech> > --- > drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c > index 6aadb65eb640..eb8ff7b258d1 100644 > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c > @@ -2833,9 +2833,10 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) > struct device_node *ddc_node; > int ret; > > - vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL); > + vc4_hdmi = drmm_kzalloc(drm, sizeof(*vc4_hdmi), GFP_KERNEL); > if (!vc4_hdmi) > return -ENOMEM; > + > mutex_init(&vc4_hdmi->mutex); > spin_lock_init(&vc4_hdmi->hw_lock); > INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 6aadb65eb640..eb8ff7b258d1 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -2833,9 +2833,10 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) struct device_node *ddc_node; int ret; - vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL); + vc4_hdmi = drmm_kzalloc(drm, sizeof(*vc4_hdmi), GFP_KERNEL); if (!vc4_hdmi) return -ENOMEM; + mutex_init(&vc4_hdmi->mutex); spin_lock_init(&vc4_hdmi->hw_lock); INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq);
Our internal structure that stores the DRM entities structure is allocated through a device-managed kzalloc. This means that this will eventually be freed whenever the device is removed. In our case, the most like source of removal is that the main device is going to be unbound, and component_unbind_all() is being run. However, it occurs while the DRM device is still registered, which will create dangling pointers, eventually resulting in use-after-free. Switch to a DRM-managed allocation to keep our structure until the DRM driver doesn't need it anymore. Signed-off-by: Maxime Ripard <maxime@cerno.tech> --- drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)