dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Kaitao Cheng" <kaitao.cheng@linux.dev>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v2 14/14] list: Cache cursors in entry iterators
Date: Tue, 09 Jun 2026 06:59:51 +0000	[thread overview]
Message-ID: <20260609065951.DC20B1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260609064122.95825-2-kaitao.cheng@linux.dev>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] Modifying the standard list iterators to pre-cache the `next` pointer fundamentally changes their traversal semantics from dynamic to static evaluation, causing use-after-free (UAF) vulnerabilities and silently breaking loops that modify the list ahead of the cursor or skip elements by advancing `pos`.
- [High] Eliminating the distinction between safe and non-safe list iterators obscures code intent, removes a vital visual guardrail for destructive operations, and introduces severe backporting risks.
--

commit e1c09f66ccd28cca66865681febeb6f8233f0a36
Author: Kaitao Cheng <chengkaitao@kylinos.cn>

list: Cache cursors in entry iterators

This commit introduces private next and previous cursor variables into the
standard list iteration macros. It changes the semantics of the
list_for_each_entry() family to cache the next pointer before executing the
loop body. It also updates comments to recommend the non-safe variants over
the safe ones when a temporary cursor is not needed.

> diff --git a/include/linux/list.h b/include/linux/list.h
> index 09d979976b3b8..9df84a56a789b 100644
> --- a/include/linux/list.h
> +++ b/include/linux/list.h
> @@ -809,6 +809,29 @@ static inline size_t list_count_nodes(struct list_head *head)
>  #define list_entry_is_head(pos, head, member)				\
>  	list_is_head(&pos->member, (head))
>  
> +#define __list_for_each_entry(pos, next, head, member)			\
> +	for (typeof(pos) next = list_next_entry(pos =			\
> +		list_first_entry(head, typeof(*pos), member), member);	\
> +	     !list_entry_is_head(pos, head, member);			\
> +	     pos = next, next = list_next_entry(next, member))

[ ... ]

> @@ -816,9 +839,7 @@ static inline size_t list_count_nodes(struct list_head *head)
>   * @member:	the name of the list_head within the struct.
>   */
>  #define list_for_each_entry(pos, head, member)				\
> -	for (pos = list_first_entry(head, typeof(*pos), member);	\
> -	     !list_entry_is_head(pos, head, member);			\
> -	     pos = list_next_entry(pos, member))
> +	__list_for_each_entry(pos, __UNIQUE_ID(next), head, member)

[Severity: Critical]
Does caching the next pointer fundamentally change the dynamic traversal
semantics of the standard list iterators kernel-wide?

A common kernel pattern is pinning the current entry (pos), dropping the
lock to perform a blocking operation, and reacquiring the lock. With
dynamic evaluation, pos->next is safely fetched under the lock.

With the new cached next pointer, if the next element was removed and freed
by a concurrent thread while the lock was dropped, next becomes a dangling
pointer, which could lead to a use-after-free when the loop steps.

Will this also silently skip dynamically inserted elements? If a loop body
inserts a new element immediately after pos, the old macro would naturally
visit it next. The new macro appears to silently skip it because it advances
using the pre-cached next.

Could this also overwrite manual cursor updates? If the loop body explicitly
alters pos to skip elements, the loop increment (pos = next) might overwrite
the updated cursor with the pre-cached next, negating the skip and potentially
causing incorrect traversal behavior.

[ ... ]

> @@ -901,6 +917,8 @@ static inline size_t list_count_nodes(struct list_head *head)
>   * @n:		another type * to use as temporary storage
>   * @head:	the head for your list.
>   * @member:	the name of the list_head within the struct.
> + *
> + * Prefer list_for_each_entry() unless the temporary cursor is needed.
>   */
>  #define list_for_each_entry_safe(pos, n, head, member)			\

[Severity: High]
Does advising developers to prefer list_for_each_entry() over the _safe
variant for removals obscure the intent of the code?

