Ticket #3432 (new defect)

Opened 5 years ago

Last modified 4 months ago

Segmentation fault when viewing file which archived multiple time (in rpm's tarball)

Reported by: asy Owned by:
Priority: major Milestone: Future Releases
Component: mc-vfs Version: master
Keywords: Cc: oleksandr@…
Blocked By: Blocking:
Branch state: no branch Votes for changeset:

Description

Steps for reproduce:

1) try to open a text file in tarball of rpm;
2) wait some minutes (about ten);
3) try to open an another file in this tarball.

Copied from http://bugzilla.altlinux.org/25960
Tested in 4.8.14

Attachments

3432-dont_expire_vfs_with_open_files.diff (537 bytes) - added by andrew_b 4 years ago.
A step to fix.
mc-hlp.zip (51.6 KB) - added by andrew_b 5 months ago.

Change History

comment:1 Changed 4 years ago by and

comment:2 Changed 4 years ago by zaytsev

In the original Alt Linux report, the reporter says that he entered the RPM first, then CONTENTS.cpio, and then opened a file for editing and left mc alone for at least 10 minutes. He also supplied a core dump once...

So apparently, it is important to have a 1) rather short VFS timeout ("Timeout for freeing VFSs") and 2) have at least 3 VFS open inside each other.

Hope that helps!

comment:3 Changed 4 years ago by andrew_b

  • Component changed from mcview to mc-vfs

comment:4 Changed 4 years ago by and

backtrace based on 4.7.5.6-alt1 x86_64 mc binary

#0  0x0000000000443930 in cpio_read_bin_head (super=0x8195a0, me=0x429800 <str_8bit_release_key+16>) at cpio.c:508
508         if (u.buf.c_magic != 070707 || u.buf.c_namesize == 0 || u.buf.c_namesize > MC_MAXPATHLEN)
(gdb) bt full
#0  0x0000000000443930 in cpio_read_bin_head (super=0x8195a0, me=0x429800 <str_8bit_release_key+16>) at cpio.c:508
        u = {buf = {c_magic = 1, c_dev = 0, c_ino = 1, c_mode = 0, c_uid = 32, c_gid = 0, c_nlink = 0, c_rdev = 0, c_mtimes = {0, 0}, c_namesize = 0, c_filesizes = {0, 0}}, shorts = {1, 0, 1, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0}}
        len = <optimized out>
        name = <optimized out>
        st = {st_dev = 0, st_ino = 4433813, st_nlink = 8192, st_mode = 3661090064, st_uid = 32767, st_gid = 8545536, __pad0 = 0, st_rdev = 140736854478096, st_size = 102, st_blksize = 4440384, st_blocks = 137438953473, st_atim = {tv_sec = 0, tv_nsec = 0}, st_mtim = {tv_sec = 4294967297, 
            tv_nsec = 32}, st_ctim = {tv_sec = 0, tv_nsec = 4294967296}, __unused = {137438953473, 0, 0}}
#1  cpio_read_head (super=0x8195a0, me=0x429800 <str_8bit_release_key+16>) at cpio.c:256
No locals.
#2  cpio_open_archive (me=0x429800 <str_8bit_release_key+16>, super=0x8195a0, name=0x81e390 "\340\237\205", op=<optimized out>) at cpio.c:699
        status = <optimized out>

comment:5 Changed 4 years ago by and

ok, reproducible

vfs_timeout triggered and fh data get invalid/too early freed

==23010==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000003950 at pc 0x0000006127e7 bp 0x7ffd91241830 sp 0x7ffd91241828
READ of size 8 at 0x606000003950 thread T0
    #0 0x6127e6 in cpio_read /tmp/portage/app-misc/mc-9999/work/mc-9999/src/vfs/cpio/cpio.c:808:47
    #1 0x7fc517011f5e in mc_read /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/interface.c:310:1
    #2 0x564fdc in tar_read /tmp/portage/app-misc/mc-9999/work/mc-9999/src/vfs/tar/tar.c:877:11
    #3 0x7fc517011f5e in mc_read /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/interface.c:310:1
    #4 0x7fc5170147ff in mc_def_getlocalcopy /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/interface.c:97:17
    #5 0x7fc517013588 in mc_getlocalcopy /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/interface.c:625:13
    #6 0x50ea06 in regex_check_type /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/ext.c:648:27
    #7 0x50ea06 in regex_command_for /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/ext.c:967
    #8 0x5f0696 in regex_command /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/./ext.h:30:12
    #9 0x5f0696 in view_file_at_line /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/cmd.c:586
    #10 0x5f26d1 in view_file /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/cmd.c:625:12
    #11 0x5f26d1 in do_view_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/cmd.c:156
    #12 0x528b49 in view_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/cmd.c:635:5
    #13 0x528b49 in midnight_execute_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1378
    #14 0x7fc517022949 in buttonbar_callback /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/buttonbar.c:172:42
    #15 0x7fc517027245 in send_message /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/../../lib/widget/widget-common.h:167:15
    #16 0x7fc517027245 in dlg_try_hotkey /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:464
    #17 0x7fc517027245 in dlg_key_event /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:509
    #18 0x7fc517027245 in dlg_process_event /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:1236
    #19 0x7fc5170289c7 in frontend_dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:570:9
    #20 0x7fc517027565 in dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:1267:5
    #21 0x4fc7b8 in create_panels_and_run_mc /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:954:5
    #22 0x4fc7b8 in do_nc /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1757
    #23 0x4fc7b8 in main /tmp/portage/app-misc/mc-9999/work/mc-9999/src/main.c:401
    #24 0x7fc5155a0953 in __libc_start_main (/lib64/libc.so.6+0x20953)
    #25 0x4270e8 in _start (/usr/bin/mc+0x4270e8)

and when opening archive in archive after mc exit we get easily

==18945==ERROR: AddressSanitizer: heap-use-after-free on address 0x6060000041c0 at pc 0x7f3b4248d0f2 bp 0x7fffbb3560c0 sp 0x7fffbb3560b8
READ of size 8 at 0x6060000041c0 thread T0
    #0 0x7f3b4248d0f1 in vfs_s_close /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/direntry.c:658:38
    #1 0x7f3b42491816 in mc_close /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/interface.c:401:14
    #2 0x564da3 in tar_free_archive /tmp/portage/app-misc/mc-9999/work/mc-9999/src/vfs/tar/tar.c:274:13
    #3 0x7f3b4248cb05 in vfs_s_free_super /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/direntry.c:360:5
    #4 0x7f3b4248fbc2 in vfs_gc_done /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/gc.c:325:13
    #5 0x7f3b4249e3ef in vfs_shut /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/vfs.c:480:5
    #6 0x4fcd5e in main /tmp/portage/app-misc/mc-9999/work/mc-9999/src/main.c:409:5
    #7 0x7f3b40a0c953 in __libc_start_main (/lib64/libc.so.6+0x20953)
    #8 0x4270e8 in _start (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x4270e8)

0x6060000041c0 is located 0 bytes inside of 56-byte region [0x6060000041c0,0x6060000041f8)
freed by thread T0 here:
    #0 0x4c7188 in __interceptor_cfree.localalias.1 (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x4c7188)
    #1 0x7f3b4248fbc2 in vfs_gc_done /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/gc.c:325:13
    #2 0x7f3b4249e3ef in vfs_shut /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/vfs.c:480:5
    #3 0x4fcd5e in main /tmp/portage/app-misc/mc-9999/work/mc-9999/src/main.c:409:5
    #4 0x7f3b40a0c953 in __libc_start_main (/lib64/libc.so.6+0x20953)
    #5 0x4270e8 in _start (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x4270e8)

previously allocated by thread T0 here:
    #0 0x4c74b0 in __interceptor_calloc (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x4c74b0)
    #1 0x7f3b4171fdd0 in g_malloc0 (/usr/lib64/libglib-2.0.so.0+0x66dd0)
    #2 0x7f3b42489e83 in vfs_s_new_super /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/direntry.c:324:13
    #3 0x7f3b42489e83 in vfs_s_get_path /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/direntry.c:1129
    #4 0x7f3b4248f10d in vfs_s_inode_from_path /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/direntry.c:380:9
    #5 0x7f3b4248d6f7 in vfs_s_opendir /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/direntry.c:409:11
    #6 0x7f3b4248dc58 in vfs_s_chdir /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/direntry.c:476:12
    #7 0x7f3b42492793 in mc_chdir /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/vfs/interface.c:687:14
    #8 0x535b84 in _do_panel_cd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/panel.c:3250:9
    #9 0x5308ba in do_panel_cd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/panel.c:4627:9
    #10 0x5308ba in do_cd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/panel.c:5027
    #11 0x50f926 in exec_extension_cd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/ext.c:400:5
    #12 0x50f926 in exec_extension /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/ext.c:436
    #13 0x50f348 in regex_command_for /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/ext.c:1029:34
    #14 0x53e79c in regex_command /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/./ext.h:30:12
    #15 0x53e79c in do_enter_on_file_entry /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/panel.c:2777
    #16 0x53e79c in do_enter /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/panel.c:2832
    #17 0x53bffd in panel_execute_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/panel.c:3426:9
    #18 0x7f3b424a6341 in send_message /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/../../lib/widget/widget-common.h:167:15
    #19 0x7f3b424a6341 in dlg_key_event /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:515
    #20 0x7f3b424a6341 in dlg_process_event /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:1236
    #21 0x7f3b424a79c7 in frontend_dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:570:9
    #22 0x7f3b424a6565 in dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:1267:5
    #23 0x4fc7b8 in create_panels_and_run_mc /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:954:5
    #24 0x4fc7b8 in do_nc /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1757
    #25 0x4fc7b8 in main /tmp/portage/app-misc/mc-9999/work/mc-9999/src/main.c:401
    #26 0x7f3b40a0c953 in __libc_start_main (/lib64/libc.so.6+0x20953)
    #27 0x4270e8 in _start (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x4270e8)

comment:6 Changed 4 years ago by and

when opening nested archives we must careful with freeing order

opening single archive

mc_open handle 100 vpath /a.tar
vfs_s_new_inode ino 103744 super 21152 ino->super 21152
vfs_s_new_inode ino 103424 super 21152 ino->super 21152
*mc quit*
vfs_gc_done stamp->id 21152
vfs_s_free_super super 21152 ino_usage 2
vfs_s_free_inode start ino 103744 super 21152 ino->subdir count 1
vfs_s_free_inode start ino 103424 super 21152 ino->subdir count 0
vfs_s_free_inode finish ino 103424 super 21152 ino->st.st_nlink 1 ino->subdir count 0
vfs_s_free_inode finish ino 103744 super 21152 ino->st.st_nlink 1 ino->subdir count 0
tar_free_archive archive 21152
mc_close handle 100

opening nested archives

mc_open handle 100 vpath /a.tar
vfs_s_new_inode ino 103744 super 21152 ino->super 21152
vfs_s_new_inode ino 103424 super 21152 ino->super 21152
mc_open handle 101 vpath /a.tar/utar://b.tar
vfs_s_new_inode ino 103104 super 20960 ino->super 20960
vfs_s_new_inode ino 102784 super 20960 ino->super 20960
*mc quit*
vfs_gc_done stamp->id 21152
vfs_s_free_super super 21152 ino_usage 2
vfs_s_free_inode start ino 103744 super 21152 ino->subdir count 1
vfs_s_free_inode start ino 103424 super 21152 ino->subdir count 0
vfs_s_free_inode abort ino 103424 super 21152 ino->st.st_nlink 2 ino->subdir count 0
vfs_s_free_inode finish ino 103744 super 21152 ino->st.st_nlink 1 ino->subdir count 0
tar_free_archive archive 21152
mc_close handle 100

