Skip to content

MDEV-41094 KDF() aliases large iteration/width to weak 32-bit values - #5731

Merged
sanja-byelkin merged 1 commit into
11.4from
11.4-MDEV-41094
Sep 22, 2026
Merged

sanja-byelkin merged 1 commit into
11.4from
11.4-MDEV-41094

Conversation

@sanja-byelkin

Copy link
Copy Markdown
Member

Item_func_kdf::val_str() read the PBKDF2 iteration count as a signed 64-bit longlong but only rejected values <= 0 before narrowing it to the 32-bit int expected by PKCS5_PBKDF2_HMAC(). Iteration counts that differ by 2^32 therefore aliased to the same 32-bit value and derived identical keys: e.g. 4294968296 silently did the work of 1000. Since the value is reproducible as (iter mod 2^32), any key derived this way was already only as strong as the aliased low iteration count, so no previously-derived ciphertext is orphaned by rejecting the alias now; it simply reports the weak request instead of silently honouring it.

Item_func_kdf::fix_length_and_dec() had the identical bug for the key width argument: key_length= (uint)args[4]->val_int() narrows before the range check, and because the result is cached as a constant, the runtime guard in val_str() (which uses a wider type and is otherwise safe) is never reached for a constant width argument. This let a width like 4294967552 silently alias to 256, and let negative widths alias to a plausible positive one, both without warning.

Both call sites now validate the argument's true 64-bit value before narrowing, reusing the existing invalid_argument_error() and NULL result already used for other invalid KDF() arguments.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@vuvova

vuvova commented Sep 21, 2026

Copy link
Copy Markdown
Member

Please, not so blatantly AI-generated, rewrite the commit comment to be readable.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Key-width validation still narrows the value before checking it on supported 32-bit builds.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Hardens KDF() validation against oversized iteration counts and key widths, with regression coverage.

Changes:

  • Validates arguments before narrowing.
  • Rejects oversized PBKDF2 iterations and key widths.
  • Adds regression tests and expected results.
File Description
sql/​item_strfunc.cc Adds KDF argument validation.
mysql-test/​main/​func_kdf.test Adds oversized-argument regression cases.
mysql-test/​main/​func_kdf.result Records expected NULL results and warnings.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread sql/item_strfunc.cc Outdated
Comment on lines 541 to 549
@@ -544,6 +548,18 @@ String *Item_func_kdf::val_str(String *buf)
}
klen/= 8;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wondered why this comment was apparently ignored (not replied to). The comment does appear to be redundant; right before the assignment we are actually ensuring that width will fit in 17 bits, which is less than the minimum size_t width of 32 bits that we support:

    if (width <= 0 || width > UINT_MAX16 + 1 || width % 8)

Side note: if we didn’t have to reject width == 0 or accept width == 0x10000, the condition could be rewritten as width & ~longlong{UINT_MAX16 - 8} or just width & ~0xFFF7LL.

KDF() narrowed its iteration-count and key-width arguments without
checking they fit, so values differing by 2^32 aliased to the same
small value and silently derived a much weaker key.

Added checks that the key width fits a 16-bit unsigned value and the
iteration count fits a 32-bit value before narrowing them, rejecting
out-of-range values with an error instead of aliasing.
@sanja-byelkin
sanja-byelkin enabled auto-merge (rebase) September 22, 2026 16:30
@sanja-byelkin
sanja-byelkin enabled auto-merge (rebase) September 22, 2026 17:03
@sanja-byelkin
sanja-byelkin merged commit 30ee95c into 11.4 Sep 22, 2026
16 of 18 checks passed
@grooverdan
grooverdan deleted the 11.4-MDEV-41094 branch September 22, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

7 participants