Text   |  XML   |  ReML   |   Visible Warnings:

Overlapping Memory Regions  at reassemble.c:835

No properties have been set. | edit properties
Jump to warning location ↓ warning details...
Show Events | Options

fragment_add_work

(/home/sate/Testcases/c/cve/wireshark-1.2.0/epan/reassemble.c)expand/collapse
Show more  
 641  fragment_add_work(fragment_data *fd_head, tvbuff_t *tvb, int offset,
 642               packet_info *pinfo, guint32 frag_offset,
 643               guint32 frag_data_len, gboolean more_frags)
 644  {
 645          fragment_data *fd;
 646          fragment_data *fd_i;
 647          guint32 max, dfpos;
 648          unsigned char *old_data;
 649   
 650          /* create new fd describing this fragment */
 651          fd = g_mem_chunk_alloc(fragment_data_chunk);
 652          fd->next = NULL;
 653          fd->flags = 0;
 654          fd->frame = pinfo->fd->num;
 655          if (fd->frame > fd_head->frame)
 656              fd_head->frame = fd->frame;
 657          fd->offset = frag_offset;
 658          fd->len  = frag_data_len;
 659          fd->data = NULL;
 660   
 661          /*
 662           * If it was already defragmented and this new fragment goes beyond 
 663           * data limits, set flag in already empty fds & point old fds to malloc'ed data.
 664           */
 665          if(fd_head->flags & FD_DEFRAGMENTED && (frag_offset+frag_data_len) >= fd_head->datalen &&
 666                  fd_head->flags & FD_PARTIAL_REASSEMBLY){
 667                  for(fd_i=fd_head->next; fd_i; fd_i=fd_i->next){
 668                          if( !fd_i->data ) {
 669                                  fd_i->data = fd_head->data + fd_i->offset;
 670                                  fd_i->flags |= FD_NOT_MALLOCED;
 671                          }
 672                          fd_i->flags &= (~FD_TOOLONGFRAGMENT) & (~FD_MULTIPLETAILS);
 673                  }
 674                  fd_head->flags &= ~(FD_DEFRAGMENTED|FD_PARTIAL_REASSEMBLY|FD_DATALEN_SET);
 675                  fd_head->flags &= (~FD_TOOLONGFRAGMENT) & (~FD_MULTIPLETAILS);
 676                  fd_head->datalen=0;
 677                  fd_head->reassembled_in=0;
 678          }
 679   
 680          if (!more_frags) {
 681                  /*
 682                   * This is the tail fragment in the sequence.
 683                   */
 684                  if (fd_head->flags & FD_DATALEN_SET) {
 685                          /* ok we have already seen other tails for this packet
 686                           * it might be a duplicate.
 687                           */
 688                          if (fd_head->datalen != (fd->offset + fd->len) ){
 689                                  /* Oops, this tail indicates a different packet
 690                                   * len than the previous ones. Something's wrong.
 691                                   */
 692                                  fd->flags      |= FD_MULTIPLETAILS;
 693                                  fd_head->flags |= FD_MULTIPLETAILS;
 694                          }
 695                  } else {
 696                          /* this was the first tail fragment, now we know the
 697                           * length of the packet
 698                           */
 699                          fd_head->datalen = fd->offset + fd->len;
 700                          fd_head->flags |= FD_DATALEN_SET;
 701                  }
 702          }
 703   
 704   
 705   
 706   
 707          /* If the packet is already defragmented, this MUST be an overlap.
 708           * The entire defragmented packet is in fd_head->data.
 709           * Even if we have previously defragmented this packet, we still
 710           * check it. Someone might play overlap and TTL games.
 711           */
 712          if (fd_head->flags & FD_DEFRAGMENTED) {
 713                  fd->flags      |= FD_OVERLAP;
 714                  fd_head->flags |= FD_OVERLAP;
 715                  /* make sure it's not too long */
 716                  if (fd->offset + fd->len > fd_head->datalen) {
 717                          fd->flags      |= FD_TOOLONGFRAGMENT;
 718                          fd_head->flags |= FD_TOOLONGFRAGMENT;
 719                  }
 720                  /* make sure it doesn't conflict with previous data */
 721                  else if ( memcmp(fd_head->data+fd->offset,
 722                          tvb_get_ptr(tvb,offset,fd->len),fd->len) ){
 723                          fd->flags      |= FD_OVERLAPCONFLICT;
 724                          fd_head->flags |= FD_OVERLAPCONFLICT;
 725                  }
 726                  /* it was just an overlap, link it and return */
 727                  LINK_FRAG(fd_head,fd);
 728                  return TRUE;
 729          }
 730   
 731   
 732   
 733          /* If we have reached this point, the packet is not defragmented yet.
 734           * Save all payload in a buffer until we can defragment.
 735           * XXX - what if we didn't capture the entire fragment due 
 736           * to a too-short snapshot length?
 737           */
 738          fd->data = g_malloc(fd->len);
 739          tvb_memcpy(tvb, fd->data, offset, fd->len);
 740          LINK_FRAG(fd_head,fd);
 741   
 742   
 743          if( !(fd_head->flags & FD_DATALEN_SET) ){
 744                  /* if we dont know the datalen, there are still missing
 745                   * packets. Cheaper than the check below.
 746                   */
 747                  return FALSE;
 748          }
 749   
 750   
 751          /*
 752           * Check if we have received the entire fragment.
 753           * This is easy since the list is sorted and the head is faked.
 754           *
 755           * First, we compute the amount of contiguous data that's
 756           * available.  (The check for fd_i->offset <= max rules out 
 757           * fragments that don't start before or at the end of the
 758           * previous fragment, i.e. fragments that have a gap between
 759           * them and the previous fragment.)
 760           */
 761          max = 0;
 762          for (fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
 763                  if ( ((fd_i->offset)<=max) &&
 764                      ((fd_i->offset+fd_i->len)>max) ){
 765                          max = fd_i->offset+fd_i->len;
 766                  }
 767          }
 768   
 769          if (max < (fd_head->datalen)) {
 770                  /*
 771                   * The amount of contiguous data we have is less than the 
 772                   * amount of data we're trying to reassemble, so we haven't
 773                   * received all packets yet.
 774                   */
 775                  return FALSE;
 776          }
 777   
 778   
 779          if (max > (fd_head->datalen)) {
 780                  /*XXX not sure if current fd was the TOOLONG*/
 781                  /*XXX is it fair to flag current fd*/
 782                  /* oops, too long fragment detected */
 783                  fd->flags      |= FD_TOOLONGFRAGMENT;
 784                  fd_head->flags |= FD_TOOLONGFRAGMENT;
 785          }
 786   
 787          /* we have received an entire packet, defragment it and 
 788           * free all fragments 
 789           */
 790          /* store old data just in case */
 791          old_data=fd_head->data;
 792          fd_head->data = g_malloc(max);
 793   
 794          /* add all data fragments */
 795          for (dfpos=0,fd_i=fd_head;fd_i;fd_i=fd_i->next) {
 796                  if (fd_i->len) {
 797                          /* dfpos is always >= than fd_i->offset */
 798                          /* No gaps can exist here, max_loop(above) does this */
 799                          /* XXX - true? Can we get fd_i->offset+fd-i->len */
 800                          /* overflowing, for example? */
 801                          /*  Actually: there is at least one pathological case wherein there can be fragments
 802                              on the list which are for offsets greater than max (i.e.: following a gap after max).
 803                              (Apparently a "DESEGMENT_UNTIL_FIN" was involved wherein the FIN packet had an offset 
 804                              less than the highest fragment offset seen. [Seen from a fuzz-test: bug #2470]).
 805                              Note that the "overlap" compare must only be done for fragments with (offset+len) <= max 
 806                              and thus within the newly g_malloc'd buffer.
 807                          */
 808                               
 809                          if ( fd_i->offset+fd_i->len > dfpos ) {
 810                                  if (fd_i->offset+fd_i->len > max)
 811                                          g_warning("Reassemble error in frame %u: offset %u + len %u > max %u",
 812                                              pinfo->fd->num, fd_i->offset,
 813                                              fd_i->len, max);
 814                                  else if (dfpos < fd_i->offset)
 815                                          g_warning("Reassemble error in frame %u: dfpos %u < offset %u",
 816                                              pinfo->fd->num, dfpos, fd_i->offset);
 817                                  else if (dfpos-fd_i->offset > fd_i->len)
 818                                          g_warning("Reassemble error in frame %u: dfpos %u - offset %u > len %u",
 819                                              pinfo->fd->num, dfpos, fd_i->offset,
 820                                              fd_i->len);
 821                                  else {
 822                                          if (fd_i->offset < dfpos) {
 823                                                  fd_i->flags    |= FD_OVERLAP;
 824                                                  fd_head->flags |= FD_OVERLAP;
 825                                                  if ( memcmp(fd_head->data+fd_i->offset,
 826                                                              fd_i->data,
 827                                                              MIN(fd_i->len,(dfpos-fd_i->offset))
 828                                                               ) ) {
 829                                                          fd_i->flags    |= FD_OVERLAPCONFLICT;
 830                                                          fd_head->flags |= FD_OVERLAPCONFLICT;
 831                                                  }
 832                                          }
 833                                          memcpy(fd_head->data+dfpos,
 834                                              fd_i->data+(dfpos-fd_i->offset),
 835                                              fd_i->len-(dfpos-fd_i->offset));
Show more  




Change Warning 1975.31066 : Overlapping Memory Regions

Priority:
State:
Finding:
Owner:
Note: