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 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 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 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<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);