Bug #95606 | ib_sdi_get may return false positive DB_OUT_OF_MEMORY | ||
---|---|---|---|
Submitted: | 3 Jun 2019 6:49 | Modified: | 10 Jul 2019 18:51 |
Reporter: | Sergei Glushchenko | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S3 (Non-critical) |
Version: | 8.0.16 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[3 Jun 2019 6:49]
Sergei Glushchenko
[3 Jun 2019 13:25]
MySQL Verification Team
Hi Mr. Glushchenko, Thank you for your bug report. I have analysed the code, compress API details and your patch. I am afraid that this is not so simple, so the patch should be a bit different. It is theoretically possible that compressed size is larger than uncompressed size. Hence, wouldn't it be better to set variable `buf_len` to the larger of two values and then do away with that conditional altogether. What is your opinion.
[3 Jun 2019 17:26]
Sergei Glushchenko
Note that ib_sdi_get returns both compressed and uncompressed length. But buffer is passed to store compressed SDI. I would expect caller to pass buffer large enough for compressed SDI, then allocate another buffer large enough for uncompressed SDI and decompress SDI into it. Note also that ib_sdi_get does not uncompress SDI, it is caller's responsibility to perform decompression.
[4 Jun 2019 12:32]
MySQL Verification Team
Hi, Thank you for your answer. My question is whether you still stand behind your patch. Do you think that no other changes would be necessary. You have, seemingly, missed a code six lines above which does the following: uint32_t buf_len = *comp_sdi_len; hence, your patch would look like this, in effect: if (*comp_sdi_len < *comp_sdi_len) Are you sure that this is what you want ???/
[4 Jun 2019 13:24]
Sergei Glushchenko
I didn't miss that code. It is you who missed following code two lines above: ib_tuple_read_u32(tuple, 2, uncomp_sdi_len); ib_tuple_read_u32(tuple, 3, comp_sdi_len); comp_sdi_len is use as both input and output. As input it is used to pass compbressed buffer length provided by caller and as an output it is used to return actual comppressed buffer length. so, condition transforms to: if (provided_comp_buf_len < actual_comp_buf_len) { ... }
[4 Jun 2019 14:30]
MySQL Verification Team
Hi, I have not been visiting that part of the code for the long, long time. In short, you are correct. Not only because of the retrieval of the data from the tuple, but also for the fact that decompression occurs in other functions, after this function has already being called. Verified as reported.
[10 Jul 2019 18:51]
Daniel Price
Posted by developer: Fixed as of the upcoming 8.0.18 release, and here's the changelog entry: An incorrect argument was used to compare serialized dictionary information (SDI) input and output values while checking the size of the buffer used to store SDI.
[11 Jul 2019 12:32]
MySQL Verification Team
Daniel, Thanks a lot .....