View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0002980||unreal||ircd||public||2006-06-19 02:50||2006-11-04 16:30|
|Platform||i386||OS||linux/fbsd (maybe others)||OS Version||2.4.32 / 4.11-st|
|Target Version||Fixed in Version||3.2.6|
|Summary||0002980: Big services stamp may break synchrony among servers.|
|Description||If you define a services stamp greater than 2147483647, and a server falls on netsplit, when it gets back, it disseminates all users as being the same servicestamp (to this max value). This can cause problems with services-ready networks, as a user could identify to others' nicks w/out knowing their password (as long as services rely on services stamp).|
|Steps To Reproduce||Run two ircds, link them. Link also a ulined server, and set your services stamp to a value greater than 2147483647. Check your services stamp's value on the remote server (it should be ok at this time). Send a SQUIT between the two ircds, and then, without logging out (which will reset the services stamp), reconnect both servers and look your services stamp being that 2147... number.|
This occurs because the user's structure servicestamp var is declared long (and that is the max value of long).
|Additional Information||Three directions to fix the issue:|
- Declare servicestamp as long long from make_user(), and adapt each call to the var to this (would imply in calling atoll() in place of atol();
- Limit the mode assigning from m_svsmode.c (case 'd') either by issuing a test for the size or by calling atol() there too (as done in the problem source, m_user.c)
- Make m_user.c work like the svsmode.c case 'd', and do a strtoul, and declare servicestamp as unsigned long (for safe) in make_user(). I'm taking this for this is the less hard way to fix the problem.
- Other solution will not fix the bug: make services not assing services stamp long wouldn't comport. :)
|Tags||No tags attached.|
|3rd party modules|
For the first solution, servicestamp is u_int32_t type, so the only problem seems to be the atol() used against this type, and maybe the best form should be the second, just calling strtoul() instead of atol.
If so, just get to m_user.c, and change all
sstamp = atol(parv);
sstamp = strtoul(parv);
Well, if this works on m_svsmode (case 'd') why not work here? *sigh*
Except strtoul is:
[quote]unsigned long int strtoul(const char *nptr, char **endptr, int base);[/quote]
wrap it in a macro?
#define atoul(x) strtoul((x), strlen((x)), 10)
The only problem is that man strtoul says the string has to start with 'an arbitrary amount of whitespace', and I don't know if that means 'zero or more' or 'one or more'
||**endptr doestn't mean the string length. it's a pointer to the first character which isn't a umber in *nptr. it can be NULL and then strtol() is like atol(). And it doestn't need of course a whitespace at the beginning would be senseless anyway|
#define atoul(x) strtoul((x), NULL, 10)
Fixed in 32* and 33* CVS:
- Services timestamps are now always treated as an unsigned long (0..2^32-1), instead
of accidently as signed long during netsynchs. This bug caused issues with values
larger than 2147483647. Reported by avenger (0002980).
|2006-06-19 02:50||avenger||New Issue|
|2006-06-19 03:01||avenger||Note Added: 0011987|
|2006-06-21 15:18||aquanight||Note Added: 0011995|
|2006-06-21 16:02||tabrisnet||Note Added: 0011996|
|2006-06-21 17:10||penna||Note Added: 0011997|
|2006-06-21 17:31||tabrisnet||Note Added: 0011998|
|2006-07-02 16:21||syzop||Status||new => acknowledged|
|2006-07-02 16:21||syzop||Relationship added||child of 0002936|
|2006-11-04 16:30||syzop||Status||acknowledged => resolved|
|2006-11-04 16:30||syzop||Fixed in Version||=> 3.2.6|
|2006-11-04 16:30||syzop||Resolution||open => fixed|
|2006-11-04 16:30||syzop||Assigned To||=> syzop|
|2006-11-04 16:30||syzop||Note Added: 0012586|