From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Ziyi Guo <n7l8m4@u.northwestern.edu>,
Sakari Ailus <sakari.ailus@linux.intel.com>,
Mauro Carvalho Chehab <mchehab+huawei@kernel.org>,
Sasha Levin <sashal@kernel.org>,
mchehab@kernel.org, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 7.0-6.12] media: i2c: imx258: add missing mutex protection for format code access
Date: Mon, 20 Apr 2026 09:18:40 -0400 [thread overview]
Message-ID: <20260420132314.1023554-126-sashal@kernel.org> (raw)
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Ziyi Guo <n7l8m4@u.northwestern.edu>
[ Upstream commit c3109ecc3bb76aab9ef65f2e795a97a764a0b4a3 ]
imx258_open(), imx258_enum_mbus_code(), and imx258_enum_frame_size()
call imx258_get_format_code() without holding imx258->mutex. However,
imx258_get_format_code() has lockdep_assert_held(&imx258->mutex)
indicating that callers must hold this lock.
All other callers of imx258_get_format_code() properly acquire the mutex:
- imx258_set_pad_format() acquires mutex at imx258.c:918
- imx258_get_pad_format() acquires mutex at imx258.c:896
The mutex is needed to protect access to imx258->vflip->val and
imx258->hflip->val which are used to calculate the bayer format code.
Add mutex_lock()/mutex_unlock() around the imx258_get_format_code()
calls in the affected functions to fix the missing lock protection.
Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have enough information for a thorough analysis. Let me compile
the findings.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: PARSE THE SUBJECT LINE
- **Subsystem**: `media: i2c: imx258` (V4L2 camera sensor driver)
- **Action verb**: "add missing" — indicates a bug fix (adding
protection that should have been there)
- **Summary**: Add missing mutex_lock/unlock around calls to
`imx258_get_format_code()` in three functions
### Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
- **Signed-off-by**: Ziyi Guo <n7l8m4@u.northwestern.edu> (author)
- **Signed-off-by**: Sakari Ailus <sakari.ailus@linux.intel.com> (media
subsystem co-maintainer)
- **Signed-off-by**: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
(media subsystem maintainer)
- No Fixes: tag (expected for candidates under review)
- No Reported-by: tag
- No Cc: stable tag
Record: The patch went through the proper media subsystem chain
(maintainer SOBs from Sakari Ailus and Mauro Carvalho Chehab). Author
appears to be a university student contributor.
### Step 1.3: ANALYZE THE COMMIT BODY TEXT
- **Bug described**: Three functions (`imx258_open()`,
`imx258_enum_mbus_code()`, `imx258_enum_frame_size()`) call
`imx258_get_format_code()` without holding `imx258->mutex`, violating
a lockdep assertion.
- **Symptom**: With `CONFIG_PROVE_LOCKING`, lockdep will trigger a
warning/assertion. Without lockdep, there's a data race on
`imx258->vflip->val` and `imx258->hflip->val`.
- **Root cause**: When `4c05213aeed73` added writable HFLIP/VFLIP
controls and `imx258_get_format_code()` with `lockdep_assert_held()`,
it failed to add mutex protection in all callers.
### Step 1.4: DETECT HIDDEN BUG FIXES
Record: This IS a genuine bug fix — missing synchronization that creates
a data race on shared state (flip values). The `lockdep_assert_held()`
assertion explicitly documents the requirement.
## PHASE 2: DIFF ANALYSIS
### Step 2.1: INVENTORY THE CHANGES
- **File modified**: `drivers/media/i2c/imx258.c` (+12/-2 net)
- **Functions modified**: `imx258_open()`, `imx258_enum_mbus_code()`,
`imx258_enum_frame_size()`
- **Scope**: Single-file, surgical fix
### Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
- **`imx258_open()`**: Added `mutex_lock/unlock` around the block that
calls `imx258_get_format_code()`. Lock is released before the
`try_crop` initialization (which doesn't need the lock).
- **`imx258_enum_mbus_code()`**: Added `mutex_lock/unlock` around the
single `imx258_get_format_code()` call.
- **`imx258_enum_frame_size()`**: Added a local `u32 code` variable,
acquires mutex, calls `imx258_get_format_code()` into the local,
releases mutex, then uses `code` for the comparison.
### Step 2.3: IDENTIFY THE BUG MECHANISM
- **Category**: Race condition / missing synchronization
- **Mechanism**: `imx258_get_format_code()` reads `imx258->vflip->val`
and `imx258->hflip->val` to compute the bayer format code. These
values can be changed concurrently by `imx258_set_ctrl()` (which holds
the ctrl handler lock but not necessarily `imx258->mutex` at the same
granularity). Without the mutex, there's a race between reading flip
values and writing them through V4L2 control operations.
- The function already has `lockdep_assert_held(&imx258->mutex)`
documenting this requirement.
### Step 2.4: ASSESS THE FIX QUALITY
- The fix is obviously correct: it adds the required mutex around the
calls, matching the pattern used by all other callers
(`imx258_get_pad_format()` at line 896, `imx258_set_pad_format()` at
line 918).
- Minimal and surgical — only adds lock/unlock pairs.
- Low regression risk — the mutex is already used throughout the driver;
adding it to more V4L2 callbacks is consistent.
- The lock scope in `imx258_open()` is appropriately narrow (released
before `try_crop` initialization).
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: BLAME THE CHANGED LINES
Record: All calls to `imx258_get_format_code()` in the affected
functions were introduced by commit `4c05213aeed73` ("media: i2c:
imx258: Make HFLIP and VFLIP controls writable") by Dave Stevenson,
which was merged for v6.11-rc1.
### Step 3.2: FOLLOW THE FIXES TARGET
No Fixes: tag present, but the bug was introduced by `4c05213aeed73`
(v6.11-rc1). This commit exists in stable trees v6.11, v6.12, v6.13, but
NOT in v6.6, v6.7–v6.10.
### Step 3.3: FILE HISTORY
Recent changes to `imx258.c` since v6.11: minor header changes
(`asm/unaligned.h` → `linux/unaligned.h`), CCI conversion, clock helper
changes. None conflict with this fix.
### Step 3.4: AUTHOR CONTEXT
- Ziyi Guo (author): Appears to be a first-time contributor (no other
commits found in this subsystem)
- Signed off by Sakari Ailus (media subsystem maintainer at Intel) —
strong endorsement
- Signed off by Mauro Carvalho Chehab (top-level media maintainer) —
accepted through the standard media tree
### Step 3.5: DEPENDENCIES
No dependencies. The fix only adds `mutex_lock()/mutex_unlock()` calls
around existing code. The mutex and `imx258_get_format_code()` already
exist in all trees that have `4c05213aeed73`.
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1-4.5
I was unable to find the specific patch submission on lore.kernel.org
(searches blocked by anti-scraping protection). The commit has proper
maintainer signoffs from both Sakari Ailus and Mauro Carvalho Chehab,
indicating it went through standard review.
Record: The mailing list discussion could not be retrieved. However, the
dual-maintainer signoff chain confirms proper review.
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: KEY FUNCTIONS
Modified: `imx258_open()`, `imx258_enum_mbus_code()`,
`imx258_enum_frame_size()`
### Step 5.2: TRACE CALLERS
These are V4L2 subdev ops callbacks:
- `imx258_open()` → `.open` in `v4l2_subdev_internal_ops` — called when
userspace opens the subdev node
- `imx258_enum_mbus_code()` → `.enum_mbus_code` in `v4l2_subdev_pad_ops`
— called via `VIDIOC_SUBDEV_ENUM_MBUS_CODE` ioctl
- `imx258_enum_frame_size()` → `.enum_frame_size` in
`v4l2_subdev_pad_ops` — called via `VIDIOC_SUBDEV_ENUM_FRAME_SIZE`
ioctl
All are reachable from userspace through standard V4L2 ioctls.
### Step 5.3-5.4: CALL CHAIN
Userspace → V4L2 ioctl → subdev pad ops →
`imx258_enum_mbus_code()/imx258_enum_frame_size()` →
`imx258_get_format_code()` (reads `vflip->val`, `hflip->val`). The race
window exists if another thread simultaneously calls `VIDIOC_S_CTRL` to
change HFLIP/VFLIP.
### Step 5.5: SIMILAR PATTERNS
Verified that other callers (`imx258_get_pad_format` at line 896,
`imx258_set_pad_format` at line 918) already properly hold the mutex.
The fix makes all callers consistent.
## PHASE 6: CROSS-REFERENCING AND STABLE TREE ANALYSIS
### Step 6.1: BUGGY CODE IN STABLE TREES
The buggy commit `4c05213aeed73` exists in v6.11+. It does NOT exist in
v6.6 or earlier LTS trees. Applicable stable trees: 6.11.y, 6.12.y,
6.13.y (and 7.0 which is the target here).
### Step 6.2: BACKPORT COMPLICATIONS
The patch should apply cleanly to any tree that has `4c05213aeed73`. The
only unrelated change between v6.11 and HEAD is the `asm/unaligned.h`
rename, which doesn't touch the affected functions.
### Step 6.3: RELATED FIXES
No other fix for this specific issue was found in any stable tree.
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: SUBSYSTEM CRITICALITY
- **Subsystem**: drivers/media/i2c — camera sensor driver
- **Criticality**: PERIPHERAL — affects users of the IMX258 camera
sensor specifically (common on Raspberry Pi, some laptops)
### Step 7.2: SUBSYSTEM ACTIVITY
Moderately active — the file has seen ~20 commits in recent history,
mostly feature additions.
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: WHO IS AFFECTED
Users of the IMX258 camera sensor who have writable HFLIP/VFLIP controls
(v6.11+).
### Step 8.2: TRIGGER CONDITIONS
- Concurrent V4L2 operations: one thread enumerating formats while
another changes HFLIP/VFLIP controls.
- Also triggers as a lockdep warning with `CONFIG_PROVE_LOCKING` even
without concurrency.
- Userspace-reachable through standard V4L2 ioctls.
### Step 8.3: FAILURE MODE SEVERITY
- With lockdep enabled: WARNING splat in kernel log (MEDIUM)
- Without lockdep: data race on `vflip->val`/`hflip->val` — could return
wrong bayer format code, leading to incorrect image format negotiation
(MEDIUM)
- Not a crash or security vulnerability, but a correctness and data race
issue.
Record: Severity: MEDIUM
### Step 8.4: RISK-BENEFIT RATIO
- **Benefit**: Fixes a real data race and lockdep warning. Ensures
correct format code under concurrent access. LOW-MEDIUM benefit (fixes
correctness, not a crash).
- **Risk**: VERY LOW — only adds mutex_lock/unlock pairs around existing
code, matching the pattern already used by other callers in the same
driver.
- **Ratio**: Favorable — minimal risk, clear correctness improvement.
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: EVIDENCE COMPILATION
**FOR backporting:**
- Fixes a real race condition (missing synchronization documented by
lockdep_assert_held)
- Small, surgical fix (12 lines added)
- Obviously correct — matches the pattern of all other callers
- Accepted through proper maintainer review chain
- No dependencies — standalone fix
- Applies to v6.11+ stable trees
**AGAINST backporting:**
- Not a crash or security vulnerability — the race leads to incorrect
bayer format code, not a panic
- Limited user base (IMX258 camera sensor users only)
- The race requires specific concurrent access patterns
- No Reported-by tag — no evidence users have hit this in practice
- Lockdep warning is the main practical symptom
### Step 9.2: STABLE RULES CHECKLIST
1. Obviously correct and tested? **Yes** — follows existing pattern,
maintainer-signed
2. Fixes a real bug? **Yes** — data race, lockdep assertion violation
3. Important issue? **Medium** — data race, but not
crash/security/corruption
4. Small and contained? **Yes** — 12 lines in one file
5. No new features? **Correct** — purely adds lock protection
6. Can apply to stable? **Yes** — clean apply expected for v6.11+
### Step 9.3: EXCEPTION CATEGORIES
Not an exception category — this is a standard bug fix.
### Step 9.4: DECISION
This is a small, correct fix for a genuine race condition with
`lockdep_assert_held` documentation proving the locking requirement. It
was accepted by the media subsystem maintainers. The fix is minimal risk
and follows the existing locking pattern. While the severity is medium
(not a crash), it fixes a real data race that could cause incorrect
format negotiation and triggers lockdep warnings with
`CONFIG_PROVE_LOCKING`.
## Verification
- [Phase 1] Parsed tags: SOBs from Ziyi Guo (author), Sakari Ailus
(media co-maintainer), Mauro Carvalho Chehab (media maintainer). No
Fixes/Reported-by/Cc:stable tags.
- [Phase 2] Diff analysis: +12/-2 lines across 3 functions in
`imx258.c`, adding `mutex_lock/unlock` around
`imx258_get_format_code()` calls.
- [Phase 2] Verified `lockdep_assert_held(&imx258->mutex)` exists at
line 696 in `imx258_get_format_code()`.
- [Phase 2] Verified other callers (`imx258_get_pad_format` at line 896,
`imx258_set_pad_format` at line 918) properly hold mutex.
- [Phase 3] git blame: All buggy call sites introduced by
`4c05213aeed73` ("Make HFLIP and VFLIP controls writable"), first in
v6.11-rc1.
- [Phase 3] `git merge-base --is-ancestor`: buggy commit present in
v6.11, v6.12, v6.13; NOT in v6.6–v6.10.
- [Phase 3] git log: No other mutex-related imx258 fixes found.
- [Phase 4] b4 dig for `4c05213aeed73`: found original submission as
patch v5 20/25 at lore.
- [Phase 4] UNVERIFIED: Could not retrieve full mailing list discussion
for the fix commit due to lore anti-scraping.
- [Phase 5] Verified callers are V4L2 subdev ops, reachable from
userspace ioctls.
- [Phase 5] Verified `imx258_get_format_code` reads `vflip->val` and
`hflip->val` (lines 698-699).
- [Phase 6] Code changes between v6.11 and HEAD in this file are minimal
(header rename, CCI conversion), no conflicts expected.
- [Phase 8] Failure mode: lockdep WARNING + data race leading to
incorrect bayer format code. Severity MEDIUM.
**YES**
drivers/media/i2c/imx258.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index e50dcfd830f52..bc9ee449a87c5 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -709,12 +709,16 @@ static int imx258_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
v4l2_subdev_state_get_format(fh->state, 0);
struct v4l2_rect *try_crop;
+ mutex_lock(&imx258->mutex);
+
/* Initialize try_fmt */
try_fmt->width = supported_modes[0].width;
try_fmt->height = supported_modes[0].height;
try_fmt->code = imx258_get_format_code(imx258);
try_fmt->field = V4L2_FIELD_NONE;
+ mutex_unlock(&imx258->mutex);
+
/* Initialize try_crop */
try_crop = v4l2_subdev_state_get_crop(fh->state, 0);
try_crop->left = IMX258_PIXEL_ARRAY_LEFT;
@@ -839,7 +843,9 @@ static int imx258_enum_mbus_code(struct v4l2_subdev *sd,
if (code->index > 0)
return -EINVAL;
+ mutex_lock(&imx258->mutex);
code->code = imx258_get_format_code(imx258);
+ mutex_unlock(&imx258->mutex);
return 0;
}
@@ -849,10 +855,16 @@ static int imx258_enum_frame_size(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_size_enum *fse)
{
struct imx258 *imx258 = to_imx258(sd);
+ u32 code;
+
if (fse->index >= ARRAY_SIZE(supported_modes))
return -EINVAL;
- if (fse->code != imx258_get_format_code(imx258))
+ mutex_lock(&imx258->mutex);
+ code = imx258_get_format_code(imx258);
+ mutex_unlock(&imx258->mutex);
+
+ if (fse->code != code)
return -EINVAL;
fse->min_width = supported_modes[fse->index].width;
--
2.53.0
next prev parent reply other threads:[~2026-04-20 13:26 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260420132314.1023554-1-sashal@kernel.org>
2026-04-20 13:16 ` [PATCH AUTOSEL 7.0-5.10] media: i2c: mt9p031: Check return value of devm_gpiod_get_optional() in mt9p031_probe() Sasha Levin
2026-04-20 13:16 ` [PATCH AUTOSEL 7.0-6.12] media: ipu-bridge: Add OV5675 sensor config Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-5.15] media: em28xx: Add a variety of DualHD usb id Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-6.1] media: em28xx: remove tuner type from Hauppauge DVB DualHD Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-5.10] media: pulse8-cec: Handle partial deinit Sasha Levin
2026-04-20 13:18 ` Sasha Levin [this message]
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-5.10] media: si2168: Fix i2c command timeout on embedded platforms Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.1] media: dw100: Fix kernel oops with PREEMPT_RT enabled Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-5.15] media: renesas: vsp1: histo: Fix code enumeration Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.18] media: synopsys: hdmirx: support use with sleeping GPIOs Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-5.15] media: ccs-pll: Fix pre-PLL divider calculation for EXT_IP_PLL_DIVIDER flag Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-5.10] media: saa7164: Fix REV2 firmware filename Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] media: rkvdec: reduce stack usage in rkvdec_init_v4l2_vp9_count_tbl() Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-5.10] media: si2168: fw 4.0-11 loses warm state during sleep Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-6.12] media: renesas: vsp1: Initialize format on all pads Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-6.12] media: renesas: vsp1: brx: Fix format propagation Sasha Levin
2026-04-20 16:12 ` Biju Das
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-5.10] media: cx25840: Fix NTSC-J, PAL-N, and SECAM standards Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-6.1] media: i2c: ar0521: Check return value of devm_gpiod_get_optional() in ar0521_probe() Sasha Levin
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=20260420132314.1023554-126-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab+huawei@kernel.org \
--cc=mchehab@kernel.org \
--cc=n7l8m4@u.northwestern.edu \
--cc=patches@lists.linux.dev \
--cc=sakari.ailus@linux.intel.com \
--cc=stable@vger.kernel.org \
/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