-
Notifications
You must be signed in to change notification settings - Fork 370
small codefix for Calc crash-on-open AV — latent UAF, debug-CRT-deter… #485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2952,6 +2952,15 @@ void ScViewData::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue> | |
| pTabData[nZoomTab]->aPageZoomY = aDefPageZoomY; | ||
| } | ||
|
|
||
| // The loop above delete'd and re-new'd pTabData[] entries (including the | ||
| // active one) but left pThisTab pointing at a freed ScViewDataTable. Restore | ||
| // the pThisTab == pTabData[nTabNo] invariant before anyone dereferences it | ||
| // (e.g. ScTabView::SetTabNo -> GetActivePart()). Mirrors SetTabNo (line | ||
| // ~1502). Without it, a debug build AVs on document open (reads 0xDDDDDDDD); | ||
| // release masks it only via allocator MRU reuse. | ||
| CreateTabData( nTabNo ); | ||
| pThisTab = pTabData[nTabNo]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not rather call This code creates
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sadly i do not have the week of AI discussion anymore.
You need a debug build, that poisens freed memory. That will cause AOO to crash when you start calc. If i understood the AI correctly it is independant of Platform. Valgrind for example can do this on Linux. Here is how i crossed the issue: (adapted to the current code)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I let the AI answer: Both would refresh pThisTab, but UpdateThis() is the wrong tool here — it carries a side effect that's appropriate for tab deletion, not for an active-tab read. Three reasons our two-line form is correct and UpdateThis() isn't:
That downward walk is exactly what DeleteTab/InsertTab (lines 515/528) want: tabs were removed, so nTabNo may now be out of range and must be pulled back to a surviving sheet. But ReadUserDataSequence is restoring the saved active tab — nTabNo is meaningful and must not move. If the active sheet happened to have no entry in the user data (pTabData[nTabNo] == NULL), UpdateThis() would silently switch the document to a different, lower-indexed sheet on open. That's a behavior regression, not a fix. CreateTabData(nTabNo) instead materializes that slot in place and leaves nTabNo alone.
Worth noting (from the memory): the proper structural fix is neither — it's to delete the cached pThisTab member entirely and derive it via a ThisTab() const { return pTabData[nTabNo]; } accessor, making the invariant correct by construction and killing the whole bug class. We didn't do that because the goal was a minimal, low-risk unblock, not a refactor. |
||
|
|
||
| if (nCount) | ||
| SetPagebreakMode( bPageMode ); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that "the loop above" should be at lines 2811-2828. This comment and the following code should be closer to that, shouldn't they?
In addition, I do not see the
deleteandnewas deterministic as the comment states. Reading the code, I understand thatpTabData[]entries could be recreated or not.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment refers to the code lines below that where added. Basically all we do is trigger a refresh of the index and nothing else.
The culprit lines are
I think it is that far below because we do not read the index before that point. The If else clause i think ends in 2942. so we could move the code in 2954.
The code needs to be outside the if - else clause in order to ensure that the code is refreshed. Better would be not handle the index static, but recalculate the index every time we want to read it, because on today architecture thats faster. (says the AI, and it is plausible to me :D ) there are more details at:
https://github.com/apache/openoffice/blob/bazel-migration/bug-readme.md#14-calc-crash-on-open-av--latent-uaf-debug-crt-deterministic-not-a-migration-bug