Hi tech@

attaching a fix for the following crash caused by a null pointer dereference
while the modeline is trying to work on a unusable display

#0  0x00000bf6a4e04433 in modeline (wp=0xbf948d9d400, modelinecolor=2) at 
display.c:800
800             vscreen[n]->v_color = modelinecolor;    /* Mode line color.     
 */
(gdb) bt
#0  0x00000bf6a4e04433 in modeline (wp=0xbf948d9d400, modelinecolor=2) at 
display.c:800
#1  0x00000bf6a4e04ecf in update (modelinecolor=2) at display.c:501
#2  0x00000bf6a4e0ee28 in main (argc=Variable "argc" is not available.
) at main.c:199

quite easy to reproduce:
 1. start a tmux session
 2. split the screen in half (^B ")
 3. start mg in one screen
 4. resize the mg screen to 2 lines (smallest allow by tmux)
 5. by now tmux should be showing unusable display
 6. type something or do a modeline command
segfault.

The interesting thing is that mg works without a crash if it's started from
a 2 line display regardless of what you do. So I am having doubts how sane
that check for 'unusable' display is.

I also assume there might be more places that die when trying to work
with an unusable display (I didn't find/hit them yet).

Thinking about it made me try another diff. Which removes the 'window is 
unusable'
check completely. So far I havent seen a single crash with it and I can resize
the window down to 2 lines and back.

I guess I'm asking for an OK for the second diff (or a reason why we should not)
versus OK'ing the first one :)

Regards,
awolk
Index: display.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/display.c,v
retrieving revision 1.47
diff -u -p -r1.47 display.c
--- display.c   3 Apr 2015 22:10:29 -0000       1.47
+++ display.c   6 Sep 2016 21:15:51 -0000
@@ -797,6 +797,8 @@ modeline(struct mgwin *wp, int modelinec
        int len;
 
        n = wp->w_toprow + wp->w_ntrows;        /* Location.             */
+       if (!vscreen[n])
+               return;
        vscreen[n]->v_color = modelinecolor;    /* Mode line color.      */
        vscreen[n]->v_flag |= (VFCHG | VFHBAD); /* Recompute, display.   */
        vtmove(n, 0);                           /* Seek to right line.   */
Index: window.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/window.c,v
retrieving revision 1.36
diff -u -p -r1.36 window.c
--- window.c    18 Nov 2015 18:21:06 -0000      1.36
+++ window.c    6 Sep 2016 21:29:48 -0000
@@ -89,12 +89,6 @@ do_redraw(int f, int n, int force)
                while (wp->w_wndp != NULL)
                        wp = wp->w_wndp;
 
-               /* check if too small */
-               if (nrow < wp->w_toprow + 3) {
-                       dobeep();
-                       ewprintf("Display unusable");
-                       return (FALSE);
-               }
                wp->w_ntrows = nrow - wp->w_toprow - 2;
                sgarbf = TRUE;
                update(CMODE);

Reply via email to