Ticket #3983 (new defect)

Opened 7 months ago

Last modified 6 months ago

SIGBUS, Bus error in __memcmp_avx2_movbe (or __memcmp_sse2) when comparing two dirs(F9,c,c,T) that contain symlink to 0 byte file

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

Description

What version of Midnight Commander is used?

$ LC_MESSAGES=C mc -V
GNU Midnight Commander 4.8.22-130-ge1d11906b
Built with GLib 2.60.1
Using the S-Lang library with terminfo database
With builtin Editor
With subshell support as default
With support for background operations
With mouse support on xterm
With internationalization support
With multiple codepages support
Virtual File Systems: cpiofs, tarfs, sfs, extfs, ftpfs, sftpfs, fish
Data types: char: 8; int: 32; long: 64; void *: 64; size_t: 64; off_t: 64;

$ LC_MESSAGES=C mc -F
Home directory: /home/user                                                      
Profile root directory: /home/user

[System data]
    Config directory: /etc/mc/
    Data directory:   /usr/share/mc/
    File extension handlers: /usr/lib/mc/ext.d/
    VFS plugins and scripts: /usr/lib/mc/
  extfs.d:        /usr/lib/mc/extfs.d/
  fish:           /usr/lib/mc/fish/

[User data]
    Config directory: /home/user/.config/mc/
    Data directory:   /home/user/.local/share/mc/
  skins:          /home/user/.local/share/mc/skins/
  extfs.d:        /home/user/.local/share/mc/extfs.d/
  fish:           /home/user/.local/share/mc/fish/
  mcedit macros:  /home/user/.local/share/mc/mc.macros
  mcedit external macros: /home/user/.local/share/mc/mcedit/macros.d/macro.*
    Cache directory:  /home/user/.cache/mc/

$ mc --configure-options
 '--prefix=/usr' '--sysconfdir=/etc' '--libexecdir=/usr/lib' '--enable-background' '--enable-network' '--enable-netcode' '--enable-charset' '--enable-nls' '--with-vfs' '--with-edit' '--with-screen=slang' '--without-x' '--without-samba' '--without-gpm-mouse' '--without-gnome' '--with-debug' '--without-included-gettext' '--disable-dependency-tracking' 'CFLAGS=-pipe -march=native -Wno-trigraphs -fno-schedule-insns2 -fno-delete-null-pointer-checks -mtune=native -fomit-frame-pointer -O2 -D_FORTIFY_SOURCE=2 -O2 -fbuiltin -ggdb3'

$ type mc
mc is aliased to `. mc-wrapper.sh --nomouse --subshell --stickchars'
$ type mc-wrapper.sh
mc-wrapper.sh is /home/user/bin/mc-wrapper.sh
$ which mc-wrapper.sh
/home/user/bin/mc-wrapper.sh
$ cat `which mc-wrapper.sh`
MC_USER=`id | sed 's/[^(]*(//;s/).*//'`
MC_PWD_FILE="${TMPDIR-/tmp}/mc-$MC_USER/mc.pwd.$$"
/usr/bin/mc -P "$MC_PWD_FILE" "$@"

if test -r "$MC_PWD_FILE"; then
	MC_PWD="`cat "$MC_PWD_FILE"`"
	if test -n "$MC_PWD" && test -d "$MC_PWD"; then
		cd "$MC_PWD"
	fi
	unset MC_PWD
fi

rm -f "$MC_PWD_FILE"
unset MC_PWD_FILE
unset MC_USER

$ coredumpctl -r|head -2
TIME                            PID   UID   GID SIG COREFILE  EXE
Mon 2019-05-06 13:36:45 CEST  13484  1000  1000   7 present   /usr/bin/mc

Note: below I've redirected the gdb output into /tmp/a file because I don't have scrollback buffer via ssh (and haven't yet figured out how to get one):

$ coredumpctl gdb >/tmp/a
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 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 "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/mc...done.
[New LWP 13484]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Core was generated by `/usr/bin/mc -P /tmp/mc-user/mc.pwd.1908 --nomouse --subshell --stickchars'.
Program terminated with signal SIGBUS, Bus error.
#0  0x00007fcc3acba480 in __memcmp_avx2_movbe () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007fcc3acba480 in __memcmp_avx2_movbe () from /usr/lib/libc.so.6
#1  0x000055a43a906808 in compare_files (size=29, vpath2=0x55a43ba32700, vpath1=0x55a43ba3f2c0) at cmd.c:238
#2  compare_dir (panel=0x55a43ba2c560, other=0x55a43ba33b70, mode=mode@entry=compare_thourough) at cmd.c:339
#3  0x000055a43a908042 in compare_dirs_cmd () at cmd.c:1165
#4  0x000055a43a8a9d05 in midnight_execute_cmd (sender=0x55a43ba22a00, command=109) at midnight.c:1115
#5  0x000055a43a8d903d in send_message (data=0x0, parm=<optimized out>, msg=MSG_ACTION, sender=0x55a43ba22a00, 
    w=<optimized out>) at ../../lib/widget/widget-common.h:210
#6  menubar_execute (menubar=0x55a43ba22a00) at menu.c:345
#7  0x000055a43a8d9baa in menubar_handle_key (key=<optimized out>, menubar=0x55a43ba22a00) at menu.c:533
#8  menubar_callback (w=0x55a43ba22a00, sender=<optimized out>, msg=<optimized out>, parm=<optimized out>, 
    data=<optimized out>) at menu.c:627
#9  0x000055a43a8925ca in send_message (data=0x0, parm=99, msg=MSG_HOTKEY, sender=0x0, w=0x55a43ba22a00)
    at ../../lib/widget/widget-common.h:210
#10 dlg_try_hotkey (h=0x55a43ba12210, h=0x55a43ba12210, d_key=99) at dialog.c:422
#11 dlg_key_event (d_key=99, h=0x55a43ba12210) at dialog.c:482
#12 dlg_process_event (h=0x55a43ba12210, key=99, event=<optimized out>) at dialog.c:1164
#13 0x000055a43a8928ab in frontend_dlg_run (h=0x55a43ba12210) at dialog.c:544
#14 dlg_run (h=0x55a43ba12210) at dialog.c:1197
#15 0x000055a43a8ab42c in do_nc () at midnight.c:1783
#16 0x000055a43a886504 in main (argc=<optimized out>, argv=<optimized out>) at main.c:409
(gdb) bt full
#0  0x00007fcc3acba480 in __memcmp_avx2_movbe () from /usr/lib/libc.so.6
No symbol table info available.
#1  0x000055a43a906808 in compare_files (size=29, vpath2=0x55a43ba32700, vpath1=0x55a43ba3f2c0) at cmd.c:238
        data2 = 0x7fcc3b35f000 <error: Cannot access memory at address 0x7fcc3b35f000>
        data1 = 0x7fcc3b389000 <error: Cannot access memory at address 0x7fcc3b389000>
        file2 = <optimized out>
        file1 = <optimized out>
        result = -1
        file1 = <optimized out>
        result = <optimized out>
        file2 = <optimized out>
        data1 = <optimized out>
        data2 = <optimized out>
#2  compare_dir (panel=0x55a43ba2c560, other=0x55a43ba33b70, mode=mode@entry=compare_thourough) at cmd.c:339
        src_name = 0x55a43ba3f2c0
        dst_name = 0x55a43ba32700
        target = <optimized out>
        source = <optimized out>
        i = 2
        j = <optimized out>
#3  0x000055a43a908042 in compare_dirs_cmd () at cmd.c:1165
        choice = 2
        thorough_flag = compare_thourough
#4  0x000055a43a8a9d05 in midnight_execute_cmd (sender=0x55a43ba22a00, command=109) at midnight.c:1115
        res = MSG_HANDLED
#5  0x000055a43a8d903d in send_message (data=0x0, parm=<optimized out>, msg=MSG_ACTION, sender=0x55a43ba22a00, 
    w=<optimized out>) at ../../lib/widget/widget-common.h:210
        ret = MSG_NOT_HANDLED
        ret = <optimized out>
