1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-06 05:53:12 +02:00

Newlog and fishy timestamp handling:

* New macro IsInvalidChannelTS() which evaluates to ts < 750000
* Check for faulty creation time ("fishy timestamp") at ALL places
  where channel->creationtime is set.
* Also, important, changed behavior:
  if !IsInvalidChannelTS then:
  1) We print our warning
  2) We pretend ts is our channel creationtime (which may be
     TStime() if the channel did not previously exist)
  3) We allow the command through and allow it to merge (in case of SJOIN)

This makes it so we still log the error (noisy) but on the other hand
we won't get "infected" by fishy timestamps since we will never set
them, no matter what happens.
This commit is contained in:
Bram Matthys
2021-08-11 15:29:45 +02:00
parent 471a97c5f6
commit 9efe590a8e
4 changed files with 36 additions and 25 deletions
+2
View File
@@ -2007,6 +2007,8 @@ struct Link {
} value;
};
#define IsInvalidChannelTS(x) ((x) < 750000) /**< Invalid channel creation time */
/**
* @addtogroup CommonStructs
* @{
+4 -1
View File
@@ -506,7 +506,10 @@ int read_channeldb(void)
R_SAFE(unrealdb_read_str(db, &mode_lock));
/* If we got this far, we can create/initialize the channel with the above */
channel = make_channel(chname);
channel->creationtime = creationtime;
if (IsInvalidChannelTS(creationtime))
channel->creationtime = TStime();
else
channel->creationtime = creationtime;
safe_strdup(channel->topic, topic);
safe_strdup(channel->topic_nick, topic_nick);
channel->topic_time = topic_time;
+18 -12
View File
@@ -417,25 +417,31 @@ void _do_mode(Channel *channel, Client *client, MessageTag *recv_mtags, int parc
{
if (sendts > 0)
{
if (!channel->creationtime || sendts < channel->creationtime)
if (IsInvalidChannelTS(sendts))
{
unreal_log(ULOG_WARNING, "mode", "MODE_INVALID_TIMESTAMP", NULL,
"MODE for channel $channel has invalid timestamp $send_timestamp (from $client.name on $client.user.servername)\n"
"Buffer: $modebuf $parabuf",
log_data_channel("channel", channel),
log_data_integer("send_timestamp", sendts),
log_data_string("modebuf", modebuf),
log_data_string("parabuf", parabuf));
/* Yeah, so what to do in this case?
* Don't set channel->creationtime
* and assume merging.
*/
sendts = channel->creationtime;
} else
if (sendts < channel->creationtime)
{
/* Our timestamp is wrong (or this is a new channel) */
tschange = 1;
channel->creationtime = sendts;
if (sendts < 750000)
{
sendto_realops(
"Warning! Possible desync: MODE for channel %s ('%s %s') has fishy timestamp (%lld) (from %s/%s)",
channel->name, modebuf, parabuf, (long long)sendts, client->direction->name, client->name);
ircd_log(LOG_ERROR, "Possible desync: MODE for channel %s ('%s %s') has fishy timestamp (%lld) (from %s/%s)",
channel->name, modebuf, parabuf, (long long)sendts, client->direction->name, client->name);
}
/* new chan or our timestamp is wrong */
/* now works for double-bounce prevention */
}
if (sendts > channel->creationtime && channel->creationtime)
{
/* theirs is wrong but we let it pass anyway */
/* Their timestamp is wrong */
sendts = channel->creationtime;
sendto_one(client, NULL, ":%s MODE %s + %lld", me.name,
channel->name, (long long)channel->creationtime);
+12 -12
View File
@@ -178,16 +178,25 @@ CMD_FUNC(cmd_sjoin)
if (parc < 5)
nomode = 1;
ts = (time_t)atol(parv[1]);
channel = find_channel(parv[2]);
if (!channel)
{
channel = make_channel(parv[2]);
channel->creationtime = ts;
oldts = -1;
}
ts = (time_t)atol(parv[1]);
if (IsInvalidChannelTS(ts))
{
unreal_log(ULOG_WARNING, "sjoin", "SJOIN_INVALID_TIMESTAMP", NULL,
"SJOIN for channel $channel has invalid timestamp $send_timestamp (from $client)",
log_data_channel("channel", channel),
log_data_integer("send_timestamp", ts));
/* Pretend they match our creation time (matches U6 behavior in m_mode.c) */
ts = channel->creationtime;
}
if (channel->creationtime > ts)
{
removeours = 1;
@@ -208,15 +217,6 @@ CMD_FUNC(cmd_sjoin)
oldts = channel->creationtime;
}
// FIXME: make it so services cannot screw this up so easily --- if possible...
if (ts < 750000)
{
if (ts != 0)
sendto_ops
("Warning! Possible desync: SJOIN for channel %s has a fishy timestamp (%lld) [%s/%s]",
channel->name, (long long)ts, client->name, client->direction->name);
}
parabuf[0] = '\0';
modebuf[0] = '+';
modebuf[1] = '\0';