From: "Cássio Gabriel" <cassiogabrielcontato@gmail.com>
To: Takashi Iwai <tiwai@suse.com>, Jaroslav Kysela <perex@perex.cz>
Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
notify@kernel.org,
"Cássio Gabriel" <cassiogabrielcontato@gmail.com>
Subject: [PATCH 1/3] ALSA: control: Use scoped cleanup for user control buffers
Date: Thu, 04 Jun 2026 01:48:12 -0300 [thread overview]
Message-ID: <20260604-alsa-scoped-cleanups-v1-1-10c43152a728@gmail.com> (raw)
In-Reply-To: <20260604-alsa-scoped-cleanups-v1-0-10c43152a728@gmail.com>
User-defined control TLV data and enum names are copied from user space
with vmemdup_user() before being installed in the user_element. Until
ownership is transferred, these temporary buffers have to be released on
every validation exit.
Use __free(kvfree) for the temporary buffers and no_free_ptr() when
ownership is transferred to the user_element. This removes the manual
kvfree() calls from the unchanged-TLV and enum-name validation paths,
makes the ownership hand-off explicit, and keeps the existing allocation
accounting and ABI unchanged.
No functional change is intended.
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/core/control.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/sound/core/control.c b/sound/core/control.c
index 5e51857635e6..28fffbe92e66 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1550,7 +1550,6 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
unsigned int size)
{
struct user_element *ue = snd_kcontrol_chip(kctl);
- unsigned int *container;
unsigned int mask = 0;
int i;
int change;
@@ -1564,17 +1563,16 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
if (check_user_elem_overflow(ue->card, (ssize_t)(size - ue->tlv_data_size)))
return -ENOMEM;
- container = vmemdup_user(buf, size);
+ unsigned int *container __free(kvfree) = vmemdup_user(buf, size);
+
if (IS_ERR(container))
return PTR_ERR(container);
change = ue->tlv_data_size != size;
if (!change)
change = memcmp(ue->tlv_data, container, size) != 0;
- if (!change) {
- kvfree(container);
+ if (!change)
return 0;
- }
if (ue->tlv_data == NULL) {
/* Now TLV data is available. */
@@ -1587,7 +1585,7 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
kvfree(ue->tlv_data);
}
- ue->tlv_data = container;
+ ue->tlv_data = no_free_ptr(container);
ue->tlv_data_size = size;
// decremented at private_free.
ue->card->user_ctl_alloc_size += size;
@@ -1628,7 +1626,6 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kctl, int op_flag,
/* called in controls_rwsem write lock */
static int snd_ctl_elem_init_enum_names(struct user_element *ue)
{
- char *names, *p;
size_t buf_len, name_len;
unsigned int i;
const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr;
@@ -1641,27 +1638,28 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue)
if (check_user_elem_overflow(ue->card, buf_len))
return -ENOMEM;
- names = vmemdup_user((const void __user *)user_ptrval, buf_len);
+ char *names __free(kvfree) = vmemdup_user((const void __user *)user_ptrval,
+ buf_len);
+
if (IS_ERR(names))
return PTR_ERR(names);
/* check that there are enough valid names */
- p = names;
+ char *p = names;
+
for (i = 0; i < ue->info.value.enumerated.items; ++i) {
- if (buf_len == 0) {
- kvfree(names);
+ if (buf_len == 0)
return -EINVAL;
- }
+
name_len = strnlen(p, buf_len);
- if (name_len == 0 || name_len >= 64 || name_len == buf_len) {
- kvfree(names);
+ if (name_len == 0 || name_len >= 64 || name_len == buf_len)
return -EINVAL;
- }
+
p += name_len + 1;
buf_len -= name_len + 1;
}
- ue->priv_data = names;
+ ue->priv_data = no_free_ptr(names);
ue->info.value.enumerated.names_ptr = 0;
// increment the allocation size; decremented again at private_free.
ue->card->user_ctl_alloc_size += ue->info.value.enumerated.names_length;
--
2.54.0
next prev parent reply other threads:[~2026-06-04 4:48 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-04 4:48 [PATCH 0/3] ALSA: scoped cleanup improvements for ALSA core Cássio Gabriel
2026-06-04 4:48 ` Cássio Gabriel [this message]
2026-06-04 4:48 ` [PATCH 2/3] ALSA: core: Add scoped cleanup helper for card references Cássio Gabriel
2026-06-04 4:48 ` [PATCH 3/3] ALSA: seq: oss: Use scoped cleanup for temporary MIDI use lock Cássio Gabriel
2026-06-04 8:21 ` [PATCH 0/3] ALSA: scoped cleanup improvements for ALSA core Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260604-alsa-scoped-cleanups-v1-1-10c43152a728@gmail.com \
--to=cassiogabrielcontato@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=notify@kernel.org \
--cc=perex@perex.cz \
--cc=tiwai@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®