NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/55468: vi(1) dumps core when type werase (Ctrl+W)



>Number:         55468
>Category:       bin
>Synopsis:       vi(1) dumps core when type werase (Ctrl+W)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jul 07 09:15:00 +0000 2020
>Originator:     Azuma OKAMOTO
>Release:        9.0_STABLE
>Organization:
>Environment:
NetBSD ringo.iwate.ceres.ne.jp 9.0_STABLE NetBSD 9.0_STABLE (GENERIC) #0: Thu Mar 26 13:01:08 JST 2020  root%ringo.iwate.ceres.ne.jp@localhost:/usr/src/sys/arch/macppc/compile/GENERIC macppc
>Description:
When you launch vi, insert some characters and then immediately erase them with Ctrl+W, it will terminate abnormally.
>How-To-Repeat:
$ uname -srm
NetBSD 9.0_STABLE macppc
$ vi

i (insert mode)
abc
Ctrl+W

Segmentation fault (core dumped)
$ gdb /usr/bin/vi vi.core
GNU gdb (GDB) 8.3
...
[New process 1]
Core was generated by `vi'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0183cea0 in v_txt ()
(gdb) bt
#0  0x0183cea0 in v_txt ()
#1  0x01834484 in v_ii ()
#2  0x01841100 in vi ()
#3  0x01827760 in editor ()
#4  0x01854044 in main ()
(gdb)

Some archs don't show it, 
but you can check it by using libefence (pkgsrc/devel/electric-fence).
$ uname -srm
NetBSD 9.0_STABLE amd64
$ LD_PRELOAD=/usr/pkg/lib/libefence.so EF_PROTECT_BELOW=1 vi

>Fix:
The following patch may improve this (freebsd's nvi2 and openbsd's nvi-1.79 have same fix).
Nvi2 contains more fixes, so switching to it is a good option.

--- external/bsd/nvi/dist/vi/v_txt.c.ORIG  2018-08-07 17:05:47.000000000 +0900
+++ external/bsd/nvi/dist/vi/v_txt.c  2020-07-07 16:33:53.624882795 +0900
@@ -1137,13 +1137,13 @@
                        if (tp->cno > max)
                                tmp = inword((UCHAR_T)tp->lb[tp->cno - 1]);
                        while (tp->cno > max) {
+                               if (tmp != inword((UCHAR_T)tp->lb[tp->cno - 1])
+                                   || ISBLANK((UCHAR_T)tp->lb[tp->cno - 1]))
+                                       break;
                                --tp->cno;
                                ++tp->owrite;
                                if (FL_ISSET(is_flags, IS_RUNNING))
                                        tp->lb[tp->cno] = ' ';
-                               if (tmp != inword((UCHAR_T)tp->lb[tp->cno - 1])
-                                   || ISBLANK((UCHAR_T)tp->lb[tp->cno - 1]))
-                                       break;
                        }
                }



Home | Main Index | Thread Index | Old Index