[PATCH 0/2] ALSA: avoid past-the-end iterators in timer/seq port registration

Maoyi Xie posted 2 patches 6 days, 8 hours ago
sound/core/seq/seq_ports.c |  7 +++++--
sound/core/timer.c         | 19 ++++++++++++++-----
2 files changed, 19 insertions(+), 7 deletions(-)
[PATCH 0/2] ALSA: avoid past-the-end iterators in timer/seq port registration
Posted by Maoyi Xie 6 days, 8 hours ago
Two fixes in sound/core that remove past-the-end iterator
use of the shape

    list_for_each_entry(iter, head, member) {
        if (...) break;
    }
    list_add_tail(&new, &iter->member);

When the loop walks all entries without break, iter is past
the end and &iter->member aliases the list head via
container_of offset cancellation. The insert lands at the
list tail, which is the intended behaviour, but the access
is undefined per C11.

Takashi Iwai confirmed on the inquiry thread that both sites
are bugs introduced by commit 9244b2c3079f ("[ALSA] alsa core:
convert to list_for_each_entry*"). The original list_for_each()
loop terminated at the list head; the conversion to
list_for_each_entry() left the post-loop access using the
container struct, which aliases the head via offset
cancellation.

The patched code tracks an explicit insert_before pointer
initialised to the list head and overwritten to &iter->member
only when the loop breaks early. Observable behaviour is
unchanged.

Inquiry thread:
https://lore.kernel.org/linux-sound/?q=iterator+used+after+loop+end+in+timer

Maoyi Xie (2):
  ALSA: timer: avoid past-the-end iterator in snd_timer_dev_register()
  ALSA: seq: avoid past-the-end iterator in snd_seq_create_port()

 sound/core/seq/seq_ports.c |  7 +++++--
 sound/core/timer.c         | 19 ++++++++++++++-----
 2 files changed, 19 insertions(+), 7 deletions(-)
Re: [PATCH 0/2] ALSA: avoid past-the-end iterators in timer/seq port registration
Posted by Takashi Iwai 5 days, 22 hours ago
On Mon, 18 May 2026 21:40:21 +0200,
Maoyi Xie wrote:
> 
> Two fixes in sound/core that remove past-the-end iterator
> use of the shape
> 
>     list_for_each_entry(iter, head, member) {
>         if (...) break;
>     }
>     list_add_tail(&new, &iter->member);
> 
> When the loop walks all entries without break, iter is past
> the end and &iter->member aliases the list head via
> container_of offset cancellation. The insert lands at the
> list tail, which is the intended behaviour, but the access
> is undefined per C11.
> 
> Takashi Iwai confirmed on the inquiry thread that both sites
> are bugs introduced by commit 9244b2c3079f ("[ALSA] alsa core:
> convert to list_for_each_entry*"). The original list_for_each()
> loop terminated at the list head; the conversion to
> list_for_each_entry() left the post-loop access using the
> container struct, which aliases the head via offset
> cancellation.
> 
> The patched code tracks an explicit insert_before pointer
> initialised to the list head and overwritten to &iter->member
> only when the loop breaks early. Observable behaviour is
> unchanged.
> 
> Inquiry thread:
> https://lore.kernel.org/linux-sound/?q=iterator+used+after+loop+end+in+timer
> 
> Maoyi Xie (2):
>   ALSA: timer: avoid past-the-end iterator in snd_timer_dev_register()
>   ALSA: seq: avoid past-the-end iterator in snd_seq_create_port()

Applied both patches now.  Thanks.


Takashi