wresize has a check that the current y/x coordinate (eg, _cury) is <= the new
size of the window (eg, _maxy), but this is incorrect since the y/x coordinate
is 0-based. As a result, after shrinking a window, if the current coordinates
were outside of the new size, a call to PDCurses may attempt to read and write
to regions outside the _y array. In the best case, this crashes, but it might
also have security implications for some applications.
I have attached a patch that fixes the bug in a clear and simple way, as well
as a patch for my own application to workaround the bug (as a reference to
other developers).
--- pdcurses/window.c 2013-10-03 05:28:08.000000000 +0000
+++ pdcurses/window.c 2013-10-03 05:28:18.000000000 +0000
@@ -464,8 +464,8 @@
return (WINDOW *)NULL;
}
- save_curx = min(win->_curx, new->_maxx);
- save_cury = min(win->_cury, new->_maxy);
+ save_curx = min(win->_curx, new->_maxx - 1);
+ save_cury = min(win->_cury, new->_maxy - 1);
if (!(win->_flags & (_SUBPAD|_SUBWIN)))
{
commit 71adb9549684ce2424d1c0f5ce6b1d68829c3267
Author: Luke Dashjr <[email protected]>
Date: Thu Oct 3 06:23:12 2013 +0000
Workaround bug in PDCurses wresize
If the current cursor position fell outside the new window dimensions, it would be moved to just-outside - which is still outside
We can workaround this by checking if it is outside, and moving it inside if so
diff --git a/libblkmaker b/libblkmaker
index 19847fb..bca8f6f 160000
--- a/libblkmaker
+++ b/libblkmaker
@@ -1 +1 @@
-Subproject commit 19847fbab02450fb0db2ae519a35808cdc091991
+Subproject commit bca8f6f5e56c547e9bbc808fb644152e44f3344d
diff --git a/miner.c b/miner.c
index bd4574f..9d73d4c 100644
--- a/miner.c
+++ b/miner.c
@@ -2000,6 +2000,28 @@ int my_cancellable_getch(void)
return rv;
}
+
+#ifdef PDCURSES
+static
+int bfg_wresize(WINDOW *win, int lines, int columns)
+{
+ int rv = wresize(win, lines, columns);
+ int x, y;
+ getyx(win, y, x);
+ if (unlikely(y >= lines || x >= columns))
+ {
+ if (y >= lines)
+ y = lines - 1;
+ if (x >= columns)
+ x = columns - 1;
+ wmove(win, y, x);
+ }
+ return rv;
+}
+#else
+# define bfg_wresize wresize
+#endif
+
#endif
void tailsprintf(char *f, const char *fmt, ...)
@@ -2359,14 +2381,14 @@ static inline void change_logwinsize(void)
statusy = logstart;
logcursor = statusy + 1;
mvwin(logwin, logcursor, 0);
- wresize(statuswin, statusy, x);
+ bfg_wresize(statuswin, statusy, x);
}
y -= logcursor;
getmaxyx(logwin, logy, logx);
/* Detect screen size change */
if (x != logx || y != logy)
- wresize(logwin, y, x);
+ bfg_wresize(logwin, y, x);
}
static void check_winsizes(void)
@@ -2383,10 +2405,10 @@ static void check_winsizes(void)
else
statusy = logstart;
logcursor = statusy + 1;
- wresize(statuswin, statusy, x);
+ bfg_wresize(statuswin, statusy, x);
getmaxyx(mainwin, y, x);
y -= logcursor;
- wresize(logwin, y, x);
+ bfg_wresize(logwin, y, x);
mvwin(logwin, logcursor, 0);
unlock_curses();
}