All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ALSA: seq: Restore the delivery error code in the bounce event
@ 2026-08-12 11:32 HyeongJun An
  2026-08-12 13:01 ` Takashi Iwai
  0 siblings, 1 reply; 4+ messages in thread
From: HyeongJun An @ 2026-08-12 11:32 UTC (permalink / raw)
  To: Takashi Iwai, Jaroslav Kysela; +Cc: linux-sound, linux-kernel, HyeongJun An

Commit efc86691e4d8 ("ALSA: seq: Fix kernel heap address leak in
bounce_error_event()") moved the data.quote.value assignment into the
kernel client branch.  A user client that sets SNDRV_SEQ_FILTER_BOUNCE
used to get the delivery error code there.  Now it gets none, and
nothing else reports it, because a queued event's write() has already
returned success by the time delivery fails.

Send struct snd_seq_event_bounce instead, the error code followed by the
original event record, which is what the UAPI header has described all
along.  Store the negative errno.  The kernel client branch negates it
only because data.quote.value is an unsigned short.

The payload grows from 28 to 32 bytes.  The snd_seq_read() rounds a
variable-length payload up to a multiple of the event size, so a legacy
client now needs an 84 byte buffer instead of 56.  That is what any
event carrying 29 payload bytes has always needed.  A UMP client reads
64 bytes either way.

Drop the stale promise to copy the external data after the event record
as well.  That was never implemented, and bounce_error_event() runs with
atomic set from the timer interrupt.

Fixes: efc86691e4d8 ("ALSA: seq: Fix kernel heap address leak in bounce_error_event()")
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
Notes for the reviewer, not part of the change.

A UMP event does not fit the payload.  A struct snd_seq_ump_event is 32
bytes while quoted.event is 28, so ump[3] is dropped while
SNDRV_SEQ_EVENT_UMP stays set in the copy.  That is already true today,
but this locks it into the UAPI.  Clear the flag, skip bouncing UMP
events, or a different layout?  I did not want to guess.

The err field carries the negative errno.  Nothing has ever produced or
consumed this struct, so the sign is being chosen here for the first
time.  Say if you want the positive value instead.

I could not check whether any user space sets SNDRV_SEQ_FILTER_BOUNCE,
or what buffer size it reads with.

 sound/core/seq/seq_clientmgr.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 11fa7e825819..c334f88de542 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -530,9 +530,10 @@ static struct snd_seq_client *get_event_dest_client(struct snd_seq_event *event)
  * Return the error event.
  *
  * If the receiver client is a user client, the original event is
- * encapsulated in SNDRV_SEQ_EVENT_BOUNCE as variable length event.  If
- * the original event is also variable length, the external data is
- * copied after the event record. 
+ * encapsulated in SNDRV_SEQ_EVENT_BOUNCE as variable length event.  The
+ * payload is struct snd_seq_event_bounce, the error code followed by the
+ * original event record.  The external data of a variable length event
+ * is not copied along.
  * If the receiver client is a kernel client, the original event is
  * quoted in SNDRV_SEQ_EVENT_KERNEL_ERROR, since this requires no extra
  * kmalloc.
@@ -541,7 +542,8 @@ static int bounce_error_event(struct snd_seq_client *client,
 			      struct snd_seq_event *event,
 			      int err, int atomic, int hop)
 {
-	struct snd_seq_event bounce_ev, quoted;
+	struct snd_seq_event_bounce quoted;
+	struct snd_seq_event bounce_ev;
 	int result;
 
 	if (client == NULL ||
@@ -565,14 +567,16 @@ static int bounce_error_event(struct snd_seq_client *client,
 		 * variable-length event carries the address of its own
 		 * extension cell, and the payload goes out verbatim.
 		 */
-		quoted = *event;
-		if (snd_seq_ev_is_variable(&quoted)) {
-			quoted.data.ext.len &= ~SNDRV_SEQ_EXT_MASK;
-			quoted.data.ext.ptr = NULL;
+		memset(&quoted, 0, sizeof(quoted));
+		quoted.err = err;
+		quoted.event = *event;
+		if (snd_seq_ev_is_variable(&quoted.event)) {
+			quoted.event.data.ext.len &= ~SNDRV_SEQ_EXT_MASK;
+			quoted.event.data.ext.ptr = NULL;
 		}
 		bounce_ev.type = SNDRV_SEQ_EVENT_BOUNCE;
 		bounce_ev.flags = SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
-		bounce_ev.data.ext.len = sizeof(struct snd_seq_event);
+		bounce_ev.data.ext.len = sizeof(quoted);
 		bounce_ev.data.ext.ptr = (char *)&quoted;
 	} else {
 		/*
-- 
2.43.0


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

end of thread, other threads:[~2026-08-12 14:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-12 11:32 [PATCH] ALSA: seq: Restore the delivery error code in the bounce event HyeongJun An
2026-08-12 13:01 ` Takashi Iwai
2026-08-12 14:15   ` [PATCH] ALSA: seq: Drop the dead struct snd_seq_event_bounce HyeongJun An
2026-08-12 14:39     ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.