-
Notifications
You must be signed in to change notification settings - Fork 171
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
SZ_GetSpace: Fix reversing error & buffer overflow #1014
Conversation
It's pretty clear when you look at the previous (ReHLDS) func implementation that it's wrong. Not only it does not match the original (HLDS) The return value is same whether the sizebuf overflowed or not. The changes that are different end up doing nothing: SZ_Clear unsets the SZ_Clear also sets |
There is no reverse mistake here, and the code behavior is exactly the same, except for the lack of @anzz1 |
I am sorry, but you are wrong. You can use either the build 6153 rehlds was originally based on, or the newer 8684 pre-anniversary one, since the First of all, the negative check does not exist. In fact, the string "%s: %i negative length on %s" does not exist anywhere in the binary, you can confirm by searching for the word "negative" Secondly, the Thirdly, the logic for print "full buffer size on %s" or "full buffer size on %s, ignoring" is wrong, one or the other or none must be printed but never both of them. But the real problem here is that the check for To simplify, this is how function should work: If overflowed: If not overflowed: But currently it does not have the "If overflowed" part. |
I didn't contradict that, I know it doesn't exist and I mentioned it above, that it really isn't in the vanilla code and should have been wrapped in
You can check with dwarf again and use the right tools to fully analyze them, and you will notice that /* <11cdc> ../engine/common.cpp:1777 */
void *SZ_GetSpace(sizebuf_t *buf, int length)
{
// void *data;
// SZ_Clear(sizebuf_t *buf);
} If you still have doubts, u can take a look at windows binaries any build, which uses less optimization and cleaner disassembler (pseudocode) code SZ_GetSpacevoid *__cdecl SZ_GetSpace(sizebuf_t *buf, int length)
{
bool v3; // zf
const char *v4; // eax
const char *v5; // eax
const char *v6; // eax
int v7; // ecx
void *result; // eax
if ( length + buf->cursize > buf->maxsize )
{
if ( !(buf->flags & 1) )
{
v4 = buf->buffername;
if ( buf->maxsize == 0 )
{
if ( !v4 )
v4 = "???";
Sys_Error("SZ_GetSpace: Tried to write to an uninitialized sizebuf_t: %s", v4);
}
if ( !v4 )
v4 = "???";
Sys_Error("SZ_GetSpace: overflow without FSB_ALLOWOVERFLOW set on %s", v4);
}
if ( length > buf->maxsize )
{
v5 = buf->buffername;
if ( !(buf->flags & 1) )
{
if ( !v5 )
v5 = "???";
Sys_Error("SZ_GetSpace: %i is > full buffer size on %s", length, v5);
}
if ( !v5 )
v5 = "???";
Con_DPrintf("SZ_GetSpace: %i is > full buffer size on %s, ignoring", length, v5);
}
v6 = buf->buffername;
if ( !buf->buffername )
v6 = "???";
Con_Printf("SZ_GetSpace: overflow on %s\n", v6);
SZ_Clear(buf);
buf->flags |= 2u;
}
v7 = buf->cursize;
result = &buf->data[v7];
buf->cursize = length + v7;
return result;
}
This does not change anything, Anyway, let's leave the point about what a function looks like in vanilla code and turn to the main question, the logic of the code.
No, it is not
Following your point of view about the logic of the code, there are no contradictions in the current code, it still works as you expected, and for some reason, you ignore the fact that |
I guess I could still reopen this since this way its more correct, with the Printf paths bifurcated. But like you said, it ultimately only changes the print part and removes the unnecessary SZ_Clear doing &~ SIZEBUF_OVERFLOWED , | SIZEBUF_OVERFLOWED dance. Setting the length to 0 in SZ_Clear makes length+cursize == length+0, which I missed. So when it comes to the overflow bug, this PR has no real effect. Was this bug ever fixed in the original HLDS? As the two possibilities are that either a similar reversing error due to incorrect output or whatever happened in ReHLDS, or that this overflow bug still exist in original HLDS too. I try to save the stack information next time I encounter it if there's anything helpful there, but as the underlying error could have happened way earlier than the crash itself it might be of no help. We'll see, the bug leading to a crash is unfortunately pretty rare and thus hard to catch as the server could run for weeks without encountering it. |
Because, if the function I'm still convinced that it doesn't matter which instructions follow the |
Oh yeah, if I followed further, I would've seen that God damn it, I thought that this issue would be finally solved. Exactly as you said, I was confused after all. 😅 Well, you live to learn, I guess. |
Anzz1, this problem what you fixed for sz getspace where we can download beacuse i have problem in my server |
edit: tl;dr; as it becomes clear in the posts further below, this PR doesn't actually fix the problem.
SZ_GetSpace: Fix reversing error & buffer overflow
This hopefully fixes the crash following soon after
SZ_GetSpace: overflow on netchan->message
and other SZ_GetSpace related errors.Also I have a question about previous implementation,
where did these come from?
https://github.com/dreamstalker/rehlds/blob/90cb97ddae6cd7c66b08987d4d8049cb9fbcc76d/rehlds/engine/common.cpp#L1189-L1192
and
https://github.com/dreamstalker/rehlds/blob/90cb97ddae6cd7c66b08987d4d8049cb9fbcc76d/rehlds/engine/common.cpp#L1243
These are not present in the original engine, nor are they wrapped in
#ifdef REHLDS_FIXES
. It seems they appear out of thin air.