All pastes #55793 Raw Edit

Mine

public text v1 · immutable
#55793 ·published 2006-05-14 13:26 UTC
rendered paste body
Index: ChangeLog
===================================================================
RCS file: /cvsroot/crossfire/crossfire/ChangeLog,v
retrieving revision 1.612
diff -c -5 -r1.612 ChangeLog
*** ChangeLog	13 May 2006 21:21:11 -0000	1.612
--- ChangeLog	14 May 2006 13:05:03 -0000
***************
*** 15,24 ****
--- 15,39 ----
  small - this just lets others know that the file has changed if nothing
  else.  With this, include the file(s) that you changed.
  ------------------------------------------------------------------------------
  Changes for CVS:
  
+ Make socket handling more robust.
+ ---
+ include/newclient.h: Split MAXSOCKBUF into MAXSOCKRECVBUF and MAXSOCKSENDBUF.
+    Increase the receive buffer size to be able to handle all valid packets;
+    decrease send buffer size to 10239 to not overflow the receive buffer of old
+    clients.
+ socket/{image.c,info.c,init.c,item.c,loop.c,lowlevel.c,request.c,sounds.c}: Use
+    renamed constants.
+ socket/image.c: In send_image_sums() prevent buffer overflows. Reject the
+    command instead.
+ socket/request.c: In send_skill_info() and send_spell_paths() prevent buffer
+    overflows. Instead send only as much information as fits into the buffer.
+ socket/loop.c: In handle_client() prevent possible array out-of-bounds access.
+ Andreas Kirschbaum 2006-05-14
+ 
  Fix server crash when sending addspell command(s).
  ---
  socket/lowlevel.c: Do not abort if output buffer is completely filled. (Was
     off-by-one, so if addspell did fill the complete buffer, the server did
     detect an buffer-overflow error.)
Index: include/newclient.h
===================================================================
RCS file: /cvsroot/crossfire/crossfire/include/newclient.h,v
retrieving revision 1.12
diff -c -5 -r1.12 newclient.h
*** include/newclient.h	9 Jan 2006 19:35:12 -0000	1.12
--- include/newclient.h	14 May 2006 13:05:03 -0000
***************
*** 46,60 ****
  
  
  #ifndef NEWCLIENT_H
  #define NEWCLIENT_H
  
! /* Maximum size of any packet we expect.  Using this makes it so we don't need to
!  * allocated and deallocated teh same buffer over and over again and the price
!  * of using a bit of extra memory.  IT also makes the code simpler.
   */
! #define MAXSOCKBUF 10240
  
  
  #define CS_QUERY_YESNO	0x1	/* Yes/no question */
  #define CS_QUERY_SINGLECHAR 0x2	/* Single character response expected */
  #define CS_QUERY_HIDEINPUT 0x4	/* Hide input being entered */
--- 46,65 ----
  
  
  #ifndef NEWCLIENT_H
  #define NEWCLIENT_H
  
! /* Maximum size of any packet we expect. This number includes both the length
!  * bytes (2 bytes) at the start of each packet and the trailing '\0' (1 byte)
!  * at the end of each packet.
   */
! #define MAXSOCKRECVBUF (2+65535+1)
! 
! /* Maximum size of any packet we send. This number does not include the length
!  * bytes at the start of each packet.
!  */
! #define MAXSOCKSENDBUF 10239
  
  
  #define CS_QUERY_YESNO	0x1	/* Yes/no question */
  #define CS_QUERY_SINGLECHAR 0x2	/* Single character response expected */
  #define CS_QUERY_HIDEINPUT 0x4	/* Hide input being entered */
Index: socket/image.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/socket/image.c,v
retrieving revision 1.10
diff -c -5 -r1.10 image.c
*** socket/image.c	18 Mar 2006 15:05:37 -0000	1.10
--- socket/image.c	14 May 2006 13:05:03 -0000
***************
*** 329,339 ****
      if (face_num <= 0 || face_num >= nrofpixmaps) {
  	LOG(llevError,"esrv_send_face (%d) out of bounds??\n",face_num);
  	return;
      }
  
