Patch for cmd donedl and cmd vdr

Download patched binaries

Vulnerable functions

Both commands lead to resetting the player state. This is the original code from sv_client.c.

static void SV_ResetPureClient_f( client_t *cl ) {
	cl->pureAuthentic = 0;
	cl->gotCP = qfalse;
}

void SV_DoneDownload_f( client_t *cl ) {
	Com_DPrintf( "clientDownload: %s Done\n", cl->name );
	// resend the game state to update any clients that entered during the download
	SV_SendClientGameState( cl );
}

Linux

.text:0804F048 ; ---------------------------------------------------------------------------
.text:0804F049                 align 10h
.text:0804F050                 mov     eax, [esp+4]
.text:0804F054                 xor     ecx, ecx
.text:0804F056                 xor     edx, edx
.text:0804F058                 mov     [eax+546C8h], ecx
.text:0804F05E                 mov     [eax+546CCh], edx
.text:0804F064                 retn
.text:0804F064 ; ---------------------------------------------------------------------------
.text:0804EE70 ; ---------------------------------------------------------------------------
.text:0804EE70                 push    ebx
.text:0804EE71                 sub     esp, 8
.text:0804EE74                 mov     ebx, [esp+10h]
.text:0804EE78                 mov     dword ptr [esp], offset aClientdownload_5 ; "clientDownload: %s Done\n"
.text:0804EE7F                 lea     eax, [ebx+4884Ch]
.text:0804EE85                 mov     [esp+4], eax
.text:0804EE89                 call    sub_806D2C0
.text:0804EE8E                 mov     [esp+10h], ebx
.text:0804EE92                 add     esp, 8
.text:0804EE95                 pop     ebx
.text:0804EE96                 jmp     sub_804EB60
.text:0804EE96 ; ---------------------------------------------------------------------------

Windows

.text:0041F3B6 ; ---------------------------------------------------------------------------
.text:0041F3B7                 align 10h
.text:0041F3C0                 mov     eax, [esp+4]
.text:0041F3C4                 xor     ecx, ecx
.text:0041F3C6                 mov     [eax+546C8h], ecx
.text:0041F3CC                 mov     [eax+546CCh], ecx
.text:0041F3D2                 retn
.text:0041F3D2 ; ---------------------------------------------------------------------------
.text:0041F252 ; ---------------------------------------------------------------------------
.text:0041F257                 align 10h
.text:0041F260                 push    esi
.text:0041F261                 mov     esi, [esp+8]
.text:0041F265                 lea     eax, [esi+4884Ch]
.text:0041F26B                 push    eax
.text:0041F26C                 push    offset aClientdownload_6 ; "clientDownload: %s Done\n"
.text:0041F271                 call    sub_40C410
.text:0041F276                 push    esi
.text:0041F277                 call    sub_41EF50
.text:0041F27C                 add     esp, 0Ch
.text:0041F27F                 pop     esi
.text:0041F280                 retn
.text:0041F280 ; ---------------------------------------------------------------------------

The fix

Patch will let the original SV_ResetPureClient_f() happen only when the player's state is not CS_ACTIVE.

SV_DoneDownload_f() checks for downloadEOF or bWWWDl flag, which, when non-zero, is a proof that player has downloaded something. Once the donedl command is sent, those values get zeroed.

Linux

.text:0804F048 ; ---------------------------------------------------------------------------
.text:0804F049                 align 10h
.text:0804F050                 cmp     byte ptr [edi], 4
.text:0804F053                 jz      short locret_804F063
.text:0804F055                 push    eax
.text:0804F056                 mov     [edi+546C8h], al
.text:0804F05C                 mov     [edi+546CCh], al
.text:0804F062                 pop     eax
.text:0804F063
.text:0804F063 locret_804F063:                         ; CODE XREF: .text:0804F053↑j
.text:0804F063                 retn
.text:0804F063 ; ---------------------------------------------------------------------------
.text:0804EE70 ; ---------------------------------------------------------------------------
.text:0804EE70                 push    eax
.text:0804EE71                 add     eax, [edi+48908h]
.text:0804EE77                 add     eax, [edi+48A14h]
.text:0804EE7D                 cmp     eax, 0
.text:0804EE80                 pop     eax
.text:0804EE81                 jz      short locret_804EE9B
.text:0804EE83                 mov     dword ptr [edi+48908h], 0
.text:0804EE8D                 mov     byte ptr [edi+48A14h], 0
.text:0804EE94                 nop
.text:0804EE95                 nop
.text:0804EE96                 jmp     sub_804EB60
.text:0804EE9B ; ---------------------------------------------------------------------------

