-
Notifications
You must be signed in to change notification settings - Fork 13.8k
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
Fix an edge case in .to_win32pe #18094
Fix an edge case in .to_win32pe #18094
Conversation
When the entry point is after the payload, there woud occassionally be cases where `poff` and `eidx` to be invalid, causing `entry` to be truncated. `poff` should never be negative and `eidx` should reserve the 256 bytes that `entry` may occupy.
poff -= [256, poff].min | ||
eidx = rand(block[1] - (poff + payload.length + 256)) + poff + payload.length |
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.
These two lines are the real fix for the boundary issues.
if payload.length + 256 >= block[1] | ||
raise RuntimeError, "The largest block in .text does not have enough contiguous space (need:#{payload.length+257} found:#{block[1]})" | ||
end |
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.
This was switched to ensure that block[1]
is greater than payload.length + 256
. 256 is the max size of the entry as you can see on L324. 5 bytes are reserved for the jump instruction.
This should prevent future calls to rand()
from receiving 0 in the event that payload.length + 256 == block[1]
. When Ruby's rand()
function is called with 0, it will return a float which is unexpected.
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.
Will wait for another team member to also approve before landing; but as a datapoint I was running into this issue once or twice every 200 generations or so on CI, to not having seen the original segfault crash after 1000+ generations. Thanks for the fix! 👍
Release NotesFixes an edgecase with |
When the entry point is after the payload, there would occasionally be cases where
poff
andeidx
to be invalid, causingentry
to be truncated.poff
should never be negative andeidx
should reserve the 256 bytes thatentry
may occupy.Testing
rand()
calls to initializeeloc
to 1 andpoff
to 100. This would have triggered the bug every time.