#6  menubar_execute (menubar=0x55a43ba22a00) at menu.c:345
        w = 0x55a43ba22a00
        menu = <optimized out>
        entry = 0x55a43ba0fe10
#7  0x000055a43a8d9baa in menubar_handle_key (key=<optimized out>, menubar=0x55a43ba22a00) at menu.c:533
        entry = <optimized out>
        menu = 0x55a43ba21170
        i = 0x55a43ba0c560 = {0x55a43ba0fe10, 0x55a43ba0feb0, 0x55a43ba0ff50, 0x55a43ba0fff0, 0x0, 0x55a43ba10090, 
          0x55a43ba10130, 0x55a43ba20e50, 0x55a43ba20ef0, 0x55a43ba20f90, 0x0, 0x55a43ba21030, 0x55a43ba210d0, 0x55a43ba0fa00}
#8  menubar_callback (w=0x55a43ba22a00, sender=<optimized out>, msg=<optimized out>, parm=<optimized out>, 
    data=<optimized out>) at menu.c:627
        menubar = 0x55a43ba22a00
#9  0x000055a43a8925ca in send_message (data=0x0, parm=99, msg=MSG_HOTKEY, sender=0x0, w=0x55a43ba22a00)
    at ../../lib/widget/widget-common.h:210
        ret = MSG_NOT_HANDLED
        ret = <optimized out>
#10 dlg_try_hotkey (h=0x55a43ba12210, h=0x55a43ba12210, d_key=99) at dialog.c:422
        hot_cur = <optimized out>
        current = 0x55a43ba22a00
        handled = MSG_NOT_HANDLED
        c = 99
        hot_cur = <optimized out>
        current = <optimized out>
        handled = <optimized out>
        c = <optimized out>
#11 dlg_key_event (d_key=99, h=0x55a43ba12210) at dialog.c:482
        handled = <optimized out>
        handled = <optimized out>
#12 dlg_process_event (h=0x55a43ba12210, key=99, event=<optimized out>) at dialog.c:1164
No locals.
#13 0x000055a43a8928ab in frontend_dlg_run (h=0x55a43ba12210) at dialog.c:544
        d_key = <optimized out>
        wh = 0x55a43ba12210
        event = {buttons = 0, x = -1, y = 982048309, type = (GPM_DOWN | GPM_DOUBLE | GPM_MFLAG | GPM_HARD | unknown: 21504)}
        wh = <optimized out>
        event = <optimized out>
        d_key = <optimized out>
#14 dlg_run (h=0x55a43ba12210) at dialog.c:1197
No locals.
#15 0x000055a43a8ab42c in do_nc () at midnight.c:1783
        ret = <optimized out>
#16 0x000055a43a886504 in main (argc=<optimized out>, argv=<optimized out>) at main.c:409
        mcerror = 0x0
        config_migrated = 0
        config_migrate_msg = 0x0
        exit_code = 1
(gdb) q
           PID: 13484 (mc)
           UID: 1000 (user)
           GID: 1000 (user)
        Signal: 7 (BUS)
     Timestamp: Mon 2019-05-06 13:36:45 CEST (11min ago)
  Command Line: /usr/bin/mc -P /tmp/mc-user/mc.pwd.1908 --nomouse --subshell --stickchars
    Executable: /usr/bin/mc
 Control Group: /system.slice/sshd.service
          Unit: sshd.service
         Slice: system.slice
       Boot ID: 85b887fbf341469ea4a8be2dd78878ac
    Machine ID: 5767ef25f523419aaa049f3d74481940
      Hostname: i87k
       Storage: /var/lib/systemd/coredump/core.mc.1000.85b887fbf341469ea4a8be2dd78878ac.13484.1557142605000000
       Message: Process 13484 (mc) of user 1000 dumped core.
                
                Stack trace of thread 13484:
                #0  0x00007fcc3acba480 __memcmp_avx2_movbe (libc.so.6)
                #1  0x000055a43a906808 compare_files (mc)
                #2  0x000055a43a908042 compare_dirs_cmd (mc)
                #3  0x000055a43a8a9d05 midnight_execute_cmd (mc)
                #4  0x000055a43a8d903d send_message (mc)
                #5  0x000055a43a8d9baa menubar_handle_key (mc)
                #6  0x000055a43a8925ca send_message (mc)
                #7  0x000055a43a8928ab frontend_dlg_run (mc)
                #8  0x000055a43a8ab42c do_nc (mc)
                #9  0x000055a43a886504 main (mc)
                #10 0x00007fcc3ab83ce3 __libc_start_main (libc.so.6)
                #11 0x000055a43a88666e _start (mc)

