Hi

Valgrind memory checker finds the following bug in cscope
feature of vim. I am using vim-7.1 (patches 1-82) on Linux x86.

==8606== Invalid write of size 1
==8606==    at 0x80D17C0: cs_fgets (if_cscope.c:267)
==8606==    by 0x818F1E6: find_tags (tag.c:1670)
==8606==    by 0x818D0F4: do_tag (tag.c:548)
==8606==    by 0x80D2E88: cs_find_common (if_cscope.c:1163)
==8606==    by 0x80D28FF: cs_find (if_cscope.c:975)
==8606==    by 0x80D14A2: do_cscope_general (if_cscope.c:135)
==8606==    by 0x80D14D1: do_cscope (if_cscope.c:150)
==8606==    by 0x809A1FB: do_one_cmd (ex_docmd.c:2622)
==8606==    by 0x8097B18: do_cmdline (ex_docmd.c:1100)
==8606==    by 0x8114018: nv_colon (normal.c:5168)
==8606==    by 0x810E16F: normal_cmd (normal.c:1141)
==8606==    by 0x80D59F5: main_loop (main.c:1180)
==8606==    by 0x80D5609: main (main.c:939)
==8606==  Address 0x7D81D50 is 0 bytes after a block of size 512 alloc'd
==8606==    at 0x4021620: malloc (vg_replace_malloc.c:149)
==8606==    by 0x8100354: lalloc (misc2.c:857)
==8606==    by 0x810027E: alloc (misc2.c:756)
==8606==    by 0x818E9B5: find_tags (tag.c:1393)
==8606==    by 0x818D0F4: do_tag (tag.c:548)
==8606==    by 0x80D2E88: cs_find_common (if_cscope.c:1163)
==8606==    by 0x80D28FF: cs_find (if_cscope.c:975)
==8606==    by 0x80D14A2: do_cscope_general (if_cscope.c:135)
==8606==    by 0x80D14D1: do_cscope (if_cscope.c:150)
==8606==    by 0x809A1FB: do_one_cmd (ex_docmd.c:2622)
==8606==    by 0x8097B18: do_cmdline (ex_docmd.c:1100)
==8606==    by 0x8114018: nv_colon (normal.c:5168)
==8606==    by 0x810E16F: normal_cmd (normal.c:1141)
==8606==    by 0x80D59F5: main_loop (main.c:1180)
==8606==    by 0x80D5609: main (main.c:939)


I can reproduce the bug by creating a cscope database
of vim source tree, then by performing the following search
in vim: ":cs find e e".

The code in if_cscope.c is:

 254     int
 255 cs_fgets(buf, size)
 256     char_u      *buf;
 257     int         size;
 258 {
 259     char *p;
 260
 261     if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
 262         return TRUE;
 263
 264     if ((int)strlen(p) > size)
 265     {
 266         strncpy((char *)buf, p, size - 1);
 267         buf[size] = '\0';
 268     }
 269     else
 270         (void)strcpy((char *)buf, p);
 271
 272     return FALSE;
 273 } /* cs_fgets */


cs_fgets() is called from tag.c:1670 with size parameter
equal to LSIZE (512).  Line 267 thus writes '\0' in buf[512].
But buf buffer was allocated with 512 bytes (LSIZE) so
line 267 writes 1 byte beyond allocated size.

Following patch fixes it and also simplifies code:

diff -c -r1.22 if_cscope.c
*** if_cscope.c 11 Mar 2007 14:48:29 -0000      1.22
--- if_cscope.c 19 Aug 2007 19:07:34 -0000
***************
*** 261,274 ****
      if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
        return TRUE;

!     if ((int)strlen(p) > size)
!     {
!       strncpy((char *)buf, p, size - 1);
!       buf[size] = '\0';
!     }
!     else
!       (void)strcpy((char *)buf, p);
!
      return FALSE;
  } /* cs_fgets */

--- 261,267 ----
      if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
        return TRUE;

!     vim_strncpy(buf, (char_u *)p, size - 1);
      return FALSE;
  } /* cs_fgets */



-- Dominique

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui