diff --git a/doc/sudo_plugin.cat b/doc/sudo_plugin.cat
index 0bb30f2ec..2187ecf21 100644
--- a/doc/sudo_plugin.cat
+++ b/doc/sudo_plugin.cat
@@ -867,6 +867,7 @@ DDEESSCCRRIIPPTTIIOONN
             int (*register_hook)(struct sudo_hook *hook));
          void (*deregister_hooks)(int version,
             int (*deregister_hook)(struct sudo_hook *hook));
+         int (*change_winsize)(unsigned int lines, unsigned int cols);
      };
 
      When an I/O plugin is loaded, ssuuddoo runs the command in a pseudo-tty.
@@ -1124,6 +1125,14 @@ DDEESSCCRRIIPPTTIIOONN
            See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a description of
            deregister_hooks.
 
+     change_winsize
+           int (*change_winsize)(unsigned int lines, unsigned int cols);
+
+           The cchhaannggee__wwiinnssiizzee() function is called whenever the window size of
+           the terminal changes from the initial values specified in the
+           user_info list.  It returns 1 on success, 0 on failure, -1 if an
+           error occurred (which will terminate the running command).
+
      _I_/_O _P_l_u_g_i_n _V_e_r_s_i_o_n _M_a_c_r_o_s
 
      Same as for the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I.
@@ -1563,6 +1572,9 @@ PPLLUUGGIINN AAPPII CCHHAANNGGEELLOOGG
      Version 1.11 (sudo 1.8.20)
            The _t_i_m_e_o_u_t entry was added to the settings list.
 
+     Version 1.12 (sudo 1.8.21)
+           The change_winsize field was added to the io_plugin struct.
+
 SSEEEE AALLSSOO
      sudo.conf(4), sudoers(4), sudo(1m)
 
@@ -1592,4 +1604,4 @@ DDIISSCCLLAAIIMMEERR
      file distributed with ssuuddoo or https://www.sudo.ws/license.html for
      complete details.
 
-Sudo 1.8.21                      June 2, 2017                      Sudo 1.8.21
+Sudo 1.8.21                      July 11, 2017                     Sudo 1.8.21
diff --git a/doc/sudo_plugin.man.in b/doc/sudo_plugin.man.in
index 4e169fccc..c4f038103 100644
--- a/doc/sudo_plugin.man.in
+++ b/doc/sudo_plugin.man.in
@@ -16,7 +16,7 @@
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.TH "SUDO_PLUGIN" "5" "June 2, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.TH "SUDO_PLUGIN" "5" "July 11, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
 .nh
 .if n .ad l
 .SH "NAME"
@@ -1470,6 +1470,7 @@ struct io_plugin {
        int (*register_hook)(struct sudo_hook *hook));
     void (*deregister_hooks)(int version,
        int (*deregister_hook)(struct sudo_hook *hook));
+    int (*change_winsize)(unsigned int lines, unsigned int cols);
 };
 .RE
 .fi
@@ -1976,6 +1977,24 @@ See the
 \fIPolicy plugin API\fR
 section for a description of
 \fRderegister_hooks.\fR
+.TP 6n
+change_winsize
+.nf
+.RS 6n
+int (*change_winsize)(unsigned int lines, unsigned int cols);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBchange_winsize\fR()
+function is called whenever the window size of the terminal changes from
+the initial values specified in the
+\fRuser_info\fR
+list.
+It returns 1 on success, 0 on failure, \-1 if an error occurred (which
+will terminate the running command).
+.RE
 .PP
 \fII/O Plugin Version Macros\fR
 .PP
@@ -2794,6 +2813,11 @@ The
 entry was added to the
 \fRsettings\fR
 list.
+.TP 6n
+Version 1.12 (sudo 1.8.21)
+The
+\fRchange_winsize\fR
+field was added to the io_plugin struct.
 .SH "SEE ALSO"
 sudo.conf(@mansectform@),
 sudoers(@mansectform@),
diff --git a/doc/sudo_plugin.mdoc.in b/doc/sudo_plugin.mdoc.in
index 285ca6e55..d8bc3b910 100644
--- a/doc/sudo_plugin.mdoc.in
+++ b/doc/sudo_plugin.mdoc.in
@@ -14,7 +14,7 @@
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 2, 2017
+.Dd July 11, 2017
 .Dt SUDO_PLUGIN @mansectform@
 .Os Sudo @PACKAGE_VERSION@
 .Sh NAME
@@ -1298,6 +1298,7 @@ struct io_plugin {
        int (*register_hook)(struct sudo_hook *hook));
     void (*deregister_hooks)(int version,
        int (*deregister_hook)(struct sudo_hook *hook));
+    int (*change_winsize)(unsigned int lines, unsigned int cols);
 };
 .Ed
 .Pp
@@ -1730,6 +1731,19 @@ See the
 .Sx Policy plugin API
 section for a description of
 .Li deregister_hooks.
+.It change_winsize
+.Bd -literal -compact
+int (*change_winsize)(unsigned int lines, unsigned int cols);
+.Ed
+.Pp
+The
+.Fn change_winsize
+function is called whenever the window size of the terminal changes from
+the initial values specified in the
+.Li user_info
+list.
+It returns 1 on success, 0 on failure, \-1 if an error occurred (which
+will terminate the running command).
 .El
 .Pp
 .Em I/O Plugin Version Macros
@@ -2447,6 +2461,10 @@ The
 entry was added to the
 .Li settings
 list.
+.It Version 1.12 (sudo 1.8.21)
+The
+.Li change_winsize
+field was added to the io_plugin struct.
 .El
 .Sh SEE ALSO
 .Xr sudo.conf @mansectform@ ,
diff --git a/include/sudo_plugin.h b/include/sudo_plugin.h
index 309e2963b..a15ce1882 100644
--- a/include/sudo_plugin.h
+++ b/include/sudo_plugin.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2016 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2009-2017 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,7 +19,7 @@
 
 /* API version major/minor */
 #define SUDO_API_VERSION_MAJOR 1
-#define SUDO_API_VERSION_MINOR 11
+#define SUDO_API_VERSION_MINOR 12
 #define SUDO_API_MKVERSION(x, y) (((x) << 16) | (y))
 #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
 
@@ -168,6 +168,7 @@ struct io_plugin {
     int (*log_stderr)(const char *buf, unsigned int len);
     void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
     void (*deregister_hooks)(int version, int (*deregister_hook)(struct sudo_hook *hook));
+    int (*change_winsize)(unsigned int rows, unsigned int cols);
 };
 
 /* Sudoers group plugin version major/minor */
diff --git a/src/exec_pty.c b/src/exec_pty.c
index d8efb2979..c7cb64303 100644
--- a/src/exec_pty.c
+++ b/src/exec_pty.c
@@ -362,6 +362,38 @@ log_stderr(const char *buf, unsigned int n, struct io_buffer *iob)
     debug_return_bool(ret);
 }
 
+/* Call I/O plugin stderr log method. */
+static void
+log_winchange(unsigned int rows, unsigned int cols)
+{
+    struct plugin_container *plugin;
+    sigset_t omask;
+    debug_decl(log_winchange, SUDO_DEBUG_EXEC);
+
+    sigprocmask(SIG_BLOCK, &ttyblock, &omask);
+    TAILQ_FOREACH(plugin, &io_plugins, entries) {
+	if (plugin->u.io->version < SUDO_API_MKVERSION(1, 12))
+	    continue;
+	if (plugin->u.io->change_winsize) {
+	    int rc;
+
+	    sudo_debug_set_active_instance(plugin->debug_instance);
+	    rc = plugin->u.io->change_winsize(rows, cols);
+	    if (rc <= 0) {
+		if (rc < 0) {
+		    /* Error: disable plugin's I/O function. */
+		    plugin->u.io->change_winsize = NULL;
+		}
+		break;
+	    }
+	}
+    }
+    sudo_debug_set_active_instance(sudo_debug_instance);
+    sigprocmask(SIG_SETMASK, &omask, NULL);
+
+    debug_return;
+}
+
 /*
  * Check whether we are running in the foregroup.
  * Updates the foreground global and does lazy init of the
@@ -376,8 +408,8 @@ check_foreground(pid_t ppgrp)
 	foreground = tcgetpgrp(io_fds[SFD_USERTTY]) == ppgrp;
 	if (foreground && !tty_initialized) {
 	    if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
-		tty_initialized = true;
 		sync_ttysize(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE]);
+		tty_initialized = true;
 	    }
 	}
     }
@@ -1266,8 +1298,8 @@ exec_pty(struct command_details *details, struct command_status *cstat)
     if (foreground) {
 	/* Copy terminal attrs from user tty -> pty slave. */
 	if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
-	    tty_initialized = true;
 	    sync_ttysize(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE]);
+	    tty_initialized = true;
 	}
 
 	/* Start out in raw mode unless part of a pipeline or backgrounded. */
@@ -1516,7 +1548,8 @@ del_io_events(bool nonblocking)
 }
 
 /*
- * Propagates tty size change signals to pty being used by the command.
+ * Propagates tty size change signals to pty being used by the command
+ * and passes new window size to the I/O plugin.
  */
 static void
 sync_ttysize(int src, int dst)
@@ -1526,9 +1559,12 @@ sync_ttysize(int src, int dst)
     debug_decl(sync_ttysize, SUDO_DEBUG_EXEC);
 
     if (ioctl(src, TIOCGWINSZ, &wsize) == 0) {
-	    ioctl(dst, TIOCSWINSZ, &wsize);
+	    (void)ioctl(dst, TIOCSWINSZ, &wsize);
 	    if ((pgrp = tcgetpgrp(dst)) != -1)
 		killpg(pgrp, SIGWINCH);
+
+	    if (tty_initialized)
+		log_winchange(wsize.ws_row, wsize.ws_col);
     }
 
     debug_return;