!     sl.buf = malloc(MAXSOCKBUF);
      fallback = get_face_fallback(ns->faceset, face_num);
  
      if (facesets[fallback].faces[face_num].data == NULL) {
  	LOG(llevError,"esrv_send_face: faces[%d].data == NULL\n",face_num);
  	return;
--- 329,339 ----
      if (face_num <= 0 || face_num >= nrofpixmaps) {
  	LOG(llevError,"esrv_send_face (%d) out of bounds??\n",face_num);
  	return;
      }
  
!     sl.buf = malloc(MAXSOCKSENDBUF);
      fallback = get_face_fallback(ns->faceset, face_num);
  
      if (facesets[fallback].faces[face_num].data == NULL) {
  	LOG(llevError,"esrv_send_face: faces[%d].data == NULL\n",face_num);
  	return;
***************
*** 385,395 ****
  void send_image_info(socket_struct *ns, char *params)
  {
      SockList sl;
      int i;
  
!     sl.buf = malloc(MAXSOCKBUF);
  
      sprintf(sl.buf,"replyinfo image_info\n%d\n%d\n", nrofpixmaps-1, bmaps_checksum);
      for (i=0; i<MAX_FACE_SETS; i++) {
  	if (facesets[i].prefix) {
  	    sprintf(sl.buf + strlen(sl.buf), "%d:%s:%s:%d:%s:%s:%s",
--- 385,395 ----
  void send_image_info(socket_struct *ns, char *params)
  {
      SockList sl;
      int i;
  
!     sl.buf = malloc(MAXSOCKSENDBUF);
  
      sprintf(sl.buf,"replyinfo image_info\n%d\n%d\n", nrofpixmaps-1, bmaps_checksum);
      for (i=0; i<MAX_FACE_SETS; i++) {
  	if (facesets[i].prefix) {
  	    sprintf(sl.buf + strlen(sl.buf), "%d:%s:%s:%d:%s:%s:%s",
***************
*** 417,427 ****
      short i;
      char qq;
      char *cp, buf[MAX_BUF];
      SockList sl;
  
!     sl.buf = malloc(MAXSOCKBUF);
  
      start = atoi(params);
      for (cp = params; *cp != '\0'; cp++)
  	if (*cp == ' ') break;
  
--- 417,427 ----
      short i;
      char qq;
      char *cp, buf[MAX_BUF];
      SockList sl;
  
!     sl.buf = malloc(MAXSOCKSENDBUF);
  
      start = atoi(params);
      for (cp = params; *cp != '\0'; cp++)
  	if (*cp == ' ') break;
  
***************
*** 434,443 ****
--- 434,450 ----
      sprintf(sl.buf,"replyinfo image_sums %d %d ", start, stop);
  
      sl.len = strlen(sl.buf);
  
      for (i=start; i<=stop; i++) {
+ 	if (sl.len+2+4+1+1+strlen(new_faces[i].name)+1 > MAXSOCKSENDBUF) {
+ 	    LOG(llevError, "send_image_sums: buffer overflow, rejecting range %d..%d\n", start, stop);
+ 	    sprintf(buf, "replyinfo image_sums %d %d", start, stop);
+ 	    cs_write_string(ns, buf, strlen(buf));
+ 	    return;
+ 	}
+ 
  	SockList_AddShort(&sl, i);
  	ns->faces_sent[i] |= NS_FACESENT_FACE;
  
  	qq = get_face_fallback(ns->faceset, i);
  	SockList_AddInt(&sl, facesets[qq].faces[i].checksum);
***************
*** 447,463 ****
  	SockList_AddChar(&sl, ( char )( qq + 1 ));
  	strcpy(sl.buf + sl.len, new_faces[i].name);
  	sl.len += qq;
  	SockList_AddChar(&sl, 0);
      }
-     /* It would make more sense to catch this pre-emptively in the code above.
-      * however, if this really happens, we probably just want to cut down the
-      * size to less than 1000, since that is what we claim the protocol would
-      * support.
-      */
-     if (sl.len > MAXSOCKBUF) {
- 	LOG(llevError,"send_image_send: buffer overrun, %d > %d\n", sl.len, MAXSOCKBUF);
- 	abort();
-     }
      Send_With_Handling(ns, &sl);
      free(sl.buf);
  }
--- 454,461 ----
Index: socket/info.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/socket/info.c,v
retrieving revision 1.27
diff -c -5 -r1.27 info.c
*** socket/info.c	5 May 2006 09:41:15 -0000	1.27
--- socket/info.c	14 May 2006 13:05:03 -0000
***************
*** 588,599 ****
  		ymax = y > ymax ? y : ymax;
  	    }
  	}
      }
  
!     sl.buf=malloc(MAXSOCKBUF);
!     snprintf((char*)sl.buf, MAXSOCKBUF, "magicmap %d %d %d %d ", (xmax-xmin+1), (ymax-ymin+1),
  	    MAGIC_MAP_HALF - xmin, MAGIC_MAP_HALF - ymin);
      sl.len=strlen((char*)sl.buf);
      
      for (y = ymin; y <= ymax; y++) {
  	for (x = xmin; x <= xmax; x++) {
--- 588,599 ----
  		ymax = y > ymax ? y : ymax;
  	    }
  	}
      }
  
!     sl.buf=malloc(MAXSOCKSENDBUF);
!     snprintf((char*)sl.buf, MAXSOCKSENDBUF, "magicmap %d %d %d %d ", (xmax-xmin+1), (ymax-ymin+1),
  	    MAGIC_MAP_HALF - xmin, MAGIC_MAP_HALF - ymin);
      sl.len=strlen((char*)sl.buf);
      
      for (y = ymin; y <= ymax; y++) {
  	for (x = xmin; x <= xmax; x++) {
Index: socket/init.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/socket/init.c,v
retrieving revision 1.48
diff -c -5 -r1.48 init.c
*** socket/init.c	18 Mar 2006 15:05:37 -0000	1.48
--- socket/init.c	14 May 2006 13:05:03 -0000
***************
*** 129,144 ****
       * we need to do something more intelligent, because client id's will start
       * duplicating (not likely in normal cases, but malicous attacks that
       * just open and close connections could get this total up.
       */
      ns->inbuf.len=0;
!     ns->inbuf.buf=malloc( sizeof( unsigned char ) * MAXSOCKBUF );
      /* Basic initialization. Needed because we do a check in
       * handle_client for oldsocketmode without checking the
       * length of data.
       */
!     memset( ns->inbuf.buf, 0, sizeof( unsigned char ) * MAXSOCKBUF );
      memset(&ns->lastmap,0,sizeof(struct Map));
      memset(ns->faces_sent, 0, ns->faces_sent_len*sizeof(*ns->faces_sent));
      memset(&ns->anims_sent,0,sizeof(ns->anims_sent));
      memset(&ns->stats,0,sizeof(struct statsinfo));
      /* Do this so we don't send a face command for the client for
--- 129,144 ----
       * we need to do something more intelligent, because client id's will start
       * duplicating (not likely in normal cases, but malicous attacks that
       * just open and close connections could get this total up.
       */
      ns->inbuf.len=0;
!     ns->inbuf.buf=malloc(MAXSOCKRECVBUF);
      /* Basic initialization. Needed because we do a check in
       * handle_client for oldsocketmode without checking the
       * length of data.
       */
!     memset(ns->inbuf.buf, 0, MAXSOCKRECVBUF);
      memset(&ns->lastmap,0,sizeof(struct Map));
      memset(ns->faces_sent, 0, ns->faces_sent_len*sizeof(*ns->faces_sent));
      memset(&ns->anims_sent,0,sizeof(ns->anims_sent));
      memset(&ns->stats,0,sizeof(struct statsinfo));
      /* Do this so we don't send a face command for the client for
Index: socket/item.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/socket/item.c,v
retrieving revision 1.39
diff -c -5 -r1.39 item.c
*** socket/item.c	5 May 2006 09:41:15 -0000	1.39
--- socket/item.c	14 May 2006 13:05:03 -0000
***************
*** 225,235 ****
      if (pl->contr->transport)
  	for (tmp=pl->contr->transport->inv; tmp && tmp->above;tmp=tmp->above) ;
      else
  	for (tmp=get_map_ob(pl->map,pl->x,pl->y); tmp && tmp->above;tmp=tmp->above) ;
  
!     sl.buf=malloc(MAXSOCKBUF);
  
      Write_String_To_Socket(&pl->contr->socket, "delinv 0", strlen("delinv 0"));
      sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd);
      sl.len=strlen((char*)sl.buf);
  
--- 225,235 ----
      if (pl->contr->transport)
  	for (tmp=pl->contr->transport->inv; tmp && tmp->above;tmp=tmp->above) ;
      else
  	for (tmp=get_map_ob(pl->map,pl->x,pl->y); tmp && tmp->above;tmp=tmp->above) ;
  
!     sl.buf=malloc(MAXSOCKSENDBUF);
  
      Write_String_To_Socket(&pl->contr->socket, "delinv 0", strlen("delinv 0"));
      sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd);
      sl.len=strlen((char*)sl.buf);
  
***************
*** 289,299 ****
  	    else head = tmp;
  
  	    add_object_to_socklist(&pl->contr->socket, &sl, head);
  	    got_one++;
  
! 	    if (sl.len > (MAXSOCKBUF-MAXITEMLEN)) {
  		Send_With_Handling(&pl->contr->socket, &sl);
  		sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd);
  		sl.len=strlen((char*)sl.buf);
  		SockList_AddInt(&sl, 0);
  		got_one=0;
--- 289,299 ----
  	    else head = tmp;
  
  	    add_object_to_socklist(&pl->contr->socket, &sl, head);
  	    got_one++;
  
! 	    if (sl.len > (MAXSOCKSENDBUF-MAXITEMLEN)) {
  		Send_With_Handling(&pl->contr->socket, &sl);
  		sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd);
  		sl.len=strlen((char*)sl.buf);
  		SockList_AddInt(&sl, 0);
  		got_one=0;
***************
*** 313,323 ****
  {
      object *tmp;
      int got_one=0;
      SockList sl;
      
!     sl.buf=malloc(MAXSOCKBUF);
  
      sprintf((char*)sl.buf,"delinv %d", op->count);
      sl.len=strlen((char*)sl.buf);
      Send_With_Handling(&pl->contr->socket, &sl);
  
--- 313,323 ----
  {
      object *tmp;
      int got_one=0;
      SockList sl;
      
!     sl.buf=malloc(MAXSOCKSENDBUF);
  
      sprintf((char*)sl.buf,"delinv %d", op->count);
      sl.len=strlen((char*)sl.buf);
      Send_With_Handling(&pl->contr->socket, &sl);
  
***************
*** 339,349 ****
  
  	    /* IT is possible for players to accumulate a huge amount of
  	     * items (especially with some of the bags out there) to
  	     * overflow the buffer.  IF so, send multiple item commands.
  	     */
! 	    if (sl.len > (MAXSOCKBUF-MAXITEMLEN)) {
  		Send_With_Handling(&pl->contr->socket, &sl);
  		sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd);
  		sl.len=strlen((char*)sl.buf);
  		SockList_AddInt(&sl, op->count);
  		got_one=0;
--- 339,349 ----
  
  	    /* IT is possible for players to accumulate a huge amount of
  	     * items (especially with some of the bags out there) to
  	     * overflow the buffer.  IF so, send multiple item commands.
  	     */
! 	    if (sl.len > (MAXSOCKSENDBUF-MAXITEMLEN)) {
  		Send_With_Handling(&pl->contr->socket, &sl);
  		sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd);
  		sl.len=strlen((char*)sl.buf);
  		SockList_AddInt(&sl, op->count);
  		got_one=0;
***************
*** 381,391 ****
  	 * this is happening - we can set a breakpoint here in the debugger
  	 * and track back the call.
  	 */
  	LOG(llevDebug,"We have not sent item %s (%d)\n", op->name, op->count);
      }
!     sl.buf=malloc(MAXSOCKBUF);
  
      strcpy((char*)sl.buf,"upditem ");
      sl.len=strlen((char*)sl.buf);
  
      SockList_AddChar(&sl, (char) flags);
--- 381,391 ----
  	 * this is happening - we can set a breakpoint here in the debugger
  	 * and track back the call.
  	 */
  	LOG(llevDebug,"We have not sent item %s (%d)\n", op->name, op->count);
      }
!     sl.buf=malloc(MAXSOCKSENDBUF);
  
      strcpy((char*)sl.buf,"upditem ");
      sl.len=strlen((char*)sl.buf);
  
      SockList_AddChar(&sl, (char) flags);
***************
*** 486,496 ****
  	    pl->contr->socket.update_look=1;
  	    return;
  	}
      }
  
!     sl.buf=malloc(MAXSOCKBUF);
  
      sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd);
      sl.len=strlen((char*)sl.buf);
  
      if (op->head) op=op->head;
--- 486,496 ----
  	    pl->contr->socket.update_look=1;
  	    return;
  	}
      }
  
!     sl.buf=malloc(MAXSOCKSENDBUF);
  
      sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd);
      sl.len=strlen((char*)sl.buf);
  
      if (op->head) op=op->head;