What steps will reproduce the problem?

Attached directory structure and files for reproduction purposes:

  1. chdir into /home/user/TODO/coredump_mc/leftdir/mc on the left panel
  2. chdir into /home/user/TODO/coredump_mc/rightdir/mc on the right panel
  3. then do F9, c, c, T to compare the dirs and crash

The above stacktrace was on an Intel i8700k CPU desktop PC(has avx and avx2), the below one is on an Ideapad Z575 laptop with AMD A6-3400M APU with Radeon(tm) HD Graphics CPU (it doesn't have avx):

$ coredumpctl gdb
           PID: 31065 (mc)
           UID: 1000 (user)
           GID: 1000 (user)
        Signal: 7 (BUS)
     Timestamp: Mon 2019-05-06 14:00:12 CEST (1min 34s ago)
  Command Line: /usr/bin/mc -P /tmp/mc-user/mc.pwd.25438 --nomouse --subshell --stickchars
    Executable: /usr/bin/mc
 Control Group: /user.slice/user-1000.slice/session-c1.scope
          Unit: session-c1.scope
         Slice: user-1000.slice
       Session: c1
     Owner UID: 1000 (user)
       Boot ID: dfe6cd331478451b8c6522386e636e51
    Machine ID: ac27e28ecb9e47208f622bcf7f772c6b
      Hostname: Z575
       Storage: /var/lib/systemd/coredump/core.mc.1000.dfe6cd331478451b8c6522386e636e51.31065.1557144012000000
       Message: Process 31065 (mc) of user 1000 dumped core.
                
                Stack trace of thread 31065:
                #0  0x00007f93b4764100 __memcmp_sse2 (libc.so.6)
                #1  0x0000564da47c0527 compare_files (mc)
                #2  0x0000564da476191d midnight_execute_cmd (mc)
                #3  0x0000564da479231d send_message (mc)
                #4  0x0000564da4792eda menubar_handle_key (mc)
                #5  0x0000564da4749b14 send_message (mc)
                #6  0x0000564da4749df9 frontend_dlg_run (mc)
                #7  0x0000564da4762fec do_nc (mc)
                #8  0x0000564da473d53c main (mc)
                #9  0x00007f93b46effce __libc_start_main (libc.so.6)
                #10 0x0000564da473d6be _start (mc)

GNU gdb (GDB) 8.2.1
Copyright (C) 2018 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 "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/mc...done.
[New LWP 31065]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Core was generated by `/usr/bin/mc -P /tmp/mc-user/mc.pwd.25438 --nomouse --subshell --stickchars'.
Program terminated with signal SIGBUS, Bus error.
#0  __memcmp_sse2 () at ../sysdeps/x86_64/memcmp.S:40
40	../sysdeps/x86_64/memcmp.S: No such file or directory.
(gdb) bt
#0  __memcmp_sse2 () at ../sysdeps/x86_64/memcmp.S:40
#1  0x0000564da47c0527 in compare_files (size=29, vpath2=0x564da4e0fe70, 
    vpath1=0x564da4e13880) at cmd.c:238
#2  compare_dir (panel=0x564da4e0d500, other=0x564da4e0e8b0, 
    mode=compare_thourough) at cmd.c:339
#3  0x0000564da47c1e18 in compare_dirs_cmd () at cmd.c:1166
#4  0x0000564da476191d in midnight_execute_cmd (sender=0x564da4dff080, 
    command=109) at midnight.c:1115
#5  0x0000564da479231d in send_message (data=0x0, parm=<optimized out>, 
    msg=MSG_ACTION, sender=0x564da4dff080, w=<optimized out>)
    at ../../lib/widget/widget-common.h:210
#6  menubar_execute (menubar=0x564da4dff080) at menu.c:345
#7  0x0000564da4792eda in menubar_handle_key (key=<optimized out>, 
    menubar=0x564da4dff080) at menu.c:533
#8  menubar_callback (w=0x564da4dff080, sender=<optimized out>, 
    msg=<optimized out>, parm=<optimized out>, data=<optimized out>)
    at menu.c:627
#9  0x0000564da4749b14 in send_message (data=0x0, parm=99, msg=MSG_HOTKEY, 
    sender=0x0, w=0x564da4dff080) at ../../lib/widget/widget-common.h:210
#10 dlg_try_hotkey (h=0x564da4df2000, h=0x564da4df2000, d_key=99)
    at dialog.c:422
#11 dlg_key_event (d_key=99, h=0x564da4df2000) at dialog.c:482
#12 dlg_process_event (h=0x564da4df2000, key=99, event=<optimized out>)
--Type <RET> for more, q to quit, c to continue without paging--c
    at dialog.c:1164
#13 0x0000564da4749df9 in frontend_dlg_run (h=0x564da4df2000) at dialog.c:544
#14 dlg_run (h=0x564da4df2000) at dialog.c:1197
#15 0x0000564da4762fec in do_nc () at midnight.c:1783
#16 0x0000564da473d53c in main (argc=<optimized out>, argv=<optimized out>) at main.c:409
(gdb) bt full
#0  __memcmp_sse2 () at ../sysdeps/x86_64/memcmp.S:40
No locals.
#1  0x0000564da47c0527 in compare_files (size=29, vpath2=0x564da4e0fe70, 
    vpath1=0x564da4e13880) at cmd.c:238
        data2 = 0x7f93b4f05000 <error: Cannot access memory at address 0x7f93b4f05000>
        data1 = <optimized out>
        file2 = <optimized out>
        file1 = <optimized out>
        result = -1
        file1 = <optimized out>
        result = <optimized out>
        file2 = <optimized out>
        data1 = <optimized out>
        data2 = <optimized out>
#2  compare_dir (panel=0x564da4e0d500, other=0x564da4e0e8b0, 
    mode=compare_thourough) at cmd.c:339
        src_name = 0x564da4e13880
        dst_name = 0x564da4e0fe70
        target = <optimized out>
        source = <optimized out>
        i = 2
        j = <optimized out>
--Type <RET> for more, q to quit, c to continue without paging--c
#3  0x0000564da47c1e18 in compare_dirs_cmd () at cmd.c:1166
        choice = <optimized out>
        thorough_flag = <optimized out>
#4  0x0000564da476191d in midnight_execute_cmd (sender=0x564da4dff080, command=109) at midnight.c:1115
        res = MSG_HANDLED
#5  0x0000564da479231d in send_message (data=0x0, parm=<optimized out>, msg=MSG_ACTION, sender=0x564da4dff080, w=<optimized out>) at ../../lib/widget/widget-common.h:210
        ret = MSG_NOT_HANDLED
        ret = <optimized out>
#6  menubar_execute (menubar=0x564da4dff080) at menu.c:345
        w = 0x564da4dff080
        menu = <optimized out>
        entry = 0x564da4dfd8a0
#7  0x0000564da4792eda in menubar_handle_key (key=<optimized out>, menubar=0x564da4dff080) at menu.c:533
        entry = <optimized out>
        menu = 0x564da4df2460
        i = 0x564da4ded160 = {0x564da4dfd8a0, 0x564da4dfd940, 0x564da4df4b90, 0x564da4df4c30, 0x0, 0x564da4df4cd0, 0x564da4df4d70, 0x564da4df4e10, 0x564da4df05f0, 0x564da4df0690, 0x0, 0x564da4df0730, 0x564da4df07d0, 0x564da4df0870}
#8  menubar_callback (w=0x564da4dff080, sender=<optimized out>, msg=<optimized out>, parm=<optimized out>, data=<optimized out>) at menu.c:627
        menubar = 0x564da4dff080
#9  0x0000564da4749b14 in send_message (data=0x0, parm=99, msg=MSG_HOTKEY, sender=0x0, w=0x564da4dff080) at ../../lib/widget/widget-common.h:210
        ret = MSG_NOT_HANDLED
        ret = <optimized out>
#10 dlg_try_hotkey (h=0x564da4df2000, h=0x564da4df2000, d_key=99) at dialog.c:422
        hot_cur = <optimized out>
        current = 0x564da4dff080
        handled = MSG_NOT_HANDLED
        c = 99
        hot_cur = <optimized out>
        current = <optimized out>
        handled = <optimized out>
        c = <optimized out>
#11 dlg_key_event (d_key=99, h=0x564da4df2000) at dialog.c:482
        handled = <optimized out>
        handled = <optimized out>
#12 dlg_process_event (h=0x564da4df2000, key=99, event=<optimized out>) at dialog.c:1164
No locals.
#13 0x0000564da4749df9 in frontend_dlg_run (h=0x564da4df2000) at dialog.c:544
        d_key = <optimized out>
        wh = 0x564da4df2000
        event = {buttons = -1528805856, x = -1, y = -1534984512, type = (GPM_MOVE | GPM_DOWN | GPM_UP | GPM_TRIPLE | unknown: 22016)}
        wh = <optimized out>
        event = <optimized out>
        d_key = <optimized out>
#14 dlg_run (h=0x564da4df2000) at dialog.c:1197
No locals.
#15 0x0000564da4762fec in do_nc () at midnight.c:1783
        ret = <optimized out>
#16 0x0000564da473d53c in main (argc=<optimized out>, argv=<optimized out>) at main.c:409
        mcerror = 0x0
        config_migrated = 0
        config_migrate_msg = 0x0
        exit_code = 1
(gdb) q

Attachments

dirs_for_F9_c_c_t.tar.xz (5.3 KB) - added by howaboutsynergy 7 months ago.
fix_the_sometimes_truncated_shell_output_in_mc.patch (3.8 KB) - added by howaboutsynergy 7 months ago.
createstreams.patch (1.4 KB) - added by howaboutsynergy 7 months ago.
xzthreads.patch (1.7 KB) - added by howaboutsynergy 7 months ago.
7z_avoid_lockup_when_pwd_needed.patch (2.9 KB) - added by howaboutsynergy 7 months ago.
select_suspend_not_skip_bydefault.patch (498 bytes) - added by howaboutsynergy 7 months ago.

Change History

Changed 7 months ago by howaboutsynergy

comment:1 Changed 7 months ago by howaboutsynergy

oh I just realized that I was also applying a bunch of other patches on top of master. I'm including them here also, but let me know if you want me to try it without the patches... hopefully they are irrelevant to the issue.

Changed 7 months ago by howaboutsynergy

Changed 7 months ago by howaboutsynergy

Changed 7 months ago by howaboutsynergy

Changed 7 months ago by howaboutsynergy

Changed 7 months ago by howaboutsynergy

comment:2 Changed 7 months ago by howaboutsynergy

Simplified reproduction steps to: one dir containing a symlink(absolute or relative) to a 0 byte file, then F9,c,c,t

ie.

  1. cd /tmp
  2. mkdir 3
  3. cd 3
  4. touch newemptyfile
  5. mkdir leftright
  6. cd leftright && ln -rs ../newemptyfile
  7. now enter mc and ensure both panels are inside dir leftright then press F9,c,c,t

comment:3 Changed 7 months ago by howaboutsynergy

  • Cc howaboutsynergy@… added
  • Summary changed from SIGBUS, Bus error in __memcmp_avx2_movbe (or __memcmp_sse2) when comparing two dirs (F9,c,c,T) to SIGBUS, Bus error in __memcmp_avx2_movbe (or __memcmp_sse2) when comparing two dirs(F9,c,c,T) that contain symlink to 0 byte file

comment:4 Changed 7 months ago by andrew_b

Thanks! But most patches are not matched to ticket topic. Please create separate tickets or attach simple patches to #3955.

Also please format your patches accordingly our coding style.

comment:5 Changed 7 months ago by howaboutsynergy

Ah, sorry for the confusion. Please ignore the patches!
The only reason I added them was because of https://midnight-commander.org/ticket/3983#comment:1 ie. because I thought that they might be needed to reproduce this issue (because I had them applied on master when I encountered this bug, and I forgot that I had them - I know that I should've tested master without any patches). But I can kinda see now that they have no effect on this issue, so they should be ignored! I don't know how to delete them from here.

comment:6 Changed 7 months ago by howaboutsynergy

actually all attachments should be deleted because there are simpler reproduction steps in https://midnight-commander.org/ticket/3983#comment:2 and thus dirs_for_F9_c_c_t.tar.xz is not needed either.

comment:7 Changed 7 months ago by howaboutsynergy

ok this isn't a mc bug, it's a <mmap-ing a symlink that points to 0 byte file> bug. It works if file is more than 0 bytes in length. Else, accessing the first byte of the resulting mmap causes the crash! In other words, mmap yields a 0 byte sized mmap which seems like a bug in mmap especially since the manual says:

The  length argument specifies the length of the mapping (which must be greater than 0).

which is clearly trying to avoid exactly this type of situation (0 byte sized mmap result ie. addr[0] will SIGBUS error)

But mc could temporarily mitigate by adding O_NOFOLLOW to prevent this crash, though then comparing the same symlinks in the same dir, it will show them as different.

non-mc repro. code:

#include <sys/types.h>
#include <sys/stat.h>

#define __USE_XOPEN2K8 1 //to get O_NOFOLLOW
#include <fcntl.h>

#include <unistd.h> // close
#include <stdio.h> //printf

#define __USE_MISC 1 //to get MAP_FILE
#include <sys/mman.h> //mmap

#include <stdlib.h>
#include <bits/mman-linux.h> // MAP_FILE
#include <string.h> // memcmp

int main() {
  int file;
  off_t size=12;
  file = open("./3/symlink_to_emptyfile", O_RDONLY // | O_NOFOLLOW //open will fail since the file is a symlink! 12 bytes symlink
      );
  if (file >= 0) {
    printf("!! open success\n");
    char *addr;
    addr = mmap (0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, file, 0);
    if (addr != MAP_FAILED){
      printf("!! mmap ok\n");
      printf("!! 1st byte of mmap: %c\n", addr[0]);
      munmap(addr, size);
    }
  } else {
    printf("!! open failed\n");
  }
  close(file);
  return 0;
}
Program terminated with signal SIGBUS, Bus error.
#0  0x0000561126fa0216 in main () at b.c:28
28	      printf("!! 1st byte of mmap: %c\n", addr[0]);
(gdb) bt full
#0  0x0000561126fa0216 in main () at b.c:28
        addr = 0x7fdce7d5f000 <error: Cannot access memory at address 0x7fdce7d5f000>
        file = 3
        size = 12

./3/symlink_to_emptyfile is a symlink to ../emptyfile which is a 0 byte file.
(it works if it's a 1 byte file, for example)

That being said, mc is using size of symlink but comparing contents of files the symlink points to. Otherwise, if mc were using the size of the file that the symlink points to, then it wouldn't even mmap anything and thus not reach the crash.
So there are two bugs here that could be squashed by using the correct size.

comment:8 Changed 7 months ago by howaboutsynergy

comment:9 Changed 6 months ago by howaboutsynergy

Ok, it looks like it's not a mmap bug, because it acts like a truncated file from offset 0, thus accessing that memory will SIGBUS, according to man 2 mmap:

SIGBUS Attempted access to a portion of the buffer that does not correspond to the file (for example, beyond the end of the file, including the case where another process has truncated the file).

So then it's up to mc to check if the file that the symlink points to is 0 bytes and if so, not mmap.
ie. Currently, just changing the size used to be size of the file that the symlink points to instead of size of the symlink, would fix this issue and the other issue mentioned in my prev. comment where only the first X bytes of the the file contents get compared (X is size of symlink, eg. le PATH_MAX)

comment:10 follow-up: ↓ 11 Changed 6 months ago by howaboutsynergy

There is a better workaround for this. Replacing #ifdef HAVE_MMAP with #if 0 in function compare_files in file src/filemanager/cmd.c

This is a better workaround than using MMAP with O_NOFOLLOW in (both) open function calls.

But I'm still interested in a proper fix for this, which means it would have to handle a bunch of cases concerning symlinks and normal files being compared... Looks like I'd have to ensure they are being tested inside ./tests/src/filemanager to match the location of cmd.c.

Any hints are welcome, meanwhile I'm looking into it. Cheers! ;)

comment:11 in reply to: ↑ 10 ; follow-up: ↓ 12 Changed 6 months ago by andrew_b

Replying to howaboutsynergy:

There is a better workaround for this. Replacing #ifdef HAVE_MMAP with #if 0 in function compare_files in file src/filemanager/cmd.c

Just configure --with-mmap=no.

comment:12 in reply to: ↑ 11 Changed 6 months ago by howaboutsynergy

Replying to andrew_b:

Replying to howaboutsynergy:

There is a better workaround for this. Replacing #ifdef HAVE_MMAP with #if 0 in function compare_files in file src/filemanager/cmd.c

Just configure --with-mmap=no.

Thanks. I didn't know about that.

Looks like there's only one other use of mmap:

src/vfs/smbfs/helpers/include/local.h:116:/* if mmap is enabled, then this is the maximum size of file to use
src/vfs/smbfs/helpers/include/local.h:117:   the mmap code on. We don't want to mmap huge files as virtual
intl/gettextP.h:163:  /* 1 if the memory is mmap()ed, 0 if the memory is malloc()ed.  */
intl/gettextP.h:165:  /* Size of mmap()ed memory.  */
intl/loadmsgcat.c:471:# define mmap(addr, len, prot, flags, fd, offset) \
intl/loadmsgcat.c:845:  /* Now we are ready to load the file.  If mmap() is available we try
intl/loadmsgcat.c:847:  data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
intl/loadmsgcat.c:852:      /* mmap() call was successful.  */
intl/loadmsgcat.c:859:  /* If the data is not yet available (i.e. mmap'ed) we try to load
intl/xsize.h:41:   implementation that uses mmap --, it's recommended to use size_overflow_p()

Meanwhile, I think I can get some inspiration from exec_get_export_variables_ext.c on how to do the file comparison tests...
*by file comparison tests I mean calling compare_dir function from src/filemanager/cmd.c

Last edited 6 months ago by howaboutsynergy (previous) (diff)

comment:13 follow-up: ↓ 14 Changed 6 months ago by howaboutsynergy

before I get too deep into this, do you require real/full name before accepting patches? I ask because I see full names of the people at the top of the source files.

EDIT: I'm still messing around with check see the Details block in this https://github.com/libcheck/check/issues/187#issue-444185772

Last edited 6 months ago by howaboutsynergy (previous) (diff)

comment:14 in reply to: ↑ 13 ; follow-up: ↓ 15 Changed 6 months ago by andrew_b

Replying to howaboutsynergy:

do you require real/full name before accepting patches?

No. This is desirable but not required.

comment:15 in reply to: ↑ 14 Changed 6 months ago by howaboutsynergy

Replying to andrew_b:

Replying to howaboutsynergy:

do you require real/full name before accepting patches?

No. This is desirable but not required.

Awesome!

Here's an unrelated thing that I found and I think that maybe mc can fix, related to tests:
https://midnight-commander.org/ticket/3986

Note: See TracTickets for help on using tickets.