Skip to content

Attempting to recover non-existent swapfile segfaults #9503

@raffitz

Description

@raffitz

@goncalor brought to my attention that trying to recover a non-existent swapfile such as foo.swp results in a segfault.

  • nvim --version:
NVIM v0.3.4
Build type: Release
LuaJIT 2.0.5
Compilation: /usr/bin/cc -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt -Wconversion -O2 -DNDEBUG -DMIN_LOG_LEVEL=3 -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fdiagnostics-color=auto -Wno-array-bounds -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -I/build/neovim/src/build/config -I/build/neovim/src/neovim-0.3.4/src -I/usr/include -I/build/neovim/src/build/src/nvim/auto -I/build/neovim/src/build/include
Compiled by builduser

Also tried with:

NVIM v0.4.0-145-g89d7e2489
Build type: RelWithDebInfo
LuaJIT 2.0.5
Compilation: /usr/bin/cc -Wshadow -Wconversion -O2 -g -DMIN_LOG_LEVEL=3 -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fdiagnostics-color=auto -Wno-array-bounds -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_UNIBI_HAS_VAR_FROM -I/home/raffitz/Documents/Programming/neovim/build/config -I/home/raffitz/Documents/Programming/neovim/src -I/home/raffitz/Documents/Programming/neovim/.deps/usr/include -I/usr/include -I/home/raffitz/Documents/Programming/neovim/build/src/nvim/auto -I/home/raffitz/Documents/Programming/neovim/build/include
Compiled by raffitz@archduke
  • Vim (version: ) behaves differently?
    Vim displays E306: Cannot open foo.swp, and does not segfault.
    Vim version is:
VIM - Vi IMproved 8.1 (2018 May 18, compiled Dec  8 2018 11:23:48)
Included patches: 1-570
Compiled by Arch Linux
Huge version with GTK3 GUI.  Features included (+) or not (-):
(...)
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK  -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/lib/libffi-3.2.1/include -I/usr/include/fribidi -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/uuid -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/gio-unix-2.0 -I/usr/include/libdrm -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -pthread  -D_FORTIFY_SOURCE=2  -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1       
Linking: gcc   -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector -rdynamic -Wl,-export-dynamic -Wl,-E -Wl,-rpath,/usr/lib/perl5/5.28/core_perl/CORE  -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -L/usr/local/lib -Wl,--as-needed -o vim   -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0  -lSM -lICE -lXt -lX11 -lXdmcp -lSM -lICE  -lm -ltinfo -lelf -lnsl    -lacl -lattr -lgpm -ldl   -Wl,-E -Wl,-rpath,/usr/lib/perl5/5.28/core_perl/CORE -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -L/usr/local/lib  -L/usr/lib/perl5/5.28/core_perl/CORE -lperl -lpthread -ldl -lm -lcrypt -lutil -lc   -L/usr/lib -ltclstub8.6 -ldl -lz -lpthread -lm
  • Operating system/version: Arch Linux
  • Terminal name/version: Happens consistently regardless of tty emulator.
  • $TERM: see above

Steps to reproduce using nvim -u NORC

Making sure that foo.swp doesn't exist,

nvim -u NORC -r foo.swp

Actual behaviour

neovim segfaults.

GDB backtrace is:

#0  0x00005555556d0651 in ml_recover ()
#1  0x00005555555bbd67 in main ()

A brief run-through with gdb shows the following:
ml_recover() calls mf_open().
mf_open() calls mf_do_open(), which returns false (as it should).
Thus, mf_open() returns NULL rather than a pointer to a mfp_T struct.
However, ml_recover() does not check whether the mfp is NULL, and tries to check whether mfp->mf_fd < 0, trying to access a null pointer, resulting in a nice segfault.

Expected behaviour

neovim should show E306: Cannot open foo.swp and not segfault.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions