Bug 651 - cp: Segmentation fault on free()
Summary: cp: Segmentation fault on free()
Status: RESOLVED FIXED
Alias: None
Product: Busybox
Classification: Unclassified
Component: Other (show other bugs)
Version: unspecified
Hardware: PC Linux
: P3 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-10-07 16:24 UTC by Jiri J.
Modified: 2009-10-08 00:15 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:


Attachments
Fix (589 bytes, patch)
2009-10-07 23:51 UTC, Denys Vlasenko
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jiri J. 2009-10-07 16:24:24 UTC
There are several cases when this segfault occurs, it all boils down to the only free() call (since it happens even without FEATURE_CP_LONG_OPTIONS) in coreutils/cp.c:
<snip>
        if (copy_file(*argv, dest, flags) < 0) {
                status = EXIT_FAILURE;
        }
        free((void*)dest);
        if (*++argv == last) {
                break;
        }
</snip>

The backtrace isn't much useful even with maximum debug support I was able to get:

$ gdb ./busybox_unstripped
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) run cp README delme
Starting program: /home/user/busybox/busybox_unstripped cp README delme

Program received signal SIGSEGV, Segmentation fault.
0x080eccd6 in free ()
(gdb) bt full
#0  0x080eccd6 in free ()
No symbol table info available.
#1  0x00000005 in ?? ()
No symbol table info available.
#2  0x000081a4 in ?? ()
No symbol table info available.
#3  0x0810d600 in ?? ()
No symbol table info available.
#4  0x00000000 in ?? ()
No symbol table info available.
(gdb)


Several observations:
  - it doesn't happen on something like
      cd /lib
      mkdir modules_test
      cp -r modules/* modules_test/.
  - it happens upon creating the destination file/directory
    (ie. without the "mkdir" step in previous example)
      cd /lib
      cp -r modules/ modules_test
    note: seems I can't reproduce it on any dir,
          just the "modules" dir in /lib segfaults
  - it happens on file overwrite, not only creation
    (ie. "cp README delme" several times in a row)
    so I believe it has nothing to do with this, looks more like
    a source/destination parsing problem

And the important thing - this bug was introduced with 48f116198d53, I suspect the part with free((void*)dest):
<snip>
                }
+               free((void*)dest);
                if (*++argv == last) {
-                       /* possibly leaking dest... */
                        break;
                }
-               free((void*)dest);
        }
</snip>

Tested on dcd27abcc (2009-10-05).
Comment 1 Denys Vlasenko 2009-10-07 23:51:57 UTC
Created attachment 685 [details]
Fix

Fixed with the attached patch. Sorry...