From: Zbigniew Jędrzejewski-Szmek Date: Thu, 27 Oct 2016 00:26:32 +0000 (-0400) Subject: Merge pull request #4448 from msoltyspl/vcfix X-Git-Tag: v232~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a5eebcff3732e2f6d29f330c3d75912f09333462;p=thirdparty%2Fsystemd.git Merge pull request #4448 from msoltyspl/vcfix Fix some formatting details in the merge. --- a5eebcff3732e2f6d29f330c3d75912f09333462 diff --cc src/vconsole/vconsole-setup.c index ac4ceb14868,185b041a1c9..a0ab5990fca --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@@ -238,21 -232,48 +232,47 @@@ static void setup_remaining_vcs(int fd return; } - /* get fonts from source console */ - cfo.data = fontbuf; + /* get metadata of the current font (width, height, count) */ r = ioctl(fd, KDFONTOP, &cfo); if (r < 0) - log_warning_errno(errno, "KD_FONT_OP_GET failed, fonts will not be copied: %m"); + log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to get the font metadata: %m"); else { - unimapd.entries = unipairs; - unimapd.entry_ct = USHRT_MAX; - r = ioctl(fd, GIO_UNIMAP, &unimapd); - if (r < 0) - log_warning_errno(errno, "GIO_UNIMAP failed, fonts will not be copied: %m"); - else - cfo.op = KD_FONT_OP_SET; - /* sanitize parameters first */ ++ /* verify parameter sanity first */ + if (cfo.width > 32 || cfo.height > 32 || cfo.charcount > 512) + log_warning("Invalid font metadata - width: %u (max 32), height: %u (max 32), count: %u (max 512)", - cfo.width, cfo.height, cfo.charcount); ++ cfo.width, cfo.height, cfo.charcount); + else { + /* + * Console fonts supported by the kernel are limited in size to 32 x 32 and maximum 512 + * characters. Thus with 1 bit per pixel it requires up to 65536 bytes. The height always + * requries 32 per glyph, regardless of the actual height - see the comment above #define + * max_font_size 65536 in drivers/tty/vt/vt.c for more details. + */ + fontbuf = malloc((cfo.width + 7) / 8 * 32 * cfo.charcount); + if (!fontbuf) { + log_oom(); + return; + } + /* get fonts from source console */ + cfo.data = fontbuf; + r = ioctl(fd, KDFONTOP, &cfo); + if (r < 0) + log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to read the font data: %m"); + else { + unimapd.entries = unipairs; + unimapd.entry_ct = USHRT_MAX; + r = ioctl(fd, GIO_UNIMAP, &unimapd); + if (r < 0) + log_warning_errno(errno, "GIO_UNIMAP failed while trying to read unicode mappings: %m"); + else + cfo.op = KD_FONT_OP_SET; + } + } } - if (cfo.op != KD_FONT_OP_SET) { ++ if (cfo.op != KD_FONT_OP_SET) + log_warning("Fonts will not be copied to remaining consoles"); - } + for (i = 1; i <= 63; i++) { char ttyname[strlen("/dev/tty") + DECIMAL_STR_MAX(int)]; _cleanup_close_ int fd_d = -1;