Repository navigation
Conversation
|
|
|
|
|
any update here? |
4befacf to
07ae81e
Compare
|
Rebased onto main to get a fresh CI run. The only red before was the Windows MSVC GLib job, which died on an SSL error pulling CMake during vcpkg install (that job builds with Gandiva off, so unrelated to this change). New run is going now. |
|
|
|
Issue says a 24-byte key can round to a value "below data_len". Could you confirm if it does? I'd say rebase, get a fresh build and ping me for review. |
07ae81e to
b74f571
Compare
|
You're right, and the issue wording is off. With a 24-byte key Rebased onto main and force-pushed, so fresh CI is running. Ready for your review. |
Could you update the issue's text to reflect that, please? |
|
Updated the issue. It now says the 24-byte key rounding never goes below data_len and that the shortfall is against the ciphertext length (data_len 8 rounds to 8, ciphertext is 16). |
|
|
||
| *out_len = | ||
| static_cast<int32_t>(arrow::bit_util::RoundUpToPowerOf2(data_len, kAesBlockSize)); | ||
| *out_len = static_cast<int32_t>( |
There was a problem hiding this comment.
The unchecked narrowing (here and below) predates this PR, but adding the padding block makes another 16 input lengths overflow. Could we guard the new allocation calculation before narrowing, in both stubs?
There was a problem hiding this comment.
I'd be ok with a pushback and tracking this as a separate issue.
There was a problem hiding this comment.
Makes sense to fix it here since the padding block is what adds those lengths. Both stubs now compute the size as int64 and set an error before the narrowing if it's above INT32_MAX. Added TestAesOutputSizeOverflow, which covers INT32_MAX - 15 and INT32_MAX for encrypt and decrypt.
Rationale for this change
gdv_fn_aes_encryptsizes its output buffer withRoundUpToPowerOf2(data_len, key_data_len), which treats the key length as the AES block size. AES works on 16 byte blocks for every supported key length, so the rounding factor is wrong, and a 24 byte key asksRoundUpToPowerOf2to round to a factor that is not a power of two, which its contract requires.On top of that, PKCS#7 padding always appends a whole block, so a block aligned input produces a ciphertext one block longer than the input and the buffer comes up short. Allocated size against the ciphertext OpenSSL actually writes:
aes_encrypt(col, key)over any 16/32/48/... byte value letsEVP_EncryptFinal_exwrite 16 bytes past the arena buffer, and a 24 byte key with an 8 byte value writes 8 past. The overrun lands on whatever the arena hands out next, so the neighbouring row's output is corrupted; once the value exceeds the arena chunk size the chunk is allocated exactly and the write runs off the end of it.gdv_fn_aes_decryptsizes its buffer with the same expression. Its plaintext is never longer than the ciphertext so it does not overrun today, but the size it computes can equaldata_lenwhile OpenSSL documentsinl + block_sizeas the output spaceEVP_DecryptUpdatemay use, and the trailingret[*out_len] = '\0'needs the room as well.What changes are included in this PR?
Both stubs now size the output from the fixed 16 byte AES block plus one block for padding, which covers the exact PKCS#7 ciphertext length and the output space OpenSSL asks for. The key length keeps its 16/24/32 validation and only picks the cipher.
Are these changes tested?
Yes.
TestGdvFnStubs.TestAesEncryptBlockAlignedInputencrypts two block aligned values from one context and decrypts the first. The undersized buffer makes the second ciphertext land on top of the first, so the decrypt fails on the current code and round-trips after the fix. It needs no sanitizer, which the existing Gandiva CI jobs do not enable. Fullgandiva-internals-test,gandiva-precompiled-testandgandiva-projector-testpass.Are there any user-facing changes?
No.
This PR contains a "Critical Fix". It fixes a heap buffer overflow in
aes_encryptthat corrupts neighbouring output (or writes off the end of the arena chunk) for any input whose length is a multiple of the AES block size.Was AI used for this PR?
In accordance to the AI generation guidelines, please disclose below whether and how AI was used in this PR.
PR code and description written by:
AI tooling was used to find the bug and to write the fix, the regression test and this description. The regression test was run against the unpatched code, where it fails, and against the patched code before submission.
Reviewed before submission by: