Fix remote buffer overflows and format string attacks. Patch by Alexey Dobriyan, diffs taken from upstream svn. http://svn.openttd.org/cgi-bin/viewcvs.cgi?rev=2899&view=rev http://bugs.gentoo.org/show_bug.cgi?id=102631 Log Message: Fix: Several format string vulnerabilities and buffer overflows in the network code --- /trunk/console_cmds.c 2005/08/28 10:59:34 2898 +++ trunk/console_cmds.c 2005/08/28 12:24:57 2899 @@ -1132,7 +1132,7 @@ SEND_COMMAND(PACKET_CLIENT_SET_NAME)(_network_player_name); } else { if (NetworkFindName(_network_player_name)) { - NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, _network_player_name); + NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", _network_player_name); ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name)); NetworkUpdateClientInfo(NETWORK_SERVER_INDEX); } --- /trunk/network.c 2005/08/28 10:59:34 2898 +++ trunk/network.c 2005/08/28 12:24:57 2899 @@ -100,7 +100,7 @@ char temp[1024]; va_start(va, str); - vsprintf(buf, str, va); + vsnprintf(buf, lengthof(buf), str, va); va_end(va); switch (action) { @@ -499,7 +499,7 @@ GetString(str, STR_NETWORK_ERR_CLIENT_GENERAL + errorno); - NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, str); + NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str); // Inform other clients of this... strange leaving ;) FOR_ALL_CLIENTS(new_cs) { --- /trunk/network_client.c 2005/08/28 10:59:34 2898 +++ trunk/network_client.c 2005/08/28 12:24:57 2899 @@ -349,7 +349,7 @@ if (ci != NULL) { if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) { // Client name changed, display the change - NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, name); + NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", name); } else if (playas != ci->client_playas) { // The player changed from client-player.. // Do not display that for now @@ -666,7 +666,7 @@ ci = NetworkFindClientInfoFromIndex(index); if (ci != NULL) { - NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, str); + NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, "%s", str); // The client is gone, give the NetworkClientInfo free ci->client_index = NETWORK_EMPTY_INDEX; @@ -684,11 +684,11 @@ NetworkClientInfo *ci; index = NetworkRecv_uint16(MY_CLIENT, p); - NetworkRecv_string(MY_CLIENT, p, str, 100); + NetworkRecv_string(MY_CLIENT, p, str, lengthof(str)); ci = NetworkFindClientInfoFromIndex(index); if (ci != NULL) { - NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, str); + NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, "%s", str); // The client is gone, give the NetworkClientInfo free ci->client_index = NETWORK_EMPTY_INDEX; --- /trunk/network_server.c 2005/08/28 10:59:34 2898 +++ trunk/network_server.c 2005/08/28 12:24:57 2899 @@ -162,7 +162,7 @@ DEBUG(net, 2)("[NET] %s made an error (%s) and his connection is closed", client_name, str); - NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, str); + NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str); FOR_ALL_CLIENTS(new_cs) { if (new_cs->status > STATUS_AUTH && new_cs != cs) { @@ -904,7 +904,7 @@ DEBUG(net, 2)("[NET] %s reported an error and is closing his connection (%s)", client_name, str); - NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, str); + NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str); FOR_ALL_CLIENTS(new_cs) { if (new_cs->status > STATUS_AUTH) { @@ -929,11 +929,11 @@ return; } - NetworkRecv_string(cs, p, str, 100); + NetworkRecv_string(cs, p, str, lengthof(str)); NetworkGetClientName(client_name, sizeof(client_name), cs); - NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, str); + NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str); FOR_ALL_CLIENTS(new_cs) { if (new_cs->status > STATUS_AUTH) { @@ -1108,7 +1108,7 @@ if (ci != NULL) { // Display change if (NetworkFindName(client_name)) { - NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, client_name); + NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", client_name); ttd_strlcpy(ci->client_name, client_name, sizeof(ci->client_name)); NetworkUpdateClientInfo(ci->client_index); } --- /trunk/texteff.c 2005/08/28 10:59:34 2898 +++ trunk/texteff.c 2005/08/28 12:24:57 2899 @@ -62,7 +62,7 @@ int length; va_start(va, message); - vsprintf(buf, message, va); + vsnprintf(buf, lengthof(buf), message, va); va_end(va); /* Special color magic */ --- openttd/os2.c +++ openttd/os2.c @@ -642,7 +642,7 @@ static long CDECL MidiSendCommand(const va_list va; char buf[512]; va_start(va, cmd); - vsprintf(buf, cmd, va); + vsnprintf(buf, sizeof(buf), cmd, va); va_end(va); return mciSendString(buf, NULL, 0, NULL, 0); } --- openttd/strgen/strgen.c +++ openttd/strgen/strgen.c @@ -84,7 +84,7 @@ void warning(const char *s, ...) { char buf[1024]; va_list va; va_start(va, s); - vsprintf(buf, s, va); + vsnprintf(buf, sizeof(buf), s, va); va_end(va); fprintf(stderr, "%d: ERROR: %s\n", _cur_line, buf); _warnings = true; @@ -94,7 +94,7 @@ void NORETURN error(const char *s, ...) char buf[1024]; va_list va; va_start(va, s); - vsprintf(buf, s, va); + vsnprintf(buf, sizeof(buf), s, va); va_end(va); fprintf(stderr, "%d: FATAL: %s\n", _cur_line, buf); exit(1); --- openttd/ttd.c +++ openttd/ttd.c @@ -70,7 +70,7 @@ void CDECL error(const char *s, ...) { va_list va; char buf[512]; va_start(va, s); - vsprintf(buf, s, va); + vsnprintf(buf, sizeof(buf), s, va); va_end(va); ShowOSErrorBox(buf); @@ -86,7 +86,7 @@ void CDECL ShowInfoF(const char *str, .. va_list va; char buf[1024]; va_start(va, str); - vsprintf(buf, str, va); + vsnprintf(buf, sizeof(buf), str, va); va_end(va); ShowInfo(buf); } @@ -99,7 +99,7 @@ char * CDECL str_fmt(const char *str, .. char *p; va_start(va, str); - len = vsprintf(buf, str, va); + len = vsnprintf(buf, sizeof(buf), str, va); va_end(va); p = malloc(len + 1); if (p) --- openttd/win32.c +++ openttd/win32.c @@ -841,7 +841,7 @@ static long CDECL MidiSendCommand(const char buf[512]; va_start(va, cmd); - vsprintf(buf, cmd, va); + vsnprintf(buf, sizeof(buf), cmd, va); va_end(va); return mciSendStringA(buf, NULL, 0, 0); }