hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/tty/vt/vc_screen.c
....@@ -386,10 +386,6 @@
386386
387387 uni_mode = use_unicode(inode);
388388 attr = use_attributes(inode);
389
- ret = -ENXIO;
390
- vc = vcs_vc(inode, &viewed);
391
- if (!vc)
392
- goto unlock_out;
393389
394390 ret = -EINVAL;
395391 if (pos < 0)
....@@ -407,16 +403,20 @@
407403 unsigned int this_round, skip = 0;
408404 int size;
409405
406
+ vc = vcs_vc(inode, &viewed);
407
+ if (!vc) {
408
+ ret = -ENXIO;
409
+ break;
410
+ }
411
+
410412 /* Check whether we are above size each round,
411413 * as copy_to_user at the end of this loop
412414 * could sleep.
413415 */
414416 size = vcs_size(vc, attr, uni_mode);
415417 if (size < 0) {
416
- if (read)
417
- break;
418418 ret = size;
419
- goto unlock_out;
419
+ break;
420420 }
421421 if (pos >= size)
422422 break;
....@@ -656,10 +656,17 @@
656656 }
657657 }
658658
659
- /* The vcs_size might have changed while we slept to grab
660
- * the user buffer, so recheck.
659
+ /* The vc might have been freed or vcs_size might have changed
660
+ * while we slept to grab the user buffer, so recheck.
661661 * Return data written up to now on failure.
662662 */
663
+ vc = vcs_vc(inode, &viewed);
664
+ if (!vc) {
665
+ if (written)
666
+ break;
667
+ ret = -ENXIO;
668
+ goto unlock_out;
669
+ }
663670 size = vcs_size(vc, attr, false);
664671 if (size < 0) {
665672 if (written)