CVE-2026-46023
Description
In the Linux kernel, the following vulnerability has been resolved:
dm mirror: fix integer overflow in create_dirty_log()
The argument count calculation in create_dirty_log() performs *args_used = 2 + param_count before validating against argc. When a user provides a param_count close to UINT_MAX via the device mapper table string, this unsigned addition wraps around to a small value, causing the subsequent argc < *args_used check to be bypassed.
The overflowed param_count is then passed as argc to dm_dirty_log_create(), where it can cause out-of-bounds reads on the argv array.
Fix by comparing param_count against argc - 2 before performing the addition, following the same pattern used by parse_features() in the same file. Since argc >= 2 is already guaranteed, the subtraction is safe.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Integer overflow in Linux kernel dm mirror's create_dirty_log() allows local privilege escalation via crafted device mapper table input.
Vulnerability
An integer overflow vulnerability exists in the create_dirty_log() function within the Linux kernel's device mapper mirror target. The function performs *args_used = 2 + param_count before validating against argc, allowing an unsigned wrap-around when param_count is close to UINT_MAX. This bypasses the subsequent argc < *args_used check. The issue affects kernel versions with the dm mirror module (dm-raid1) present. The fix commit reference is 47dad9eea75d33212d3d2cea10e7ed6a1bfc0713 in the stable kernel tree [1].
Exploitation
An attacker with the ability to create a device mapper table entry (typically requires root privileges or access to device-mapper ioctls such as DM_TABLE_LOAD) can supply a crafted table string where param_count is set to a value near UINT_MAX. The overflowed count is then passed as argc to dm_dirty_log_create(), which uses it to index into the argv array, potentially reading out-of-bounds memory. The condition is triggered during the creation of a mirrored device with a dirty log [1].
Impact
Successful exploitation results in an out-of-bounds read on kernel heap memory adjacent to the argv array. This may allow an attacker to leak sensitive kernel data (information disclosure) or cause a denial-of-service (kernel panic). In some configurations, the read could influence control flow, potentially leading to privilege escalation. The issue is classified as a high-severity vulnerability [1].
Mitigation
The fix has been applied to the Linux kernel stable tree in commit 47dad9eea75d33212d3d2cea10e7ed6a1bfc0713. Users should update to a kernel version containing this patch. The fix reorders the validation to compare param_count against argc - 2 before performing the addition, preventing the overflow. No workaround is available for unpatched kernels; loading dm mirror table entries should be restricted to trusted users [1].
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
104c788c6f921bdm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 80a5c412770799..de5c00704e69c6 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
35f6b3281efddm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 94b6c43dfa5cbd..93e3470a701c58 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
47dad9eea75ddm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 94b6c43dfa5cbd..93e3470a701c58 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
87c99a50e0fddm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 268f734ca9c38a..bc8e04f6832a6b 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
17a08791d428dm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 80a5c412770799..de5c00704e69c6 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
87c99a50e0fddm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 268f734ca9c38a..bc8e04f6832a6b 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
17a08791d428dm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 80a5c412770799..de5c00704e69c6 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
35f6b3281efddm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 94b6c43dfa5cbd..93e3470a701c58 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
47dad9eea75ddm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 94b6c43dfa5cbd..93e3470a701c58 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
4c788c6f921bdm mirror: fix integer overflow in create_dirty_log()
1 file changed · +3 −4
drivers/md/dm-raid1.c+3 −4 modifieddiff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 80a5c412770799..de5c00704e69c6 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -993,13 +993,13 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - *args_used = 2 + param_count; - - if (argc < *args_used) { + if (param_count > argc - 2) { ti->error = "Insufficient mirror log arguments"; return NULL; } + *args_used = 2 + param_count; + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, argv + 2); if (!dl) { -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Integer overflow in argument count calculation in create_dirty_log() allows bounds check bypass."
Attack vector
An attacker with the ability to craft a device-mapper table string (typically requiring root or CAP_SYS_ADMIN) supplies a `param_count` value close to UINT_MAX. The original code computes `*args_used = 2 + param_count` before checking `argc < *args_used`; the unsigned addition wraps around to a small value, bypassing the bounds check. The overflowed `param_count` is then passed as `argc` to `dm_dirty_log_create()`, where it causes out-of-bounds reads on the `argv` array [patch_id=2660361].
Affected code
The vulnerable function is `create_dirty_log()` in `drivers/md/dm-raid1.c` [patch_id=2660361]. The bug is in the argument count validation logic at lines 993-1000 of the original code.
What the fix does
The patch moves the bounds check before the addition and changes the comparison to `param_count > argc - 2` [patch_id=2660361]. This prevents integer overflow because the subtraction `argc - 2` is safe (argc >= 2 is guaranteed) and the comparison is performed before any addition. The assignment `*args_used = 2 + param_count` now occurs only after the validation passes, following the same pattern used by `parse_features()` in the same file.
Preconditions
- authAttacker must be able to supply a crafted device-mapper table string (typically requires root or CAP_SYS_ADMIN privileges)
- inputThe param_count value in the table string must be close to UINT_MAX to trigger the integer overflow
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/17a08791d428885d00e510864283a7b839792368nvd
- git.kernel.org/stable/c/35f6b3281efd44d19110574663bc17a610bc73b9nvd
- git.kernel.org/stable/c/47dad9eea75d33212d3d2cea10e7ed6a1bfc0713nvd
- git.kernel.org/stable/c/4c788c6f921b22f9b6c3f316c4a071c05683e7denvd
- git.kernel.org/stable/c/87c99a50e0fdc68a5b9b52a94d49452cd3ff02canvd
News mentions
0No linked articles in our index yet.