Your message dated Tue, 27 Jan 2009 20:01:57 GMT
with message-id <[email protected]>
and subject line slocate has been removed from Debian, closing #398328
has caused the Debian Bug report #398328,
regarding double free sometimes (w. fix; also fixes a memory leak).
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
398328: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=398328
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: slocate
Version: 3.1-1
Severity: normal
Tags: patch

Sometimes, slocate does a double free.  Examples:

$ slocate -i lib/modules*fat.ko
/lib/modules/2.6.8-2-686/kernel/fs/fat/fat.ko
/lib/modules/2.6.8-2-686/kernel/fs/vfat/vfat.ko
/lib/modules/2.6.16-2-686/kernel/fs/fat/fat.ko
/lib/modules/2.6.16-2-686/kernel/fs/vfat/vfat.ko
*** glibc detected *** double free or corruption (fasttop): 0x08052790 ***
Aborted
$

(now notice the surrounding asterisks)

$ slocate -i *lib/modules*fat.ko*
/lib/modules/2.6.8-2-686/kernel/fs/fat/fat.ko
/lib/modules/2.6.8-2-686/kernel/fs/vfat/vfat.ko
/lib/modules/2.6.16-2-686/kernel/fs/fat/fat.ko
/lib/modules/2.6.16-2-686/kernel/fs/vfat/vfat.ko
$

In the following, do s|([a-z0-9]*)|lib/modules*\1.ko| (such that "*foobar"
becomes "*lib/modules*foobar.ko", and the '*' before foobar maps to the '*'
before lib).

It does a double free on:
fat
*fat
fat*
(not *fat*)

vfat
(not *vfat)
(not vfat*)
(not *vfat*)

ext3
(not *ext3)
(not ext3*)
(not *ext3*)

(not reiserfs)
(not *reiserfs)
(not reiserfs*)
(not *reiserfs*)

I'm not sure about the difference, but it may very well depend on the ordering
of some stuff (and hence my locate.db, and my file system contents).

Anyways, I found a wrong call to free; if it's deleted, slocate doesn't
double-free on any of the above cases.

Here's the patch:

diff -ru slocate-orig/slocate-3.1/src/slocate.c 
slocate-fixed/slocate-3.1/src/slocate.c
--- slocate-orig/slocate-3.1/src/slocate.c      2006-03-08 05:40:11.000000000 
+0100
+++ slocate-fixed/slocate-3.1/src/slocate.c     2006-10-18 12:57:23.000000000 
+0200
@@ -499,6 +499,7 @@
        struct stat db_stat;
        gid_t effective_gid = 0;
        time_t now = 0;
+       char *search_str_argument = search_str;
 
        effective_gid = getegid();
 
@@ -557,8 +558,8 @@
                memcpy(tmp_str+1, search_str, ss_len);
                tmp_str[ss_len+1] = '*';
                tmp_str[ss_len+2] = 0;
-               free(search_str);
                search_str = tmp_str;
+               /* (search_str_argument != search_str): we free later */
        }       
 
        g_data->slevel = ch[0];
@@ -709,6 +710,10 @@
                free(path_head);
                path_head = NULL;
        }
+       if (search_str != search_str_argument) {
+               free(search_str);
+               search_str = NULL;
+       }
 
        return ret;
 }

I found that free_cmd_data frees some freed data: (cmd_data->search_str[i]).
So, tracking down the use of ->search_str, I found that it's passed to
search_db ("/* Search each string */"), wherein it's freed: if search_str is
globulent (if (search_str && (strchr(search_str,'*') != NULL ...))), then it's
replaced by "*${search_str}*\0".  Following search_str into match, it seems
like it isn't freed (or otherwise significantly frobbed) there.

The solution, of course, is to *not* free search_ptr.  That's what the line
"-      free(search_str);" does.  The rest is simply a fix for a memory leak:
tmp_str wasn't freed.

perhaps it was thought that search_str was passed by reference?  Then it might
have worked;  figuring out whether passing it by reference would be better is
left as an exercise to the reader :P

Running the old vs. the new version with valgrind reveals that exactly one
lossage disappears;  it still loses 36 bytes in 1 block directly, and 120
bytes in 10 blocks indirectly, but that's all lost inside libc (it appears).

Anyways, hope you like my code :)

-- System Information:
Debian Release: testing/unstable
  APT prefers testing
  APT policy: (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.16-2-686
Locale: LANG=en_GB, LC_CTYPE=en_GB (charmap=ISO-8859-1) (ignored: LC_ALL set to 
en_GB.ISO-8859-1)

Versions of packages slocate depends on:
ii  adduser                      3.97        Add and remove users and groups
ii  dpkg                         1.13.22     package maintenance system for Deb
ii  libc6                        2.3.6.ds1-4 GNU C Library: Shared libraries

slocate recommends no packages.

-- no debconf information

-- 
Take a ! on my #|

Jonas Kölker <[email protected]> <URL:http://jonaskoelker.homeunix.org/>

Attachment: signature.asc
Description: Digital signature


--- End Message ---
--- Begin Message ---
Version: 3.1-1.1+rm

The slocate package has been removed from Debian testing, unstable and
experimental, so I am now closing the bugs that were still opened
against it.

For more information about this package's removal, read
http://bugs.debian.org/457565 . That bug might give the reasons why
this package was removed, and suggestions of possible replacements.

Don't hesitate to reply to this mail if you have any question.

Thank you for your contribution to Debian.

Kind regards,
--
Marco Rodrigues


--- End Message ---

Reply via email to