mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] ALSA: scoped cleanup improvements for ALSA core
@ 2026-06-04  4:48 Cássio Gabriel
  2026-06-04  4:48 ` [PATCH 1/3] ALSA: control: Use scoped cleanup for user control buffers Cássio Gabriel
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Cássio Gabriel @ 2026-06-04  4:48 UTC (permalink / raw)
  To: Takashi Iwai, Jaroslav Kysela
  Cc: linux-sound, linux-kernel, notify, Cássio Gabriel

This series converts a few local ALSA ownership patterns
to scoped cleanup helpers.

- The first patch uses __free(kvfree) for temporary user control buffers
in the ALSA control core.
- The second patch promotes the existing local snd_card_unref cleanup
helper to the common ALSA core header and uses it for temporary card
references in the control layer.
- The third patch applies the same idea to the temporary OSS sequencer
MIDI use-lock reference added for embedded SysEx event lifetime handling.

These are cleanup/hardening changes only. No functional change is intended.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
Cássio Gabriel (3):
      ALSA: control: Use scoped cleanup for user control buffers
      ALSA: core: Add scoped cleanup helper for card references
      ALSA: seq: oss: Use scoped cleanup for temporary MIDI use lock

 include/sound/core.h               |  2 ++
 sound/core/control.c               | 36 +++++++++++++++++-------------------
 sound/core/control_led.c           | 11 ++++-------
 sound/core/seq/oss/seq_oss_event.h |  1 +
 sound/core/seq/oss/seq_oss_ioctl.c | 10 ++++------
 sound/core/seq/oss/seq_oss_rw.c    |  5 ++---
 6 files changed, 30 insertions(+), 35 deletions(-)
---
base-commit: 10a5707d968cf679d3ceb849eae5317b45c80c60
change-id: 20260601-alsa-scoped-cleanups-2b22958dab12

Best regards,
--  
Cássio Gabriel <cassiogabrielcontato@gmail.com>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] ALSA: control: Use scoped cleanup for user control buffers
  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
  2026-06-04  4:48 ` [PATCH 2/3] ALSA: core: Add scoped cleanup helper for card references Cássio Gabriel
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Cássio Gabriel @ 2026-06-04  4:48 UTC (permalink / raw)
  To: Takashi Iwai, Jaroslav Kysela
  Cc: linux-sound, linux-kernel, notify, Cássio Gabriel

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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/3] ALSA: core: Add scoped cleanup helper for card references
  2026-06-04  4:48 [PATCH 0/3] ALSA: scoped cleanup improvements for ALSA core Cássio Gabriel
  2026-06-04  4:48 ` [PATCH 1/3] ALSA: control: Use scoped cleanup for user control buffers Cássio Gabriel
@ 2026-06-04  4:48 ` 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
  3 siblings, 0 replies; 5+ messages in thread
From: Cássio Gabriel @ 2026-06-04  4:48 UTC (permalink / raw)
  To: Takashi Iwai, Jaroslav Kysela
  Cc: linux-sound, linux-kernel, notify, Cássio Gabriel

Several ALSA paths acquire temporary card references with snd_card_ref()
and release them manually with snd_card_unref(). control_led.c already
defines a local cleanup helper for this pattern, while other core paths
still open-code the release.

Move the helper to the common ALSA core header and use it in control-layer
card-reference paths. This makes the ownership rule explicit and avoids
future missing-unref mistakes when adding early exits.

No functional change is intended.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
 include/sound/core.h     |  2 ++
 sound/core/control.c     |  6 +++---
 sound/core/control_led.c | 11 ++++-------
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/include/sound/core.h b/include/sound/core.h
index 4bb76c21c956..8b2ca95d13f7 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -319,6 +319,8 @@ static inline void snd_card_unref(struct snd_card *card)
 	put_device(&card->card_dev);
 }
 
+DEFINE_FREE(snd_card_unref, struct snd_card *, if (_T) snd_card_unref(_T))
+
 #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
 
 /* device.c */
diff --git a/sound/core/control.c b/sound/core/control.c
index 28fffbe92e66..7a8dc506221e 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -2291,7 +2291,6 @@ EXPORT_SYMBOL_GPL(snd_ctl_request_layer);
  */
 void snd_ctl_register_layer(struct snd_ctl_layer_ops *lops)
 {
-	struct snd_card *card;
 	int card_number;
 
 	scoped_guard(rwsem_write, &snd_ctl_layer_rwsem) {
@@ -2299,11 +2298,12 @@ void snd_ctl_register_layer(struct snd_ctl_layer_ops *lops)
 		snd_ctl_layer = lops;
 	}
 	for (card_number = 0; card_number < SNDRV_CARDS; card_number++) {
-		card = snd_card_ref(card_number);
+		struct snd_card *card __free(snd_card_unref) =
+			snd_card_ref(card_number);
+
 		if (card) {
 			scoped_guard(rwsem_read, &card->controls_rwsem)
 				lops->lregister(card);
-			snd_card_unref(card);
 		}
 	}
 }
diff --git a/sound/core/control_led.c b/sound/core/control_led.c
index d92b36ab5ec6..8cbacee57ce7 100644
--- a/sound/core/control_led.c
+++ b/sound/core/control_led.c
@@ -240,8 +240,6 @@ static void snd_ctl_led_notify(struct snd_card *card, unsigned int mask,
 	}
 }
 
-DEFINE_FREE(snd_card_unref, struct snd_card *, if (_T) snd_card_unref(_T))
-
 static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id,
 			      unsigned int group, bool set)
 {
@@ -758,18 +756,17 @@ static int __init snd_ctl_led_init(void)
 static void __exit snd_ctl_led_exit(void)
 {
 	struct snd_ctl_led *led;
-	struct snd_card *card;
 	unsigned int group, card_number;
 
 	snd_ctl_disconnect_layer(&snd_ctl_led_lops);
 	for (card_number = 0; card_number < SNDRV_CARDS; card_number++) {
 		if (!snd_ctl_led_card_valid[card_number])
 			continue;
-		card = snd_card_ref(card_number);
-		if (card) {
+		struct snd_card *card __free(snd_card_unref) =
+			snd_card_ref(card_number);
+
+		if (card)
 			snd_ctl_led_sysfs_remove(card);
-			snd_card_unref(card);
-		}
 	}
 	for (group = 0; group < MAX_LED; group++) {
 		led = &snd_ctl_leds[group];

-- 
2.54.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/3] ALSA: seq: oss: Use scoped cleanup for temporary MIDI use lock
  2026-06-04  4:48 [PATCH 0/3] ALSA: scoped cleanup improvements for ALSA core Cássio Gabriel
  2026-06-04  4:48 ` [PATCH 1/3] ALSA: control: Use scoped cleanup for user control buffers Cássio Gabriel
  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 ` Cássio Gabriel
  2026-06-04  8:21 ` [PATCH 0/3] ALSA: scoped cleanup improvements for ALSA core Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Cássio Gabriel @ 2026-06-04  4:48 UTC (permalink / raw)
  To: Takashi Iwai, Jaroslav Kysela
  Cc: linux-sound, linux-kernel, notify, Cássio Gabriel

The OSS sequencer write and out-of-band paths may receive a temporary
snd_use_lock_t reference from snd_seq_oss_process_event(). This was added
to keep MIDI device data alive until events with embedded SysEx data are
dispatched.

Use a scoped cleanup helper for that temporary reference. This keeps the
lifetime rule local to the variable declaration and avoids future missing
snd_use_lock_free() paths if these event handling paths gain more exits.

No functional change is intended.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
 sound/core/seq/oss/seq_oss_event.h |  1 +
 sound/core/seq/oss/seq_oss_ioctl.c | 10 ++++------
 sound/core/seq/oss/seq_oss_rw.c    |  5 ++---
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/sound/core/seq/oss/seq_oss_event.h b/sound/core/seq/oss/seq_oss_event.h
index a4524e51d0e9..54da1f810b3a 100644
--- a/sound/core/seq/oss/seq_oss_event.h
+++ b/sound/core/seq/oss/seq_oss_event.h
@@ -96,5 +96,6 @@ int snd_seq_oss_process_event(struct seq_oss_devinfo *dp, union evrec *q,
 int snd_seq_oss_process_timer_event(struct seq_oss_timer *rec, union evrec *q);
 int snd_seq_oss_event_input(struct snd_seq_event *ev, int direct, void *private_data, int atomic, int hop);
 
+DEFINE_FREE(seq_oss_use_lock, snd_use_lock_t *, if (_T) snd_use_lock_free(_T))
 
 #endif /* __SEQ_OSS_EVENT_H */
diff --git a/sound/core/seq/oss/seq_oss_ioctl.c b/sound/core/seq/oss/seq_oss_ioctl.c
index ce7a69d52b30..f1a79776773f 100644
--- a/sound/core/seq/oss/seq_oss_ioctl.c
+++ b/sound/core/seq/oss/seq_oss_ioctl.c
@@ -45,18 +45,17 @@ static int snd_seq_oss_oob_user(struct seq_oss_devinfo *dp, void __user *arg)
 {
 	unsigned char ev[8];
 	struct snd_seq_event tmpev;
-	snd_use_lock_t *lock = NULL;
 
 	if (copy_from_user(ev, arg, 8))
 		return -EFAULT;
 	memset(&tmpev, 0, sizeof(tmpev));
 	snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.client, dp->addr.port);
 	tmpev.time.tick = 0;
-	if (!snd_seq_oss_process_event(dp, (union evrec *)ev, &tmpev, &lock)) {
+
+	snd_use_lock_t *lock __free(seq_oss_use_lock) = NULL;
+
+	if (!snd_seq_oss_process_event(dp, (union evrec *)ev, &tmpev, &lock))
 		snd_seq_oss_dispatch(dp, &tmpev, 0, 0);
-		if (lock)
-			snd_use_lock_free(lock);
-	}
 	return 0;
 }
 
@@ -178,4 +177,3 @@ snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long ca
 	}
 	return 0;
 }
-
diff --git a/sound/core/seq/oss/seq_oss_rw.c b/sound/core/seq/oss/seq_oss_rw.c
index b7147ac78ee8..6e417b10a102 100644
--- a/sound/core/seq/oss/seq_oss_rw.c
+++ b/sound/core/seq/oss/seq_oss_rw.c
@@ -154,7 +154,6 @@ insert_queue(struct seq_oss_devinfo *dp, union evrec *rec, struct file *opt)
 {
 	int rc = 0;
 	struct snd_seq_event event;
-	snd_use_lock_t *lock = NULL;
 
 	/* if this is a timing event, process the current time */
 	if (snd_seq_oss_process_timer_event(dp->timer, rec))
@@ -166,6 +165,8 @@ insert_queue(struct seq_oss_devinfo *dp, union evrec *rec, struct file *opt)
 	event.type = SNDRV_SEQ_EVENT_NOTEOFF;
 	snd_seq_oss_fill_addr(dp, &event, dp->addr.client, dp->addr.port);
 
+	snd_use_lock_t *lock __free(seq_oss_use_lock) = NULL;
+
 	if (snd_seq_oss_process_event(dp, rec, &event, &lock))
 		return 0; /* invalid event - no need to insert queue */
 
@@ -175,8 +176,6 @@ insert_queue(struct seq_oss_devinfo *dp, union evrec *rec, struct file *opt)
 	else
 		rc = snd_seq_kernel_client_enqueue(dp->cseq, &event, opt,
 						   !is_nonblock_mode(dp->file_mode));
-	if (lock)
-		snd_use_lock_free(lock);
 	return rc;
 }
 		

-- 
2.54.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] ALSA: scoped cleanup improvements for ALSA core
  2026-06-04  4:48 [PATCH 0/3] ALSA: scoped cleanup improvements for ALSA core Cássio Gabriel
                   ` (2 preceding siblings ...)
  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 ` Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2026-06-04  8:21 UTC (permalink / raw)
  To: Cássio Gabriel
  Cc: Takashi Iwai, Jaroslav Kysela, linux-sound, linux-kernel, notify

On Thu, 04 Jun 2026 06:48:11 +0200,
Cássio Gabriel wrote:
> 
> This series converts a few local ALSA ownership patterns
> to scoped cleanup helpers.
> 
> - The first patch uses __free(kvfree) for temporary user control buffers
> in the ALSA control core.
> - The second patch promotes the existing local snd_card_unref cleanup
> helper to the common ALSA core header and uses it for temporary card
> references in the control layer.
> - The third patch applies the same idea to the temporary OSS sequencer
> MIDI use-lock reference added for embedded SysEx event lifetime handling.
> 
> These are cleanup/hardening changes only. No functional change is intended.
> 
> Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
> ---
> Cássio Gabriel (3):
>       ALSA: control: Use scoped cleanup for user control buffers
>       ALSA: core: Add scoped cleanup helper for card references
>       ALSA: seq: oss: Use scoped cleanup for temporary MIDI use lock

Applied all three patches to for-next branch.  Thanks.


Takashi

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-06-04  8:21 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-04  4:48 [PATCH 0/3] ALSA: scoped cleanup improvements for ALSA core Cássio Gabriel
2026-06-04  4:48 ` [PATCH 1/3] ALSA: control: Use scoped cleanup for user control buffers Cássio Gabriel
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

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®