ETTV (Linux)

.text:08059131 ; ---------------------------------------------------------------------------
.text:08059133                 align 10h
.text:08059140
.text:08059140 loc_8059140:                            ; CODE XREF: .text:08059131↑j
.text:08059140                 mov     eax, [esp+4]
.text:08059144                 cmp     dword ptr [eax], 4
.text:08059147                 jz      short locret_805915D
.text:08059149                 mov     dword ptr [eax+5474Ch], 0
.text:08059153                 mov     dword ptr [eax+54750h], 0
.text:0805915D
.text:0805915D locret_805915D:                         ; CODE XREF: .text:08059147↑j
.text:0805915D                 retn
.text:0805915D ; ---------------------------------------------------------------------------
.text:0805802D ; ---------------------------------------------------------------------------
.text:08058032                 db 90h
.text:08058033 ; ---------------------------------------------------------------------------
.text:08058033
.text:08058033 loc_8058033:                            ; CODE XREF: .text:08058054↓j
.text:08058033                 pop     ebx
.text:08058034                 retn
.text:08058034 ; ---------------------------------------------------------------------------
.text:08058035                 align 2
.text:08058036
.text:08058036 loc_8058036:                            ; CODE XREF: .text:0805806A↓j
.text:08058036                 pop     ebx
.text:08058037                 jmp     sub_8056800
.text:0805803C ; ---------------------------------------------------------------------------
.text:0805803C                 nop
.text:0805803D                 nop
.text:0805803E                 nop
.text:0805803F                 nop
.text:08058040                 push    ebx
.text:08058041                 nop
.text:08058042                 nop
.text:08058043                 nop
.text:08058044                 nop
.text:08058045                 nop
.text:08058046                 nop
.text:08058047                 nop
.text:08058048                 mov     eax, [ebx+48A14h]
.text:0805804E                 add     eax, [ebx+48908h]
.text:08058054                 jz      short loc_8058033
.text:08058056                 mov     dword ptr [ebx+48A14h], 0
.text:08058060                 mov     dword ptr [ebx+48908h], 0
.text:0805806A                 jmp     short loc_8058036
.text:0805806A ; ---------------------------------------------------------------------------
.text:0805806C                 db  90h
.text:0805806D ; ---------------------------------------------------------------------------

Windows

.text:0041F3B6 ; ---------------------------------------------------------------------------
.text:0041F3B7                 align 10h
.text:0041F3C0                 cmp     dword ptr [ebp+0], 4
.text:0041F3C4                 jz      short locret_41F3D8
.text:0041F3C6                 mov     eax, [esp+4]
.text:0041F3CA                 xor     ecx, ecx
.text:0041F3CC                 mov     [eax+546C8h], ecx
.text:0041F3D2                 mov     [eax+546CCh], ecx
.text:0041F3D8
.text:0041F3D8 locret_41F3D8:                          ; CODE XREF: .text:0041F3C4↑j
.text:0041F3D8                 retn
.text:0041F3D8 ; ---------------------------------------------------------------------------
.text:0041F252 ; ---------------------------------------------------------------------------
.text:0041F257                 align 4
.text:0041F258
.text:0041F258 loc_41F258:                             ; CODE XREF: .text:0041F284↓j
.text:0041F258                 pop     eax
.text:0041F259                 retn
.text:0041F25A ; ---------------------------------------------------------------------------
.text:0041F25A
.text:0041F25A loc_41F25A:                             ; CODE XREF: .text:0041F286↓j
.text:0041F25A                 pop     eax
.text:0041F25B                 jmp     sub_41EF50
.text:0041F260 ; ---------------------------------------------------------------------------
.text:0041F260                 push    eax
.text:0041F261                 add     eax, [ebp+48908h]
.text:0041F267                 mov     dword ptr [ebp+48908h], 0
.text:0041F271                 add     eax, [ebp+48A14h]
.text:0041F277                 mov     dword ptr [ebp+48A14h], 0
.text:0041F281                 cmp     eax, 0
.text:0041F284                 jz      short loc_41F258
.text:0041F286                 jmp     short loc_41F25A
.text:0041F286 ; ---------------------------------------------------------------------------

There are multiple versions of etded binaries in the wild thanks to previous patches. You can apply the patch to your own binary using this script.