diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/tty/vt/vc_screen.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index bf1502fd5..79453abcf 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -631,6 +631,18 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) ret = copy_from_user(con_buf, buf, this_round); console_lock(); + /* The vc might have been freed or vcs_size might have changed + * while we slept to grab the user buffer; recheck here, before + * if (ret), so every break path below passes a fresh vc to the + * post-loop vcs_scr_updated(). Return data written so far. + */ + vc = vcs_vc(inode, &viewed); + if (!vc) { + if (written) + break; + return -ENXIO; + } + if (ret) { this_round -= ret; if (!this_round) { @@ -642,17 +654,6 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) return -EFAULT; } } - - /* The vc might have been freed or vcs_size might have changed - * while we slept to grab the user buffer, so recheck. - * Return data written up to now on failure. - */ - vc = vcs_vc(inode, &viewed); - if (!vc) { - if (written) - break; - return -ENXIO; - } size = vcs_size(vc, attr, false); if (size < 0) { if (written) |
