From nobody Mon Sep 28 07:22:51 2026 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (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 4BF083B14D6 for ; Tue, 25 Aug 2026 06:37:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787639864; cv=none; b=C+dwujgMjfPzueMu/xiHa2ULTZTNooEYEH3WcfQYoGxX69zJHw7ZFm1sKT3rzqBrLsOlCpG046o9+RRMTTJ5cihERijkiWXonYiuoXsQnfTYRzJIBvZKdDOP235leVJOFAs3zvFezsYpUplZQ33+3e+0YR/aEiUPkFwBce9b0Zo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787639864; c=relaxed/simple; bh=qE50yLD2V3tITUPrI+VW+ML5IxIwxwtiEGU8xsuoxL8=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=qC8FOgLz/cPrrrijPgRAfy8SXkpFk+Rnw8Fq4PRfkdqT78UoBd20S7S7BOPdLoKnLIqC8pT0ZX5/GN54B7RGLWRYQA7C3cGAzwIzbS0jFUSdWolER+xPMvJriCL+SNE5YZ9dbVrg8MAOfspArJFY2O7PZDrCgR29CoWpQ7BQjs4= 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=WPPxb8aX; arc=none smtp.client-ip=209.85.218.45 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="WPPxb8aX" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-c1671ec8692so622411366b.0 for ; Mon, 24 Aug 2026 23:37:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787639861; x=1788244661; 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=Ci3WaRxL1LKBNX+6XcT/a5YijLEiic6s2oitvILr4v4=; b=WPPxb8aX8QDACdttdq/wAVwTvvTFLOG3gdhfTku71kOb95llZ+5ogG2BqSdi+ZtrMN LZh4dVSeaR5JHUEV74f7uMVbqXLNcC7Cp37NAoC2BbTZkfmJMlBaZ/CkgAjPK+rPpY2K nRvbyZjwZtUJuMX8t/vvwkmTmlZf4ubxXCL+V71ih2MIVQArbiBEVFMUvjBNOhVLV5eX wslO0L8poaA1xDhDX3Fuke1FC9V496Uz3As423vyUaS+B9Ap/N+xwmV1MXvH6MCLnn7N ujMsw/OTyUbDZdUePclOZuRb1CSd5p7A5qYeDRbQGsRMWEWKUVyHNosxxs+NO0yYE92R 70eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787639861; x=1788244661; 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=Ci3WaRxL1LKBNX+6XcT/a5YijLEiic6s2oitvILr4v4=; b=Z7Vn/TwlfeNm6HU+4PFk22V37UB0wX0Y8J/oVQUFHU8iyzMJFaZwRYcNq7kExvnV/W lcUFItLb1vT9Rgh51zzJgP7V3PZcbaVTEu0iP1An7BDah+QFDwraFxN3+Sw0WCRMwvyM RA61Ouk75jnpAEkOc599Iy24ic+k3TzKc2fRMGKEswuGNAzotFr4Ljn1nq/QO3Vv+rWU XnUmW/ZX7O58mz2uc61Wj64Dml3L4/lWoj1jFFZR64VFRfoMVe8qJFMQKyHDTWOl40Ka YfeoOpbyltrkmC0aKKbQe5HUU8y2kTIQQKp6p5tzxJhWcm9AQjNzS8vWNQ84r49FDwBQ pK6A== X-Forwarded-Encrypted: i=1; AHgh+RqLEdEJmTsHgyrGPtQ6BiSyHPutxb+DMJzQ3Lb5WAfnp78jzXEAIGY8j2jSc5mt1N8HeB2OnR5uT5M3w34=@vger.kernel.org X-Gm-Message-State: AFuF++k5FRF9eVp5QO57mm8UM08loIF1kkYKt77gBYU96NCtLaiyNj+L 46z4ciTiC+ZyeljFrNsu5jPDvux2ieiBGySAL3Ld62otskS4fiL2YqwT X-Gm-Gg: AR+sD1212r60rduraQfJSClj8sJQiZ+vWNmIj/S9jE1lIs6SW6Wa8c74LcR/RQ9+y7M NkKkwHigjF3yA4lbBKL8FjrFLUROt8FhWhEFSCTsArIL5f26l2lQlLJ+GeSugBe+LRzRpdCzwZY zzLcM9KkoklF6cTZ1rl7gmy7s+UbjQSzTOOgi9Rkgq8w16/d/7NT+X6+5+LUxgnoez3Q2llHUWp Q1t2iySfMguhtWzaX429i44eIYCPY7dU9um9ssx+krwAhLFVqsQmfnEGp6hhlOJYrw1UD15x7pV Wiu2pPz3ddKDapyacv7WDHqVRyqm1fUzm35zxcO6if9oD6tauVqAYhFjAzXsJAOZ1fFpuMK1uLt Gaysc6EyVeo0DiaJiaBmT/TGnRgOs7JjB5UadKOT8aAbpHXdYTttivm686QeEQKXl0TvWp55PL7 2sgEKM8ShF/s2SoV64sCqdbhK90tbXNg4l7WOh9oy0PUSLIop7tkVKK5ecg0JsjuZgsmRsvIoc8 7rQ5Ufjm61F1ziFzByxTFisLDVZ+e5VDIvcZ2XacNFWLG5bZQc0E/o8St0i/mVAEfNq0WS+LBGe kBBh68hdCKcbLGIWK+E6MMlQcmxAUbxydQ+YqsJLlzSNtKBXLE/e/k54huppQ+2g6GjW X-Received: by 2002:a17:907:9626:b0:c24:87e3:b8b8 with SMTP id a640c23a62f3a-c249209907amr2334856866b.17.1787639861208; Mon, 24 Aug 2026 23:37:41 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a02-3100-af54-b201-7419-a557-62e9-4d13.310.pool.telefonica.de. [2a02:3100:af54:b201:7419:a557:62e9:4d13]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c249689fa97sm1442110066b.57.2026.08.24.23.37.39 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 24 Aug 2026 23:37:40 -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 , Mark Brown , Liam Girdwood , Cezary Rojewski , Kuninori Morimoto , linux-sound@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v3] drm/vc4: hdmi: Unregister the ASoC card on unbind Date: Tue, 25 Aug 2026 08:37:35 +0200 Message-Id: <20260825063735.14676-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 remains alive until the final reference to the DRM device is dropped. The card is registered with devm_snd_soc_register_card() on the HDMI platform device from the component bind callback, so its devres node starts out in the component's devres group and would ordinarily be released at component unbind, while vc4_hdmi is still alive. Whenever an ASoC component is registered, the core retries every card waiting for components. For a devm-managed card, each retry destroys and re-adds its devres node. Because snd_soc_bind_card() requeues the card and converts -EPROBE_DEFER to success, even a retry that still defers can move the node outside the now-closed component devres group. It is then released only at HDMI platform driver detach rather than component unbind. With no DRM file open, as in the reproducer below, aggregate teardown drops the final DRM reference. This frees vc4_hdmi before the HDMI platform device's devres release, so snd_soc_unregister_card() accesses 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 devm_card_bind_release / devres_release_all / driver_detach Allocated by task 171: drmm_kmalloc / vc4_hdmi_bind Freed by task 262 (rmmod): drm_dev_put / component_del If a DRM file remains open through platform detach, the final DRM release is deferred until the last close and the ordering is reversed. Register the card without devm and unregister it from the component unbind callback, where both the HDMI device resources and vc4_hdmi are alive. This makes the card lifetime independent of when the final DRM reference is dropped. Fixes: 42d99857d6f0 ("ASoC: core: Move all users to deferrable card binding= ") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Karl Mehltretter --- v3: - Clarify that DRM-managed memory is released when the final DRM reference is dropped, not necessarily at driver unbind. With no open DRM file this precedes the HDMI platform devres release; with a file held open through detach the ordering is reversed. No code changes. v2: https://lore.kernel.org/r/20260823173740.2983-1-kmehltretter@gmail.com/ - Preserve the existing ASoC component-lifetime comment and document at the card registration site how deferrable binding can move the card's devres node outside the component devres group. - Point Fixes at the deferrable card binding change. - Add the ASoC maintainers and linux-sound recipients, add the stable trailer, and update Assisted-by to the current format. v1: https://lore.kernel.org/r/20260822143218.68764-1-kmehltretter@gmail.com/ 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 | 24 +++++++++++++++++++++--- drivers/gpu/drm/vc4/vc4_hdmi.h | 1 + 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 17c8635c5afa..7e312932488a 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -2422,12 +2422,18 @@ 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); + + /* + * Deferred card binding can move a devm registration outside the + * component devres group, so unregister the card explicitly at unbind. + */ + 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 +3351,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)