浏览代码

* Too large client packets, which would otherwise cause the client to crash, are now dropped and reported (bugreport:4391).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@14503 54d463be-8e91-2dee-dedb-b68131a5f0ec
ai4rei 14 年之前
父节点
当前提交
10396bbbbf
共有 3 个文件被更改,包括 20 次插入0 次删除
  1. 1 0
      Changelog-Trunk.txt
  2. 7 0
      conf/packet_athena.conf
  3. 12 0
      src/common/socket.c

+ 1 - 0
Changelog-Trunk.txt

@@ -1,6 +1,7 @@
 Date	Added
 
 2010/11/25
+	* Too large client packets, which would otherwise cause the client to crash, are now dropped and reported (bugreport:4391). [Ai4rei]
 	* Fixed a crash when an unknown map is encountered during parsing a 'script' npc and the script has mismatched curly braces (bugreport:4423, since r11502). [Ai4rei]
 	* Fixed script commands attachrid and detachrid not updating the attached character's information about currently running script, causing errors with dialog-based scripts or preventing characters from walking (bugreport:4571). [Ai4rei]
 2010/11/24

+ 7 - 0
conf/packet_athena.conf

@@ -8,6 +8,13 @@ debug: no
 // How long can a socket stall before closing the connection (in seconds)
 stall_time: 60
 
+// Maximum allowed size for clients packets in bytes (default: 20480).
+// NOTE: To reduce the size of reported packets, lower the values of defines, which
+//       have been customized, such as MAX_STORAGE, MAX_GUILD_STORAGE or MAX_CART.
+// NOTE: Do not modify this setting, unless the client has been modified to support
+//       larger packets. The client will crash, when it receives larger packets.
+socket_max_client_packet: 20480
+
 //----- IP Rules Settings -----
 
 // If IP's are checked when connecting.

+ 12 - 0
src/common/socket.c

@@ -199,6 +199,10 @@ time_t stall_time = 60;
 uint32 addr_[16];   // ip addresses of local host (host byte order)
 int naddr_ = 0;   // # of ip addresses
 
+// Maximum packet size in bytes, which the client is able to handle.
+// Larger packets cause a buffer overflow and stack corruption.
+static size_t socket_max_client_packet = 20480;
+
 // initial recv buffer size (this will also be the max. size)
 // biggest known packet: S 0153 <len>.w <emblem data>.?B -> 24x24 256 color .bmp (0153 + len.w + 1618/1654/1756 bytes)
 #define RFIFO_SIZE (2*1024)
@@ -643,6 +647,12 @@ int WFIFOSET(int fd, size_t len)
 		exit(EXIT_FAILURE);
 	}
 
+	if( !s->flag.server && len > socket_max_client_packet )
+	{// see declaration of socket_max_client_packet for details
+		ShowError("WFIFOSET: Dropped too large client packet 0x%04x (length=%u, max=%u).\n", WFIFOW(fd,0), len, socket_max_client_packet);
+		return 0;
+	}
+
 	if( !s->flag.server && s->wdata_size+len > WFIFO_MAX )
 	{// reached maximum write fifo size
 		set_eof(fd);
@@ -1064,6 +1074,8 @@ int socket_config_read(const char* cfgName)
 			ddos_autoreset = atoi(w2);
 		else if (!strcmpi(w1,"debug"))
 			access_debug = config_switch(w2);
+		else if (!strcmpi(w1,"socket_max_client_packet"))
+			socket_max_client_packet = strtoul(w2, NULL, 0);
 #endif
 		else if (!strcmpi(w1, "import"))
 			socket_config_read(w2);