[MDEV-24156] trx_undo_left() fails to prevent overflow Created: 2020-11-06 Updated: 2020-11-12 Resolved: 2020-11-12 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB |
| Affects Version/s: | 5.5, 10.0, 10.1, 10.2, 10.3, 10.4, 10.5 |
| Fix Version/s: | 10.2.37, 10.3.28, 10.4.18, 10.5.9 |
| Type: | Bug | Priority: | Major |
| Reporter: | Marko Mäkelä | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | corruption, crash, overflow, upstream | ||
| Issue Links: |
|
||||||||
| Description |
|
The function trx_undo_left() checks whether an undo log record (or a part of it) would fit in the undo log page. If not, a new undo log page will be allocated. There is some wishful thinking in the design of the function, all the way from the very start of the public history of InnoDB:
Due to the unsigned return type, the additional 10 bytes actually constitute an unsafety margin that causes us to waste 10 bytes in every undo log page. If the ptr is already past those 10+4 bytes from the end of the page, the function will return a large positive value. But the numerous trx_undo_left(...) < ... checks would expect a negative value. I think that we must add debug assertions to the function in all maintained versions (backport parts of Also, we should re-review all code that calls the function, especially the code that writes indexed virtual columns to the undo log. |
| Comments |
| Comment by Marko Mäkelä [ 2020-11-06 ] | ||||||||||||||
|
I believe that this could fix the root cause of MySQL Bug #94553 Crash in trx_undo_rec_copy and similar reports. | ||||||||||||||
| Comment by Matthias Leich [ 2020-11-11 ] | ||||||||||||||
|
| ||||||||||||||
| Comment by Marko Mäkelä [ 2020-11-11 ] | ||||||||||||||
|
mleich, sorry, I thought that you would have triggered the new debug assertion ut_ad(left >= 0) that we introduced in trx_undo_left().
The large dest_size looks like -4 when interpreted as a signed integer. The col_len=4 that was passed to row_mysql_store_blob_ref() is definitely too small. | ||||||||||||||
| Comment by Matthias Leich [ 2020-11-12 ] | ||||||||||||||
|
For the rr trace mentioned above I have created |