From nobody Mon Sep 28 11:39:39 2026 Received: from mail-ej1-f42.google.com (mail-ej1-f42.google.com [209.85.218.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 737DF2DEA61 for ; Sat, 22 Aug 2026 14:32:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787409150; cv=none; b=q9cx1mvHqiagfdwlEY8ytC4J4zz6KpAVB2zRR4TtVz5f+HMdDA754/ZdDe/GIaaFnl+0lDmUS/Y1tb4FbdblTJj925EnZdNFvA7Qd1VAgXToq4iRVIHTNjPloKg/LP4RmQk+3I5lZ8WdhEgNpJCWf4lD6P/VAkOqdMY/813l1+0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787409150; c=relaxed/simple; bh=n2URlp40WYenWdFHAyjv/o6e4/I419bulzHbisFSJ0U=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=gfiHFYLVp/k+xsF7UX0Xajb9P3rIsz5t+nNXSVn+qGmyGlSG7psALnV5CY2p0bDucfK8tf/XPAHsj+SJZPEET3ftTb8Jfo+zPkDHReMihHTSDFGzR1DSOYffqZSnIQzk+7WTWciYGw3KH3sWyXjmFvjGZdDqcx+9pJEVSO1czx4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=M4E9gEcE; arc=none smtp.client-ip=209.85.218.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="M4E9gEcE" Received: by mail-ej1-f42.google.com with SMTP id a640c23a62f3a-c15b1da6b82so210655166b.1 for ; Sat, 22 Aug 2026 07:32:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787409146; x=1788013946; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=5m/bovsJ2cKRYH/evjqdCUTYp41mLIq3pohE3pwpIfM=; b=M4E9gEcE50u+8/5uzdB8HmFgJ0rdnJzh0iWNPOKdz6WySJ+vb4hTJWtOMv4XEytgla LQ3JLVT5z+g8yFqWJ/nCccQIjv6OemYZy/n28AVEQ0W8fH5krqQVWeWqlV3stniWb686 iN2PHO5itXjZSIbkZcIQ4lMD29hnHHICUh5nrOYLFwkOwgDpPdW+qYRG5sG4MjkL6UOj /J6lxB9s8sV6XFXPD7Mn39Z20qdDpuClev6ByRRfY+decvDVMa4KK/xz4cE1RmYAg/Ak 4PuZKLZrgrzAw7Kh0g9JpQyeomIPx4IC5mukJ6c5tZ9E0pOkg2TbBYaXw6v401HQmm9y DAtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787409146; x=1788013946; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=5m/bovsJ2cKRYH/evjqdCUTYp41mLIq3pohE3pwpIfM=; b=IV54lNYImd5CfDHAZQzMMD8gNvuFnETdFZwuZ1uSDjaMHGLqBFo5gVpWkD0gsDpt7h rFizb4k5pwJPZuww/+uOyfCzyV4DBIdYQVm1TPW8PXCmkwgGbqqK/JuB7jkMH16woRFb UwCnar1nsZn7W8oCHpNdyPsmcF0938myCrpmozhSAJqXvj9pXTgwRSZ9LoMZpuZ+h292 P2AXMKVQXmqKhGOcK+KvngeVitOEs+cKfeZE6QgAegeqny8HrSJrDXO0uTfPI7DhzkER NB0i+aM7oe6dgzKeAoBvgSh16KYLuKPLnAYNqtyt//J0fko7zU4j/IJGSyIRottd53y3 LbuQ== X-Forwarded-Encrypted: i=1; AHgh+RpY/ecEOEuaZhu2Krn5E3xJUWohahC2RKP5SRLAJH+mMVjV/VDbRuuDhfyfmlE8TLMNJjf1iilszBPRyNA=@vger.kernel.org X-Gm-Message-State: AFuF++nZp3N/iMldlUNrkKtGU9ZHtLClkwpDJ7Ld2dvPxDF55nLvBixv VrkxqSwUCX/aZyvKXdEswWqXrLImPJpOzn6lyPOqblsNBaqMG3r+l5pu X-Gm-Gg: AR+sD109gMl+OBmNInaMVOb5/fQw9q2FiVOHz6//XVhxgAWxIlB9YPfPu4YUbzdKMTp tSWjQ6Fvs476aTPdDM1M4vtAktHuncm1wBE9Ew3oqjTZrkGh1dXAeJRxFxG2VYKe48KUiD1GAap GJ7tBYOqRBb2SmtfiAMn8J34+ezy9uZXTWAHapndLRPOQw/Y3GHobS17+SKq011f8pdv4C1gJC4 JSI2ftyVQZuwpAp28QyLAHdAxq5tutjJSvnPVQAeGozxZSx3WMI/lmf67vhE1CJ/t1Oht99/sYl I2WY73yDBoL9Gbu4msy4/b/SuxTiv674SO8CzP9iBCN1/b85+WqSmcK1bziNZufXP1NHiuKfUId EBM1rHqTLP2s1eGDCNZbwH4T8WuXTIAt5MoBDC+murnBsBHS0aj5k0dSESlfx0cV6A9hR3aOVIv rM/DSuJSBV8p86R1heAEqrMtbRA+PA0GMAC66MnFlSeZEZUuBgFVihVT2X39kJtXo1WZotmiKe6 fH+5xwwDmqmrPbg63LAPTKMa21+wQtwMmtMvHDyOVBrE94m1wAFwasdd5P/TCwm+RGQnF+i50GN xf01PGSPw3O30ReyakqphjhxuwjnGa7cpdHgijvXfIFuSEzvJos4YDUP23+uQf2xkamG6jodDAC Cl0U0 X-Received: by 2002:a17:907:d12:b0:c15:f26a:3438 with SMTP id a640c23a62f3a-c246a6b0994mr1614247666b.24.1787409146368; Sat, 22 Aug 2026 07:32:26 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a02-3100-a0f5-8c01-3de3-cd62-aa6f-2fb0.310.pool.telefonica.de. [2a02:3100:a0f5:8c01:3de3:cd62:aa6f:2fb0]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c249689fa1dsm317362066b.56.2026.08.22.07.32.25 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sat, 22 Aug 2026 07:32:25 -0700 (PDT) From: Karl Mehltretter To: Maxime Ripard , Dave Stevenson Cc: Karl Mehltretter , =?UTF-8?q?Ma=C3=ADra=20Canal?= , Raspberry Pi Kernel Maintenance , Maarten Lankhorst , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH] drm/vc4: hdmi: Unregister the ASoC card on unbind Date: Sat, 22 Aug 2026 16:32:18 +0200 Message-Id: <20260822143218.68764-1-kmehltretter@gmail.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" vc4_hdmi, including the embedded ASoC card, is DRM-managed and freed together with the DRM device when the aggregate device is torn down. The card however is registered device-managed on the HDMI platform device, whose release runs later, so snd_soc_unregister_card() operates on freed memory: # modprobe vc4; rmmod vc4 BUG: KASAN: slab-use-after-free in snd_soc_unregister_card Read of size 1 at addr ffff0000456a8450 by task rmmod/262 Allocated by task 171: drmm_kmalloc / vc4_hdmi_bind Freed by task 262 (rmmod): drm_managed_release / drm_dev_put Register the card without devm and unregister it from a component unbind callback, where the HDMI device resources and the DRM-managed structure are both still alive. Fixes: b4f2c70c1a7a ("drm/vc4: hdmi: Switch to drmm_kzalloc") Assisted-by: Claude:claude-fable-5 Signed-off-by: Karl Mehltretter --- Tested on a Raspberry Pi 400 (BCM2711), v7.2-11658-g26260251022f, with KASAN: report gone, rmmod/insmod loop clean. drivers/gpu/drm/vc4/vc4_hdmi.c | 46 ++++++++++++++++------------------ drivers/gpu/drm/vc4/vc4_hdmi.h | 1 + 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 17c8635c5afa..ce28075f77b6 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -2349,28 +2349,11 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4= _hdmi) vc4_hdmi->audio.dma_data.maxburst =3D 2; =20 /* - * NOTE: Strictly speaking, we should probably use a DRM-managed - * registration there to avoid removing all the audio components - * by the time the driver doesn't have any user anymore. - * - * However, the ASoC core uses a number of devm_kzalloc calls - * when registering, even when using non-device-managed - * functions (such as in snd_soc_register_component()). - * - * If we call snd_soc_unregister_component() in a DRM-managed - * action, the device-managed actions have already been executed - * and thus we would access memory that has been freed. - * - * Using device-managed hooks here probably leaves us open to a - * bunch of issues if userspace still has a handle on the ALSA - * device when the device is removed. However, this is mitigated - * by the use of drm_dev_enter()/drm_dev_exit() in the audio - * path to prevent the access to the device resources if it - * isn't there anymore. - * - * Then, the vc4_hdmi structure is DRM-managed and thus only - * freed whenever the last user has closed the DRM device file. - * It should thus outlive ALSA in most situations. + * The card is unregistered from the component unbind callback: + * a DRM-managed action can run after the device-managed ASoC + * resources are gone, and the device-managed release runs after + * the DRM-managed vc4_hdmi structure holding the card has been + * freed. Only at unbind time are both still alive. */ ret =3D devm_snd_dmaengine_pcm_register(dev, &pcm_conf, 0); if (ret) { @@ -2422,12 +2405,13 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4= _hdmi) * snd_soc_card_get_drvdata() if needed. */ snd_soc_card_set_drvdata(card, vc4_hdmi); - ret =3D devm_snd_soc_register_card(dev, card); + ret =3D snd_soc_register_card(card); if (ret) - dev_err_probe(dev, ret, "Could not register sound card\n"); + return dev_err_probe(dev, ret, "Could not register sound card\n"); =20 - return ret; + vc4_hdmi->audio.card_registered =3D true; =20 + return 0; } =20 static irqreturn_t vc4_hdmi_hpd_irq_thread(int irq, void *priv) @@ -3345,8 +3329,20 @@ static int vc4_hdmi_bind(struct device *dev, struct = device *master, void *data) return ret; } =20 +static void vc4_hdmi_unbind(struct device *dev, struct device *master, + void *data) +{ + struct vc4_hdmi *vc4_hdmi =3D dev_get_drvdata(dev); + + if (vc4_hdmi->audio.card_registered) { + snd_soc_unregister_card(&vc4_hdmi->audio.card); + vc4_hdmi->audio.card_registered =3D false; + } +} + static const struct component_ops vc4_hdmi_ops =3D { .bind =3D vc4_hdmi_bind, + .unbind =3D vc4_hdmi_unbind, }; =20 static int vc4_hdmi_dev_probe(struct platform_device *pdev) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index 29d461d4ee49..444c73513d86 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -106,6 +106,7 @@ struct vc4_hdmi_audio { struct snd_soc_dai_link_component platform; struct snd_dmaengine_dai_dma_data dma_data; bool streaming; + bool card_registered; }; =20 /* General HDMI hardware state. */ --=20 2.39.5 (Apple Git-154)