vfs_gc_done stamp->id 20960
vfs_s_free_super super 20960 ino_usage 2
vfs_s_free_inode start ino 103104 super 20960 ino->subdir count 1
vfs_s_free_inode start ino 102784 super 20960 ino->subdir count 0
vfs_s_free_inode finish ino 102784 super 20960 ino->st.st_nlink 1 ino->subdir count 0
vfs_s_free_inode finish ino 103104 super 20960 ino->st.st_nlink 1 ino->subdir count 0
tar_free_archive archive 20960
mc_close handle 101
vfs_s_close fh 14928
vfs_s_close fh 14928 fh->ino 103424
vfs_s_close fh 14928 fh->ino 103424 fh->ino->super 21152
*BOOM* accessing to already freed superblock 21152

when reversing traversal of vfs_gc_done stamp processing mc will survive

mc_open handle 100 vpath /a.tar
vfs_s_new_inode ino 103744 super 20960 ino->super 20960
vfs_s_new_inode ino 103424 super 20960 ino->super 20960
mc_open handle 101 vpath /a.tar/utar://b.tar
vfs_s_new_inode ino 103104 super 20768 ino->super 20768
vfs_s_new_inode ino 102784 super 20768 ino->super 20768
*mc quit*
vfs_gc_done stamp->id 20768
vfs_s_free_super super 20768 ino_usage 2
vfs_s_free_inode start ino 103104 super 20768 ino->subdir count 1
vfs_s_free_inode start ino 102784 super 20768 ino->subdir count 0
vfs_s_free_inode finish ino 102784 super 20768 ino->st.st_nlink 1 ino->subdir count 0
vfs_s_free_inode finish ino 103104 super 20768 ino->st.st_nlink 1 ino->subdir count 0
tar_free_archive archive 20768
mc_close handle 101
vfs_s_close fh 15056
vfs_s_close fh 15056 fh->ino 103424
vfs_s_close fh 15056 fh->ino 103424 fh->ino->super 20960
vfs_s_free_inode start ino 103424 super 20960 ino->subdir count 0
vfs_s_free_inode abort ino 103424 super 20960 ino->st.st_nlink 2 ino->subdir count 0

vfs_gc_done stamp->id 20960
vfs_s_free_super super 20960 ino_usage 2
vfs_s_free_inode start ino 103744 super 20960 ino->subdir count 1
vfs_s_free_inode start ino 103424 super 20960 ino->subdir count 0
vfs_s_free_inode finish ino 103424 super 20960 ino->st.st_nlink 1 ino->subdir count 0
vfs_s_free_inode finish ino 103744 super 20960 ino->st.st_nlink 1 ino->subdir count 0
tar_free_archive archive 20960
mc_close handle 100

This is maybe a solution for correct existing (second stacktrace),
this will not help when vfs_gc freeing a in-use superblock too early (first stacktrace).

But why is there no vfs_s_close() in opening_single_archive example?
Maybe vfs_s_close() is triggered wrong on nested archives?

Last edited 4 years ago by and (previous) (diff)

comment:7 Changed 4 years ago by and

root case is when doing

_do_panel_ch vpath_old /a.tar/utar:// vpath /a.tar/utar://b.tar/utar://

we must ensure that vpath_old don't get added to stamplist (auto. gc freeing after expire)
when current vpath rely on vpath_old e.g. cascade vfs.
vfs_release_path() -> vfs_stamp_create() check for nothingisopen() but tar and cpio don't support it yet.

comment:8 Changed 4 years ago by andrew_b

Related to #2095.

Changed 4 years ago by andrew_b

A step to fix.

comment:9 Changed 5 months ago by andrew_b

comment:10 Changed 5 months ago by andrew_b

Not fully fixed yet.
The example archive is attached.

Changed 5 months ago by andrew_b

comment:11 Changed 5 months ago by andrew_b

I believe the cause of segfault is sfs_nothingisopen() which always returns TRUE.

comment:12 Changed 4 months ago by andrew_b

Ticket #4001 has been marked as a duplicate of this ticket.

comment:13 Changed 4 months ago by post-factum

  • Cc oleksandr@… added
Note: See TracTickets for help on using tickets.