]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 May 2021 12:00:16 +0000 (14:00 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 May 2021 12:00:16 +0000 (14:00 +0200)
added patches:
leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch
qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch
tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch
vgacon-record-video-mode-changes-with-vt_resizex.patch
video-hgafb-fix-potential-null-pointer-dereference.patch
vt-fix-character-height-handling-with-vt_resizex.patch

queue-4.4/leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch [new file with mode: 0644]
queue-4.4/qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch [new file with mode: 0644]
queue-4.4/vgacon-record-video-mode-changes-with-vt_resizex.patch [new file with mode: 0644]
queue-4.4/video-hgafb-fix-potential-null-pointer-dereference.patch [new file with mode: 0644]
queue-4.4/vt-fix-character-height-handling-with-vt_resizex.patch [new file with mode: 0644]

diff --git a/queue-4.4/leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch b/queue-4.4/leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch
new file mode 100644 (file)
index 0000000..17b5213
--- /dev/null
@@ -0,0 +1,37 @@
+From 6647f7a06eb030a2384ec71f0bb2e78854afabfe Mon Sep 17 00:00:00 2001
+From: Phillip Potter <phil@philpotter.co.uk>
+Date: Mon, 3 May 2021 13:56:36 +0200
+Subject: leds: lp5523: check return value of lp5xx_read and jump to cleanup code
+
+From: Phillip Potter <phil@philpotter.co.uk>
+
+commit 6647f7a06eb030a2384ec71f0bb2e78854afabfe upstream.
+
+Check return value of lp5xx_read and if non-zero, jump to code at end of
+the function, causing lp5523_stop_all_engines to be executed before
+returning the error value up the call chain. This fixes the original
+commit (248b57015f35) which was reverted due to the University of Minnesota
+problems.
+
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
+Link: https://lore.kernel.org/r/20210503115736.2104747-10-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-lp5523.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/leds/leds-lp5523.c
++++ b/drivers/leds/leds-lp5523.c
+@@ -318,7 +318,9 @@ static int lp5523_init_program_engine(st
+       /* Let the programs run for couple of ms and check the engine status */
+       usleep_range(3000, 6000);
+-      lp55xx_read(chip, LP5523_REG_STATUS, &status);
++      ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
++      if (ret)
++              goto out;
+       status &= LP5523_ENG_STATUS_MASK;
+       if (status != LP5523_ENG_STATUS_MASK) {
diff --git a/queue-4.4/qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch b/queue-4.4/qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch
new file mode 100644 (file)
index 0000000..fbc347f
--- /dev/null
@@ -0,0 +1,44 @@
+From 84460f01cba382553199bc1361f69a872d5abed4 Mon Sep 17 00:00:00 2001
+From: Tom Seewald <tseewald@gmail.com>
+Date: Mon, 3 May 2021 13:56:52 +0200
+Subject: qlcnic: Add null check after calling netdev_alloc_skb
+
+From: Tom Seewald <tseewald@gmail.com>
+
+commit 84460f01cba382553199bc1361f69a872d5abed4 upstream.
+
+The function qlcnic_dl_lb_test() currently calls netdev_alloc_skb()
+without checking afterwards that the allocation succeeded. Fix this by
+checking if the skb is NULL and returning an error in such a case.
+Breaking out of the loop if the skb is NULL is not correct as no error
+would be reported to the caller and no message would be printed for the
+user.
+
+Cc: David S. Miller <davem@davemloft.net>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Tom Seewald <tseewald@gmail.com>
+Link: https://lore.kernel.org/r/20210503115736.2104747-26-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+@@ -1038,6 +1038,8 @@ int qlcnic_do_lb_test(struct qlcnic_adap
+       for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
+               skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
++              if (!skb)
++                      goto error;
+               qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
+               skb_put(skb, QLCNIC_ILB_PKT_SIZE);
+               adapter->ahw->diag_cnt = 0;
+@@ -1061,6 +1063,7 @@ int qlcnic_do_lb_test(struct qlcnic_adap
+                       cnt++;
+       }
+       if (cnt != i) {
++error:
+               dev_err(&adapter->pdev->dev,
+                       "LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
+               if (mode != QLCNIC_ILB_MODE)
index d0108dc6e6b697736eddc32442c64a79ec9ede3b..f8c8c2ef6aa8a9df62dc1f93d099b3a178df3d70 100644 (file)
@@ -23,3 +23,9 @@ revert-niu-fix-missing-checks-of-niu_pci_eeprom_read.patch
 ethernet-sun-niu-fix-missing-checks-of-niu_pci_eeprom_read.patch
 net-stmicro-handle-clk_prepare-failure-during-init.patch
 net-rtlwifi-properly-check-for-alloc_workqueue-failure.patch
+leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch
+qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch
+video-hgafb-fix-potential-null-pointer-dereference.patch
+vgacon-record-video-mode-changes-with-vt_resizex.patch
+vt-fix-character-height-handling-with-vt_resizex.patch
+tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch
diff --git a/queue-4.4/tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch b/queue-4.4/tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch
new file mode 100644 (file)
index 0000000..d5e53dd
--- /dev/null
@@ -0,0 +1,71 @@
+From ffb324e6f874121f7dce5bdae5e05d02baae7269 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Sat, 15 May 2021 03:00:37 +0000
+Subject: tty: vt: always invoke vc->vc_sw->con_resize callback
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit ffb324e6f874121f7dce5bdae5e05d02baae7269 upstream.
+
+syzbot is reporting OOB write at vga16fb_imageblit() [1], for
+resize_screen() from ioctl(VT_RESIZE) returns 0 without checking whether
+requested rows/columns fit the amount of memory reserved for the graphical
+screen if current mode is KD_GRAPHICS.
+
+----------
+  #include <sys/types.h>
+  #include <sys/stat.h>
+  #include <fcntl.h>
+  #include <sys/ioctl.h>
+  #include <linux/kd.h>
+  #include <linux/vt.h>
+
+  int main(int argc, char *argv[])
+  {
+        const int fd = open("/dev/char/4:1", O_RDWR);
+        struct vt_sizes vt = { 0x4100, 2 };
+
+        ioctl(fd, KDSETMODE, KD_GRAPHICS);
+        ioctl(fd, VT_RESIZE, &vt);
+        ioctl(fd, KDSETMODE, KD_TEXT);
+        return 0;
+  }
+----------
+
+Allow framebuffer drivers to return -EINVAL, by moving vc->vc_mode !=
+KD_GRAPHICS check from resize_screen() to fbcon_resize().
+
+Link: https://syzkaller.appspot.com/bug?extid=1f29e126cf461c4de3b3 [1]
+Reported-by: syzbot <syzbot+1f29e126cf461c4de3b3@syzkaller.appspotmail.com>
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Tested-by: syzbot <syzbot+1f29e126cf461c4de3b3@syzkaller.appspotmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/vt/vt.c           |    2 +-
+ drivers/video/console/fbcon.c |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -826,7 +826,7 @@ static inline int resize_screen(struct v
+       /* Resizes the resolution of the display adapater */
+       int err = 0;
+-      if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
++      if (vc->vc_sw->con_resize)
+               err = vc->vc_sw->con_resize(vc, width, height, user);
+       return err;
+--- a/drivers/video/console/fbcon.c
++++ b/drivers/video/console/fbcon.c
+@@ -1986,7 +1986,7 @@ static int fbcon_resize(struct vc_data *
+                       return -EINVAL;
+               DPRINTK("resize now %ix%i\n", var.xres, var.yres);
+-              if (CON_IS_VISIBLE(vc)) {
++              if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) {
+                       var.activate = FB_ACTIVATE_NOW |
+                               FB_ACTIVATE_FORCE;
+                       fb_set_var(info, &var);
diff --git a/queue-4.4/vgacon-record-video-mode-changes-with-vt_resizex.patch b/queue-4.4/vgacon-record-video-mode-changes-with-vt_resizex.patch
new file mode 100644 (file)
index 0000000..ddd9254
--- /dev/null
@@ -0,0 +1,65 @@
+From d4d0ad57b3865795c4cde2fb5094c594c2e8f469 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+Date: Thu, 13 May 2021 11:51:41 +0200
+Subject: vgacon: Record video mode changes with VT_RESIZEX
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+commit d4d0ad57b3865795c4cde2fb5094c594c2e8f469 upstream.
+
+Fix an issue with VGA console font size changes made after the initial
+video text mode has been changed with a user tool like `svgatextmode'
+calling the VT_RESIZEX ioctl.  As it stands in that case the original
+screen geometry continues being used to validate further VT resizing.
+
+Consequently when the video adapter is firstly reprogrammed from the
+original say 80x25 text mode using a 9x16 character cell (720x400 pixel
+resolution) to say 80x37 text mode and the same character cell (720x592
+pixel resolution), and secondly the CRTC character cell updated to 9x8
+(by loading a suitable font with the KD_FONT_OP_SET request of the
+KDFONTOP ioctl), the VT geometry does not get further updated from 80x37
+and only upper half of the screen is used for the VT, with the lower
+half showing rubbish corresponding to whatever happens to be there in
+the video memory that maps to that part of the screen.  Of course the
+proportions change according to text mode geometries and font sizes
+chosen.
+
+Address the problem then, by updating the text mode geometry defaults
+rather than checking against them whenever the VT is resized via a user
+ioctl.
+
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Fixes: e400b6ec4ede ("vt/vgacon: Check if screen resize request comes from userspace")
+Cc: stable@vger.kernel.org # v2.6.24+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/console/vgacon.c |   14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -1179,12 +1179,20 @@ static int vgacon_resize(struct vc_data
+       if ((width << 1) * height > vga_vram_size)
+               return -EINVAL;
++      if (user) {
++              /*
++               * Ho ho!  Someone (svgatextmode, eh?) may have reprogrammed
++               * the video mode!  Set the new defaults then and go away.
++               */
++              screen_info.orig_video_cols = width;
++              screen_info.orig_video_lines = height;
++              vga_default_font_height = c->vc_font.height;
++              return 0;
++      }
+       if (width % 2 || width > screen_info.orig_video_cols ||
+           height > (screen_info.orig_video_lines * vga_default_font_height)/
+           c->vc_font.height)
+-              /* let svgatextmode tinker with video timings and
+-                 return success */
+-              return (user) ? 0 : -EINVAL;
++              return -EINVAL;
+       if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */
+               vgacon_doresize(c, width, height);
diff --git a/queue-4.4/video-hgafb-fix-potential-null-pointer-dereference.patch b/queue-4.4/video-hgafb-fix-potential-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..572c252
--- /dev/null
@@ -0,0 +1,76 @@
+From dc13cac4862cc68ec74348a80b6942532b7735fa Mon Sep 17 00:00:00 2001
+From: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
+Date: Mon, 3 May 2021 13:57:06 +0200
+Subject: video: hgafb: fix potential NULL pointer dereference
+
+From: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
+
+commit dc13cac4862cc68ec74348a80b6942532b7735fa upstream.
+
+The return of ioremap if not checked, and can lead to a NULL to be
+assigned to hga_vram. Potentially leading to a NULL pointer
+dereference.
+
+The fix adds code to deal with this case in the error label and
+changes how the hgafb_probe handles the return of hga_card_detect.
+
+Cc: Ferenc Bakonyi <fero@drama.obuda.kando.hu>
+Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
+Link: https://lore.kernel.org/r/20210503115736.2104747-40-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/hgafb.c |   21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/video/fbdev/hgafb.c
++++ b/drivers/video/fbdev/hgafb.c
+@@ -285,6 +285,8 @@ static int hga_card_detect(void)
+       hga_vram_len  = 0x08000;
+       hga_vram = ioremap(0xb0000, hga_vram_len);
++      if (!hga_vram)
++              return -ENOMEM;
+       if (request_region(0x3b0, 12, "hgafb"))
+               release_io_ports = 1;
+@@ -344,13 +346,18 @@ static int hga_card_detect(void)
+                       hga_type_name = "Hercules";
+                       break;
+       }
+-      return 1;
++      return 0;
+ error:
+       if (release_io_ports)
+               release_region(0x3b0, 12);
+       if (release_io_port)
+               release_region(0x3bf, 1);
+-      return 0;
++
++      iounmap(hga_vram);
++
++      pr_err("hgafb: HGA card not detected.\n");
++
++      return -EINVAL;
+ }
+ /**
+@@ -548,13 +555,11 @@ static struct fb_ops hgafb_ops = {
+ static int hgafb_probe(struct platform_device *pdev)
+ {
+       struct fb_info *info;
++      int ret;
+-      if (! hga_card_detect()) {
+-              printk(KERN_INFO "hgafb: HGA card not detected.\n");
+-              if (hga_vram)
+-                      iounmap(hga_vram);
+-              return -EINVAL;
+-      }
++      ret = hga_card_detect();
++      if (!ret)
++              return ret;
+       printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n",
+               hga_type_name, hga_vram_len/1024);
diff --git a/queue-4.4/vt-fix-character-height-handling-with-vt_resizex.patch b/queue-4.4/vt-fix-character-height-handling-with-vt_resizex.patch
new file mode 100644 (file)
index 0000000..850e313
--- /dev/null
@@ -0,0 +1,226 @@
+From 860dafa902595fb5f1d23bbcce1215188c3341e6 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+Date: Thu, 13 May 2021 11:51:50 +0200
+Subject: vt: Fix character height handling with VT_RESIZEX
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+commit 860dafa902595fb5f1d23bbcce1215188c3341e6 upstream.
+
+Restore the original intent of the VT_RESIZEX ioctl's `v_clin' parameter
+which is the number of pixel rows per character (cell) rather than the
+height of the font used.
+
+For framebuffer devices the two values are always the same, because the
+former is inferred from the latter one.  For VGA used as a true text
+mode device these two parameters are independent from each other: the
+number of pixel rows per character is set in the CRT controller, while
+font height is in fact hardwired to 32 pixel rows and fonts of heights
+below that value are handled by padding their data with blanks when
+loaded to hardware for use by the character generator.  One can change
+the setting in the CRT controller and it will update the screen contents
+accordingly regardless of the font loaded.
+
+The `v_clin' parameter is used by the `vgacon' driver to set the height
+of the character cell and then the cursor position within.  Make the
+parameter explicit then, by defining a new `vc_cell_height' struct
+member of `vc_data', set it instead of `vc_font.height' from `v_clin' in
+the VT_RESIZEX ioctl, and then use it throughout the `vgacon' driver
+except where actual font data is accessed which as noted above is
+independent from the CRTC setting.
+
+This way the framebuffer console driver is free to ignore the `v_clin'
+parameter as irrelevant, as it always should have, avoiding any issues
+attempts to give the parameter a meaning there could have caused, such
+as one that has led to commit 988d0763361b ("vt_ioctl: make VT_RESIZEX
+behave like VT_RESIZE"):
+
+ "syzbot is reporting UAF/OOB read at bit_putcs()/soft_cursor() [1][2],
+  for vt_resizex() from ioctl(VT_RESIZEX) allows setting font height
+  larger than actual font height calculated by con_font_set() from
+  ioctl(PIO_FONT). Since fbcon_set_font() from con_font_set() allocates
+  minimal amount of memory based on actual font height calculated by
+  con_font_set(), use of vt_resizex() can cause UAF/OOB read for font
+  data."
+
+The problem first appeared around Linux 2.5.66 which predates our repo
+history, but the origin could be identified with the old MIPS/Linux repo
+also at: <git://git.kernel.org/pub/scm/linux/kernel/git/ralf/linux.git>
+as commit 9736a3546de7 ("Merge with Linux 2.5.66."), where VT_RESIZEX
+code in `vt_ioctl' was updated as follows:
+
+               if (clin)
+-                      video_font_height = clin;
++                      vc->vc_font.height = clin;
+
+making the parameter apply to framebuffer devices as well, perhaps due
+to the use of "font" in the name of the original `video_font_height'
+variable.  Use "cell" in the new struct member then to avoid ambiguity.
+
+References:
+
+[1] https://syzkaller.appspot.com/bug?id=32577e96d88447ded2d3b76d71254fb855245837
+[2] https://syzkaller.appspot.com/bug?id=6b8355d27b2b94fb5cedf4655e3a59162d9e48e3
+
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org # v2.6.12+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/vt/vt_ioctl.c      |    6 ++---
+ drivers/video/console/vgacon.c |   44 ++++++++++++++++++++---------------------
+ include/linux/console_struct.h |    1 
+ 3 files changed, 26 insertions(+), 25 deletions(-)
+
+--- a/drivers/tty/vt/vt_ioctl.c
++++ b/drivers/tty/vt/vt_ioctl.c
+@@ -898,17 +898,17 @@ int vt_ioctl(struct tty_struct *tty,
+                       if (vcp) {
+                               int ret;
+                               int save_scan_lines = vcp->vc_scan_lines;
+-                              int save_font_height = vcp->vc_font.height;
++                              int save_cell_height = vcp->vc_cell_height;
+                               if (v.v_vlin)
+                                       vcp->vc_scan_lines = v.v_vlin;
+                               if (v.v_clin)
+-                                      vcp->vc_font.height = v.v_clin;
++                                      vcp->vc_cell_height = v.v_clin;
+                               vcp->vc_resize_user = 1;
+                               ret = vc_resize(vcp, v.v_cols, v.v_rows);
+                               if (ret) {
+                                       vcp->vc_scan_lines = save_scan_lines;
+-                                      vcp->vc_font.height = save_font_height;
++                                      vcp->vc_cell_height = save_cell_height;
+                                       console_unlock();
+                                       return ret;
+                               }
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -436,7 +436,7 @@ static void vgacon_init(struct vc_data *
+               vc_resize(c, vga_video_num_columns, vga_video_num_lines);
+       c->vc_scan_lines = vga_scan_lines;
+-      c->vc_font.height = vga_video_font_height;
++      c->vc_font.height = c->vc_cell_height = vga_video_font_height;
+       c->vc_complement_mask = 0x7700;
+       if (vga_512_chars)
+               c->vc_hi_font_mask = 0x0800;
+@@ -574,32 +574,32 @@ static void vgacon_cursor(struct vc_data
+               switch (c->vc_cursor_type & 0x0f) {
+               case CUR_UNDERLINE:
+                       vgacon_set_cursor_size(c->vc_x,
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 2 : 3),
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 1 : 2));
+                       break;
+               case CUR_TWO_THIRDS:
+                       vgacon_set_cursor_size(c->vc_x,
+-                                             c->vc_font.height / 3,
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             c->vc_cell_height / 3,
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 1 : 2));
+                       break;
+               case CUR_LOWER_THIRD:
+                       vgacon_set_cursor_size(c->vc_x,
+-                                             (c->vc_font.height * 2) / 3,
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             (c->vc_cell_height * 2) / 3,
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 1 : 2));
+                       break;
+               case CUR_LOWER_HALF:
+                       vgacon_set_cursor_size(c->vc_x,
+-                                             c->vc_font.height / 2,
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             c->vc_cell_height / 2,
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 1 : 2));
+                       break;
+               case CUR_NONE:
+@@ -610,7 +610,7 @@ static void vgacon_cursor(struct vc_data
+                       break;
+               default:
+                       vgacon_set_cursor_size(c->vc_x, 1,
+-                                             c->vc_font.height);
++                                             c->vc_cell_height);
+                       break;
+               }
+               break;
+@@ -621,13 +621,13 @@ static int vgacon_doresize(struct vc_dat
+               unsigned int width, unsigned int height)
+ {
+       unsigned long flags;
+-      unsigned int scanlines = height * c->vc_font.height;
++      unsigned int scanlines = height * c->vc_cell_height;
+       u8 scanlines_lo = 0, r7 = 0, vsync_end = 0, mode, max_scan;
+       raw_spin_lock_irqsave(&vga_lock, flags);
+       vgacon_xres = width * VGA_FONTWIDTH;
+-      vgacon_yres = height * c->vc_font.height;
++      vgacon_yres = height * c->vc_cell_height;
+       if (vga_video_type >= VIDEO_TYPE_VGAC) {
+               outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
+               max_scan = inb_p(vga_video_port_val);
+@@ -682,9 +682,9 @@ static int vgacon_doresize(struct vc_dat
+ static int vgacon_switch(struct vc_data *c)
+ {
+       int x = c->vc_cols * VGA_FONTWIDTH;
+-      int y = c->vc_rows * c->vc_font.height;
++      int y = c->vc_rows * c->vc_cell_height;
+       int rows = screen_info.orig_video_lines * vga_default_font_height/
+-              c->vc_font.height;
++              c->vc_cell_height;
+       /*
+        * We need to save screen size here as it's the only way
+        * we can spot the screen has been resized and we need to
+@@ -1125,7 +1125,7 @@ static int vgacon_adjust_height(struct v
+                               cursor_size_lastto = 0;
+                               c->vc_sw->con_cursor(c, CM_DRAW);
+                       }
+-                      c->vc_font.height = fontheight;
++                      c->vc_font.height = c->vc_cell_height = fontheight;
+                       vc_resize(c, 0, rows);  /* Adjust console size */
+               }
+       }
+@@ -1186,12 +1186,12 @@ static int vgacon_resize(struct vc_data
+                */
+               screen_info.orig_video_cols = width;
+               screen_info.orig_video_lines = height;
+-              vga_default_font_height = c->vc_font.height;
++              vga_default_font_height = c->vc_cell_height;
+               return 0;
+       }
+       if (width % 2 || width > screen_info.orig_video_cols ||
+           height > (screen_info.orig_video_lines * vga_default_font_height)/
+-          c->vc_font.height)
++          c->vc_cell_height)
+               return -EINVAL;
+       if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */
+--- a/include/linux/console_struct.h
++++ b/include/linux/console_struct.h
+@@ -29,6 +29,7 @@ struct vc_data {
+       unsigned int    vc_rows;
+       unsigned int    vc_size_row;            /* Bytes per row */
+       unsigned int    vc_scan_lines;          /* # of scan lines */
++      unsigned int    vc_cell_height;         /* CRTC character cell height */
+       unsigned long   vc_origin;              /* [!] Start of real screen */
+       unsigned long   vc_scr_end;             /* [!] End of real screen */
+       unsigned long   vc_visible_origin;      /* [!] Top of visible window */