***************
*** 511,521 ****
  
  void esrv_del_item(player *pl, int tag)
  {
      SockList sl;
  
!     sl.buf=malloc(MAXSOCKBUF);
  
      strcpy((char*)sl.buf,"delitem ");
      sl.len=strlen((char*)sl.buf);
      SockList_AddInt(&sl, tag);
  
--- 511,521 ----
  
  void esrv_del_item(player *pl, int tag)
  {
      SockList sl;
  
!     sl.buf=malloc(MAXSOCKSENDBUF);
  
      strcpy((char*)sl.buf,"delitem ");
      sl.len=strlen((char*)sl.buf);
      SockList_AddInt(&sl, tag);
  
Index: socket/loop.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/socket/loop.c,v
retrieving revision 1.43
diff -c -5 -r1.43 loop.c
*** socket/loop.c	19 Mar 2006 01:51:46 -0000	1.43
--- socket/loop.c	14 May 2006 13:05:03 -0000
***************
*** 183,193 ****
      /* This is not the most efficient block, but keeps the code simpler -
       * we basically read a byte at a time until we get a newline, error,
       * or no more characters to read.
       */
      do {
! 	if (ns->inbuf.len >= MAXSOCKBUF-1) {
  	    ns->status = Ns_Dead;
  	    LOG(llevDebug, "Old input socket sent too much data without newline\n");
  	    return;
  	}
  #ifdef WIN32 /* ***win32: change oldsocket read() to recv() */
--- 183,193 ----
      /* This is not the most efficient block, but keeps the code simpler -
       * we basically read a byte at a time until we get a newline, error,
       * or no more characters to read.
       */
      do {
! 	if (ns->inbuf.len >= MAXSOCKRECVBUF-1) {
  	    ns->status = Ns_Dead;
  	    LOG(llevDebug, "Old input socket sent too much data without newline\n");
  	    return;
  	}
  #ifdef WIN32 /* ***win32: change oldsocket read() to recv() */
***************
*** 339,349 ****
  	    
  	if (ns->status == Ns_Old) {
  	    handle_oldsocket(ns);
  	    return;
  	}
! 	i=SockList_ReadPacket(ns->fd, &ns->inbuf, MAXSOCKBUF-1);
  	/* Special hack - let the user switch to old mode if in the Ns_Add
  	 * phase.  Don't demand they add in the special length bytes
  	 */
  	if (ns->status == Ns_Add) {
  	    if (!strncasecmp(ns->inbuf.buf,"oldsocketmode", 13)) {
--- 339,349 ----
  	    
  	if (ns->status == Ns_Old) {
  	    handle_oldsocket(ns);
  	    return;
  	}
! 	i=SockList_ReadPacket(ns->fd, &ns->inbuf, MAXSOCKRECVBUF-1);
  	/* Special hack - let the user switch to old mode if in the Ns_Add
  	 * phase.  Don't demand they add in the special length bytes
  	 */
  	if (ns->status == Ns_Add) {
  	    if (!strncasecmp(ns->inbuf.buf,"oldsocketmode", 13)) {
***************
*** 364,373 ****
--- 364,375 ----
  	    return;
  	}
  	/* Still dont have a full packet */
  	if (i==0) return;
  
+ 	ns->inbuf.buf[ns->inbuf.len]='\0';  /* Terminate buffer - useful for string data */
+ 
  	/* First, break out beginning word.  There are at least
  	 * a few commands that do not have any paremeters.  If
  	 * we get such a command, don't worry about trying
  	 * to break it up.
  	 */
***************
*** 377,387 ****
  	    data++;
  	    len = ns->inbuf.len - (data - ns->inbuf.buf);
  	}
  	else len=0;
  
- 	ns->inbuf.buf[ns->inbuf.len]='\0';  /* Terminate buffer - useful for string data */
  	for (i=0; client_commands[i].cmdname !=NULL; i++) {
  	    if (strcmp((char*)ns->inbuf.buf+2,client_commands[i].cmdname)==0) {
  		client_commands[i].cmdproc((char*)data,len,ns);
  		ns->inbuf.len=0;
  		return;
--- 379,388 ----
Index: socket/lowlevel.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/socket/lowlevel.c,v
retrieving revision 1.15
diff -c -5 -r1.15 lowlevel.c
*** socket/lowlevel.c	13 May 2006 21:21:12 -0000	1.15
--- socket/lowlevel.c	14 May 2006 13:05:03 -0000
***************
*** 107,120 ****
   *
   ******************************************************************************/
  
  /**
   * This reads from fd and puts the data in sl.  We return true if we think
!  * we have a full packet, 0 if we have a partial packet.  The only processing
!  * we do is remove the intial size value.  len (As passed) is the size of the
!  * buffer allocated in the socklist.  We make the assumption the buffer is
!  * at least 2 bytes long.
   */
   
  int SockList_ReadPacket(int fd, SockList *sl, int len)
  {
      int stat,toread;
--- 107,120 ----
   *
   ******************************************************************************/
  
  /**
   * This reads from fd and puts the data in sl.  We return true if we think
!  * we have a full packet, 0 if we have a partial packet, or -1 if an error
!  * occurred.  The only processing we do is remove the initial size value.  len
!  * (As passed) is the size of the buffer allocated in the socklist.  We make
!  * the assumption the buffer is at least 2 bytes long.
   */
   
  int SockList_ReadPacket(int fd, SockList *sl, int len)
  {
      int stat,toread;
***************
*** 422,439 ****
   * The only difference in this function is that we take a SockList
   *, and we prepend the length information.
   */
  void Send_With_Handling(socket_struct *ns, const SockList *msg)
  {
!     unsigned char sbuf[4];
  
      if (ns->status == Ns_Dead || !msg)
  	return;
  
!     if (msg->len > MAXSOCKBUF) {
! 	LOG(llevError,"Trying to send a buffer beyond properly size, len =%d\n",
! 	    msg->len);
  	/* Almost certainly we've overflowed a buffer, so quite now to make
  	 * it easier to debug.
  	 */
  	abort();
      }
--- 422,439 ----
   * The only difference in this function is that we take a SockList
   *, and we prepend the length information.
   */
  void Send_With_Handling(socket_struct *ns, const SockList *msg)
  {
!     unsigned char sbuf[2];
  
      if (ns->status == Ns_Dead || !msg)
  	return;
  
!     if (msg->len > MAXSOCKSENDBUF) {
! 	LOG(llevError,"Trying to send a buffer beyond properly size, len %d > max len %d\n",
! 	    msg->len, MAXSOCKSENDBUF);
  	/* Almost certainly we've overflowed a buffer, so quite now to make
  	 * it easier to debug.
  	 */
  	abort();
      }
Index: socket/request.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/socket/request.c,v
retrieving revision 1.89
diff -c -5 -r1.89 request.c
*** socket/request.c	13 May 2006 21:21:12 -0000	1.89
--- socket/request.c	14 May 2006 13:05:03 -0000
***************
*** 768,778 ****
  {
      SockList sl;
      char buf[MAX_BUF];
      uint16 flags;
  
!     sl.buf=malloc(MAXSOCKBUF);
      strcpy((char*)sl.buf,"stats ");
      sl.len=strlen((char*)sl.buf);
      
      if(pl->ob != NULL)
      {
--- 768,778 ----
  {
      SockList sl;
      char buf[MAX_BUF];
      uint16 flags;
  
!     sl.buf=malloc(MAXSOCKSENDBUF);
      strcpy((char*)sl.buf,"stats ");
      sl.len=strlen((char*)sl.buf);
      
      if(pl->ob != NULL)
      {
***************
*** 863,873 ****
  {
      SockList	sl;
  
      pl->last_weight = weight;
  
!     sl.buf=malloc(MAXSOCKBUF);
  
      strcpy((char*)sl.buf,"player ");
      sl.len=strlen((char*)sl.buf);
      SockList_AddInt(&sl, pl->ob->count);
      SockList_AddInt(&sl, weight);
--- 863,873 ----
  {
      SockList	sl;
  
      pl->last_weight = weight;
  
!     sl.buf=malloc(MAXSOCKSENDBUF);
  
      strcpy((char*)sl.buf,"player ");
      sl.len=strlen((char*)sl.buf);
      SockList_AddInt(&sl, pl->ob->count);
      SockList_AddInt(&sl, weight);
***************
*** 902,912 ****
      if (anim_num < 0 || anim_num > num_animations) {
  	LOG(llevError,"esrv_send_anim (%d) out of bounds??\n",anim_num);
  	return;
      }
  
!     sl.buf = malloc(MAXSOCKBUF);
      strcpy((char*)sl.buf, "anim ");
      sl.len=5;
      SockList_AddShort(&sl, anim_num);
      SockList_AddShort(&sl, 0);  /* flags - not used right now */
      /* Build up the list of faces.  Also, send any information (ie, the
--- 902,912 ----
      if (anim_num < 0 || anim_num > num_animations) {
  	LOG(llevError,"esrv_send_anim (%d) out of bounds??\n",anim_num);
  	return;
      }
  
!     sl.buf = malloc(MAXSOCKSENDBUF);
      strcpy((char*)sl.buf, "anim ");
      sl.len=5;
      SockList_AddShort(&sl, anim_num);
      SockList_AddShort(&sl, 0);  /* flags - not used right now */
      /* Build up the list of faces.  Also, send any information (ie, the
***************
*** 1049,1059 ****
      static long frames,bytes,tbytes,tframes;
      uint8 *cur;
      SockList sl;
  
  
!     sl.buf=malloc(MAXSOCKBUF);
      strcpy((char*)sl.buf,"map ");
      sl.len=strlen((char*)sl.buf);
  
      cur = compactlayer(ns,sl.buf+sl.len,MAP_LAYERS,newmap);
      sl.len=cur-sl.buf;
--- 1049,1059 ----
      static long frames,bytes,tbytes,tframes;
      uint8 *cur;
      SockList sl;
  
  
!     sl.buf=malloc(MAXSOCKSENDBUF);
      strcpy((char*)sl.buf,"map ");
      sl.len=strlen((char*)sl.buf);
  
      cur = compactlayer(ns,sl.buf+sl.len,MAP_LAYERS,newmap);
      sl.len=cur-sl.buf;
***************
*** 1437,1456 ****
      uint8 eentrysize;
      uint16  ewhatstart,ewhatflag;
      uint8   extendedinfos;
      mapstruct *m;
  
!     sl.buf=malloc(MAXSOCKBUF);
      if (pl->contr->socket.mapmode == Map1Cmd)
  	strcpy((char*)sl.buf,"map1 ");
      else
  	strcpy((char*)sl.buf,"map1a ");
      sl.len=strlen((char*)sl.buf);
      startlen = sl.len;
      /*Extendedmapinfo structure initialisation*/
      if (pl->contr->socket.ext_mapinfos){
!         esl.buf=malloc(MAXSOCKBUF);
          strcpy((char*)esl.buf,"mapextended ");
          esl.len=strlen((char*)esl.buf);
          extendedinfos=EMI_NOREDRAW;
          if (pl->contr->socket.EMI_smooth)
              extendedinfos|=EMI_SMOOTH;
--- 1437,1456 ----
      uint8 eentrysize;
      uint16  ewhatstart,ewhatflag;
      uint8   extendedinfos;
      mapstruct *m;
  
!     sl.buf=malloc(MAXSOCKSENDBUF);
      if (pl->contr->socket.mapmode == Map1Cmd)
  	strcpy((char*)sl.buf,"map1 ");
      else
  	strcpy((char*)sl.buf,"map1a ");
      sl.len=strlen((char*)sl.buf);
      startlen = sl.len;
      /*Extendedmapinfo structure initialisation*/
      if (pl->contr->socket.ext_mapinfos){
!         esl.buf=malloc(MAXSOCKSENDBUF);
          strcpy((char*)esl.buf,"mapextended ");
          esl.len=strlen((char*)esl.buf);
          extendedinfos=EMI_NOREDRAW;
          if (pl->contr->socket.EMI_smooth)
              extendedinfos|=EMI_SMOOTH;
***************
*** 1855,1865 ****
  
  void esrv_map_scroll(socket_struct *ns,int dx,int dy)
  {
      struct Map newmap;
      int x,y, mx, my;
!     char buf[MAXSOCKBUF];
  
      sprintf(buf,"map_scroll %d %d", dx, dy);
      Write_String_To_Socket(ns, buf, strlen(buf));
  
      /* If we are using the Map1aCmd, we may in fact send
--- 1855,1865 ----
  
  void esrv_map_scroll(socket_struct *ns,int dx,int dy)
  {
      struct Map newmap;
      int x,y, mx, my;
!     char buf[MAXSOCKSENDBUF];
  
      sprintf(buf,"map_scroll %d %d", dx, dy);
      Write_String_To_Socket(ns, buf, strlen(buf));
  
      /* If we are using the Map1aCmd, we may in fact send
***************
*** 1925,1944 ****
  void send_skill_info(socket_struct *ns, char *params)
  {
      SockList sl;
      int i;
  
!     sl.buf = malloc(MAXSOCKBUF);
      strcpy((char*)sl.buf,"replyinfo skill_info\n");
-     for (i=1; i< NUM_SKILLS; i++) {
- 	sprintf((char*)sl.buf + strlen((char*)sl.buf), "%d:%s\n", i + CS_STAT_SKILLINFO,
- 		skill_names[i]);
-     }
      sl.len = strlen((char*)sl.buf);
!     if (sl.len > MAXSOCKBUF) {
! 	LOG(llevError,"Buffer overflow in send_skill_info!\n");
! 	fatal(0);
      }
      Send_With_Handling(ns, &sl);
      free(sl.buf);
  }
  
--- 1925,1948 ----
  void send_skill_info(socket_struct *ns, char *params)
  {
      SockList sl;
      int i;
  
!     sl.buf = malloc(MAXSOCKSENDBUF);
      strcpy((char*)sl.buf,"replyinfo skill_info\n");
      sl.len = strlen((char*)sl.buf);
!     for (i=1; i< NUM_SKILLS; i++) {
! 	int len;
! 
! 	len = 16+strlen(skill_names[i]); /* upper bound for length */
! 	if (sl.len+len > MAXSOCKSENDBUF) {
! 	    LOG(llevError, "Buffer overflow in send_skill_info, not sending all skill information\n");
! 	    break;
! 	}
! 
! 	sprintf((char*)sl.buf+sl.len, "%d:%s\n", i+CS_STAT_SKILLINFO, skill_names[i]);
! 	sl.len += strlen((char*)sl.buf+sl.len);
      }
      Send_With_Handling(ns, &sl);
      free(sl.buf);
  }
  
***************
*** 1948,1965 ****
   */
  void send_spell_paths (socket_struct *ns, char *params) {
      SockList sl;
      int i;
  
!     sl.buf = malloc(MAXSOCKBUF);
      strcpy((char*)sl.buf,"replyinfo spell_paths\n");
-     for(i=0; i<NRSPELLPATHS; i++)
- 	sprintf((char*)sl.buf + strlen((char*)sl.buf), "%d:%s\n", 1<<i, spellpathnames[i]);
      sl.len = strlen((char*)sl.buf);
!     if (sl.len > MAXSOCKBUF) {
! 	LOG(llevError,"Buffer overflow in send_spell_paths!\n");
! 	fatal(0);
      }
      Send_With_Handling(ns, &sl);
      free(sl.buf);
  }
  
--- 1952,1975 ----
   */
  void send_spell_paths (socket_struct *ns, char *params) {
      SockList sl;
      int i;
  
!     sl.buf = malloc(MAXSOCKSENDBUF);
      strcpy((char*)sl.buf,"replyinfo spell_paths\n");
      sl.len = strlen((char*)sl.buf);
!     for(i=0; i<NRSPELLPATHS; i++) {
! 	int len;
! 
! 	len = 16+strlen(spellpathnames[i]); /* upper bound for length */
! 	if (sl.len+len > MAXSOCKSENDBUF) {
! 	    LOG(llevError, "Buffer overflow in send_spell_paths, not sending all spell information\n");
! 	    break;
! 	}
! 
! 	sprintf((char*)sl.buf+sl.len, "%d:%s\n", 1<<i, spellpathnames[i]);
! 	sl.len += strlen((char*)sl.buf+sl.len);
      }
      Send_With_Handling(ns, &sl);
      free(sl.buf);
  }
  
***************
*** 1986,1996 ****
  	    if (spell->last_eat != spell->stats.dam+SP_level_dam_adjust(pl->ob, spell)) {
  		spell->last_eat = spell->stats.dam+SP_level_dam_adjust(pl->ob, spell);
  		flags |= UPD_SP_DAMAGE;
  	    }
  	    if (flags !=0) {
! 		sl.buf = malloc(MAXSOCKBUF);
  		strcpy((char*)sl.buf,"updspell ");
  		sl.len=strlen((char*)sl.buf);
  		SockList_AddChar(&sl, flags);
  		SockList_AddInt(&sl, spell->count);
  		if (flags & UPD_SP_MANA) SockList_AddShort(&sl, spell->last_sp);
--- 1996,2006 ----
  	    if (spell->last_eat != spell->stats.dam+SP_level_dam_adjust(pl->ob, spell)) {
  		spell->last_eat = spell->stats.dam+SP_level_dam_adjust(pl->ob, spell);
  		flags |= UPD_SP_DAMAGE;
  	    }
  	    if (flags !=0) {
! 		sl.buf = malloc(MAXSOCKSENDBUF);
  		strcpy((char*)sl.buf,"updspell ");
  		sl.len=strlen((char*)sl.buf);
  		SockList_AddChar(&sl, flags);
  		SockList_AddInt(&sl, spell->count);
  		if (flags & UPD_SP_MANA) SockList_AddShort(&sl, spell->last_sp);
***************
*** 2010,2020 ****
      if (!pl->socket.monitor_spells) return;
      if (!pl || !spell || spell->env != pl->ob) {
  	LOG(llevError, "Invalid call to esrv_remove_spell");
  	return;
      }
!     sl.buf = malloc(MAXSOCKBUF);
      strcpy((char*)sl.buf,"delspell ");
      sl.len=strlen((char*)sl.buf);
      SockList_AddInt(&sl, spell->count);
      Send_With_Handling(&pl->socket, &sl);
      free(sl.buf);
--- 2020,2030 ----
      if (!pl->socket.monitor_spells) return;
      if (!pl || !spell || spell->env != pl->ob) {
  	LOG(llevError, "Invalid call to esrv_remove_spell");
  	return;
      }
!     sl.buf = malloc(MAXSOCKSENDBUF);
      strcpy((char*)sl.buf,"delspell ");
      sl.len=strlen((char*)sl.buf);
      SockList_AddInt(&sl, spell->count);
      Send_With_Handling(&pl->socket, &sl);
      free(sl.buf);
***************
*** 2078,2102 ****
      if (!pl) {
  	LOG(llevError, "esrv_add_spells, tried to add a spell to a NULL player");
  	return;
      }
      if (!pl->socket.monitor_spells) return;
!     sl.buf = malloc(MAXSOCKBUF);
      strcpy((char*)sl.buf,"addspell ");
      sl.len=strlen((char*)sl.buf);
      if (!spell) {
  	for (spell=pl->ob->inv; spell!=NULL; spell=spell->below) {
  	    if (spell->type != SPELL) continue;
  	    /* were we to simply keep appending data here, we could exceed 
! 	     * MAXSOCKBUF if the player has enough spells to add, we know that
  	     * append_spell will always append 23 data bytes, plus 3 length
  	     * bytes and 2 strings (because that is the spec) so we need to
  	     * check that the length of those 2 strings, plus the 26 bytes, 
  	     * won't take us over the length limit for the socket, if it does,
  	     * we need to send what we already have, and restart packet formation 
  	     */
! 	    if (sl.len > (MAXSOCKBUF - (26 + strlen(spell->name) + 
  				(spell->msg?strlen(spell->msg):0)))) {
  		Send_With_Handling(&pl->socket, &sl);
  		strcpy((char*)sl.buf,"addspell ");
  		sl.len=strlen((char*)sl.buf);
  	    }
--- 2088,2112 ----
      if (!pl) {
  	LOG(llevError, "esrv_add_spells, tried to add a spell to a NULL player");
  	return;
      }
      if (!pl->socket.monitor_spells) return;
!     sl.buf = malloc(MAXSOCKSENDBUF);
      strcpy((char*)sl.buf,"addspell ");
      sl.len=strlen((char*)sl.buf);
      if (!spell) {
  	for (spell=pl->ob->inv; spell!=NULL; spell=spell->below) {
  	    if (spell->type != SPELL) continue;
  	    /* were we to simply keep appending data here, we could exceed 
! 	     * MAXSOCKSENDBUF if the player has enough spells to add, we know that
  	     * append_spell will always append 23 data bytes, plus 3 length
  	     * bytes and 2 strings (because that is the spec) so we need to
  	     * check that the length of those 2 strings, plus the 26 bytes, 
  	     * won't take us over the length limit for the socket, if it does,
  	     * we need to send what we already have, and restart packet formation 
  	     */
! 	    if (sl.len > (MAXSOCKSENDBUF - (26 + strlen(spell->name) + 
  				(spell->msg?strlen(spell->msg):0)))) {
  		Send_With_Handling(&pl->socket, &sl);
  		strcpy((char*)sl.buf,"addspell ");
  		sl.len=strlen((char*)sl.buf);
  	    }
***************
*** 2106,2116 ****
      else if (spell->type != SPELL) {
  	LOG(llevError, "Asked to send a non-spell object as a spell");
  	return;
      }
      else append_spell(pl, &sl, spell);
!     if (sl.len > MAXSOCKBUF) {
  	LOG(llevError,"Buffer overflow in esrv_add_spells!\n");
  	fatal(0);
      }
      /* finally, we can send the packet */
      Send_With_Handling(&pl->socket, &sl);
--- 2116,2126 ----
      else if (spell->type != SPELL) {
  	LOG(llevError, "Asked to send a non-spell object as a spell");
  	return;
      }
      else append_spell(pl, &sl, spell);
!     if (sl.len > MAXSOCKSENDBUF) {
  	LOG(llevError,"Buffer overflow in esrv_add_spells!\n");
  	fatal(0);
      }
      /* finally, we can send the packet */
      Send_With_Handling(&pl->socket, &sl);
Index: socket/sounds.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/socket/sounds.c,v
retrieving revision 1.6
diff -c -5 -r1.6 sounds.c
*** socket/sounds.c	5 May 2006 09:41:15 -0000	1.6
--- socket/sounds.c	14 May 2006 13:05:03 -0000
***************
*** 37,47 ****
  	soundtype=SOUND_SPELL;
  	soundnum -=SOUND_CAST_SPELL_0;
      }
      else soundtype=SOUND_NORMAL;
  
!     sl.buf=malloc(MAXSOCKBUF);
      strcpy((char*)sl.buf, "sound ");
      sl.len=strlen((char*)sl.buf);
      SockList_AddChar(&sl, x);
      SockList_AddChar(&sl, y);
      SockList_AddShort(&sl, soundnum);
--- 37,47 ----
  	soundtype=SOUND_SPELL;
  	soundnum -=SOUND_CAST_SPELL_0;
      }
      else soundtype=SOUND_NORMAL;
  
!     sl.buf=malloc(MAXSOCKSENDBUF);
      strcpy((char*)sl.buf, "sound ");
      sl.len=strlen((char*)sl.buf);
      SockList_AddChar(&sl, x);
      SockList_AddChar(&sl, y);
      SockList_AddShort(&sl, soundnum);