Bug 3605 - fs_fakeChkSum? eh?
Status: RESOLVED FIXED
Alias: None
Product: ioquake3
Classification: Unclassified
Component: Misc
Version: GIT MASTER
Hardware: All All
: P3 minor
Assignee: Zachary J. Slater
QA Contact: ioquake3 bugzilla mailing list
URL:
Depends on:
Blocks:
 
Reported: 2008-04-19 16:18 EDT by /dev/humancontroller
Modified: 2009-10-11 12:35:26 EDT
1 user (show)

See Also:


Attachments
erase fs_fakeChkSum (1.61 KB, patch)
2008-04-30 22:01 EDT, /dev/humancontroller

Description /dev/humancontroller 2008-04-19 16:18:51 EDT
fs_fakeChkSum caught my eye.

When building a list of referenced paks on the client, if it's non-0, then it is added as a pak checksum. It's a static global int (and therefore initialized to 0). When we're accessing a non-(cfg|menu|...) file, it's set to random(). But random() returns a float between 0.0 and 1.0, and in all cases but 1.0 it is truncated to 0. rand() would be the intended value. But with that fixed, there's no reset (to 0) in either FS_Restart, or FS_ClearPakReferences, so after visiting a non-pure server, we will never be pure again. But even with that fixed, most importantly, on non-pure servers, the value's existance doesn't matter, and on pure servers, no such files are referenced anyway.

I think it's uselessness and insignificance is what made it not noticable. Remove (if yes, should I make a patch)?
Comment 1 /dev/humancontroller 2008-04-30 22:01:39 EDT
Created attachment 1740 [details]
erase fs_fakeChkSum

had nothing else to do at the moment
take it or leave it :P
Comment 2 Ludwig Nussel 2008-07-10 16:36:15 EDT
       long int random(void);

RETURN VALUE
       The random() function returns a value  between  0  and  RAND_MAX.

So the code is correct. You could be right that the variable needs to be reset at some place. That needs further investigation.
Comment 3 Amanieu d'Antras 2008-07-10 16:56:50 EDT
You can initialize fs_fakeChecksum to 0 in FS_Startup.
Also, random() shouldn't be used since it could return 0 and the code checks for non-zero. Can be easily fix with "if(fakeChecksum) fakeChecksum=0;".

Here is how I reimplemented it (I accidentally removed it in the previous commit): http://tremfusion.tremforges.net/hg/tremfusion/rev/ae5f4dc25b20
Comment 4 /dev/humancontroller 2008-07-11 11:57:23 EDT
Ludwig, random() is overridden in q_shared.h:
#define random() ((rand () & 0x7fff) / ((float)0x7fff))

The intended output of the reference string is "cgame ui @ ref1 ref2 ... numpaks", but if fs_fakeChkSum != 0, then the result is "cgame fake ui fake @ ref1 ref2 ... fake numpaks". This the incorrectness.

I've taken a look at, and seen good things in Amanieu's implementation.
If we don't add that fs_allowUnpure, note that in the case of fs_numServerPaks != 0 (a pure server!), the first "if ( Q_stricmp( filename + l - 4, ".cfg" ) && ... ) { continue; }" makes the second such check (with "fs_fakeChkSum = random();") useless.
Comment 5 Amanieu d'Antras 2008-07-11 16:36:12 EDT
In TremFusion I completely changed the use of sv_pure from cheat protection to a list of "recommended" pk3 that the client should use, but can override using fs_extraPaks.
(I never liked pure, it's just another form of DRM and it is useless for preventing cheaters)

(In reply to comment #4)
> The intended output of the reference string is "cgame ui @ ref1 ref2 ...
> numpaks", but if fs_fakeChkSum != 0, then the result is "cgame fake ui fake @
> ref1 ref2 ... fake numpaks". This the incorrectness.

The incorrectness is intentional, because that reference string is ignored on non-pure servers. If the server is pure, it will reject the client because of the invalid reference string. There shouldn't be any other cases of invalid references since the client prevents any pk3s not in the server pure list from being opened.
Comment 6 Thilo Schulz 2009-10-11 12:35:26 EDT
Fixed in rev. 1654
I did not remove the fake checksum check, just made sure it can never be 0.
Also reset the fake checksum after FS_Restart.