The _safe variant explicitly signals to reviewers and static analysis tools
that the loop body may mutate the list. Conflating variable-scoping
convenience with traversal safety constraints removes a visual guardrail for
destructive operations.

Additionally, does this introduce a backporting hazard? If developers write
new code that unlinks elements using list_for_each_entry(), backporting those
patches to older stable kernels (which lack this caching patch) will compile
cleanly but might reliably introduce use-after-free vulnerabilities, as older
kernels evaluate pos->next after pos has been unlinked.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260609064122.95825-1-kaitao.cheng@linux.dev?part=14

  reply	other threads:[~2026-06-09  6:59 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-09  6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
2026-06-09  6:13 ` [PATCH v2 01/14] drbd: Open-code transfer log list walk Kaitao Cheng
2026-06-09  6:53   ` sashiko-bot
2026-06-09  6:13 ` [PATCH v2 02/14] firewire: core: Open-code topology " Kaitao Cheng
2026-06-09  6:53   ` sashiko-bot
2026-06-09  6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
2026-06-09  6:25   ` [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk Kaitao Cheng
2026-06-09  7:00     ` Andy Shevchenko
2026-06-09  6:25   ` [PATCH v2 05/14] drm/i915: Open-code DFS dependency list walk Kaitao Cheng
2026-06-09  6:25   ` [PATCH v2 06/14] drm/ttm: Open-code reservation " Kaitao Cheng
2026-06-09  6:51     ` sashiko-bot
2026-06-09  6:25   ` [PATCH v2 07/14] spi: fsi: Open-code message transfer walk Kaitao Cheng
2026-06-09  7:02     ` Andy Shevchenko
2026-06-09  6:25   ` [PATCH v2 08/14] spi: stm32-ospi: " Kaitao Cheng
2026-06-09  6:57     ` sashiko-bot
2026-06-09  6:25   ` [PATCH v2 09/14] spi: stm32-qspi: " Kaitao Cheng
2026-06-09  6:55     ` sashiko-bot
2026-06-09  6:38 ` [PATCH v2 10/14] spi: tegra210-quad: " Kaitao Cheng
2026-06-09  6:38   ` [PATCH v2 11/14] locking/locktorture: Open-code ww mutex list walk Kaitao Cheng
2026-06-09  6:54     ` sashiko-bot
2026-06-09  6:38   ` [PATCH v2 12/14] locking/ww_mutex: Open-code stress reorder " Kaitao Cheng
2026-06-09  6:57   ` [PATCH v2 10/14] spi: tegra210-quad: Open-code message transfer walk sashiko-bot
2026-06-09  6:41 ` [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk Kaitao Cheng
2026-06-09  6:41   ` [PATCH v2 14/14] list: Cache cursors in entry iterators Kaitao Cheng
2026-06-09  6:59     ` sashiko-bot [this message]
2026-06-09  6:55   ` [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk sashiko-bot
2026-06-09  6:47 ` [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Andy Shevchenko
2026-06-09  7:05   ` Andy Shevchenko
2026-06-09 10:33 ` Christian König
2026-06-10  6:14   ` Kaitao Cheng
2026-06-10  8:07     ` Christian König
2026-06-10  8:18       ` Kaitao Cheng
2026-06-10  9:11         ` Christian König
2026-06-10 15:02           ` Andy Shevchenko
2026-06-11  8:01             ` Christian König
2026-06-11  8:29               ` Andy Shevchenko
2026-06-11  8:39                 ` Christian König
2026-06-11 18:31                   ` Andy Shevchenko
2026-06-11 12:27                 ` Kaitao Cheng
2026-06-10 14:43     ` Andy Shevchenko
2026-06-11  4:42       ` Kaitao Cheng
2026-06-11  6:54         ` Andy Shevchenko
2026-06-11  7:36           ` Kaitao Cheng
2026-06-11  7:52             ` Andy Shevchenko
2026-06-11 12:04               ` Kaitao Cheng

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=20260609065951.DC20B1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kaitao.cheng@linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    /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