Fonts: Support FONT_EXTRA_WORDS macros for built-in fonts

syzbot has reported an issue in the framebuffer layer, where a malicious
user may overflow our built-in font data buffers.

In order to perform a reliable range check, subsystems need to know
`FONTDATAMAX` for each built-in font. Unfortunately, our font descriptor,
`struct console_font` does not contain `FONTDATAMAX`, and is part of the
UAPI, making it infeasible to modify it.

For user-provided fonts, the framebuffer layer resolves this issue by
reserving four extra words at the beginning of data buffers. Later,
whenever a function needs to access them, it simply uses the following
macros:

Recently we have gathered all the above macros to <linux/font.h>. Let us
do the same thing for built-in fonts, prepend four extra words (including
`FONTDATAMAX`) to their data buffers, so that subsystems can use these
macros for all fonts, no matter built-in or user-provided.

This patch depends on patch "fbdev, newport_con: Move FONT_EXTRA_WORDS
macros into linux/font.h".

Cc: stable@vger.kernel.org
Link: https://syzkaller.appspot.com/bug?id=08b8be45afea11888776f897895aef9ad1c3ecfd
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/ef18af00c35fb3cc826048a5f70924ed6ddce95b.1600953813.git.yepeilin.cs@gmail.com
This commit is contained in:
Peilin Ye 2020-09-24 09:42:22 -04:00 committed by Daniel Vetter
parent bb0890b4cd
commit 6735b4632d
13 changed files with 56 additions and 54 deletions

View File

@ -67,4 +67,9 @@ extern const struct font_desc *get_default_font(int xres, int yres,
#define FONT_EXTRA_WORDS 4 #define FONT_EXTRA_WORDS 4
struct font_data {
unsigned int extra[FONT_EXTRA_WORDS];
const unsigned char data[];
} __packed;
#endif /* _VIDEO_FONT_H */ #endif /* _VIDEO_FONT_H */

View File

@ -8,8 +8,8 @@
#define FONTDATAMAX 9216 #define FONTDATAMAX 9216
static const unsigned char fontdata_10x18[FONTDATAMAX] = { static struct font_data fontdata_10x18 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, 0x00, /* 0000000000 */ 0x00, 0x00, /* 0000000000 */
0x00, 0x00, /* 0000000000 */ 0x00, 0x00, /* 0000000000 */
@ -5129,8 +5129,7 @@ static const unsigned char fontdata_10x18[FONTDATAMAX] = {
0x00, 0x00, /* 0000000000 */ 0x00, 0x00, /* 0000000000 */
0x00, 0x00, /* 0000000000 */ 0x00, 0x00, /* 0000000000 */
0x00, 0x00, /* 0000000000 */ 0x00, 0x00, /* 0000000000 */
} };
};
const struct font_desc font_10x18 = { const struct font_desc font_10x18 = {
@ -5138,7 +5137,7 @@ const struct font_desc font_10x18 = {
.name = "10x18", .name = "10x18",
.width = 10, .width = 10,
.height = 18, .height = 18,
.data = fontdata_10x18, .data = fontdata_10x18.data,
#ifdef __sparc__ #ifdef __sparc__
.pref = 5, .pref = 5,
#else #else

View File

@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/font.h> #include <linux/font.h>
static const unsigned char fontdata_6x10[] = { #define FONTDATAMAX 2560
static struct font_data fontdata_6x10 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
@ -3074,14 +3076,13 @@ static const unsigned char fontdata_6x10[] = {
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
} };
};
const struct font_desc font_6x10 = { const struct font_desc font_6x10 = {
.idx = FONT6x10_IDX, .idx = FONT6x10_IDX,
.name = "6x10", .name = "6x10",
.width = 6, .width = 6,
.height = 10, .height = 10,
.data = fontdata_6x10, .data = fontdata_6x10.data,
.pref = 0, .pref = 0,
}; };

View File

@ -9,8 +9,8 @@
#define FONTDATAMAX (11*256) #define FONTDATAMAX (11*256)
static const unsigned char fontdata_6x11[FONTDATAMAX] = { static struct font_data fontdata_6x11 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
@ -3338,8 +3338,7 @@ static const unsigned char fontdata_6x11[FONTDATAMAX] = {
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
} };
};
const struct font_desc font_vga_6x11 = { const struct font_desc font_vga_6x11 = {
@ -3347,7 +3346,7 @@ const struct font_desc font_vga_6x11 = {
.name = "ProFont6x11", .name = "ProFont6x11",
.width = 6, .width = 6,
.height = 11, .height = 11,
.data = fontdata_6x11, .data = fontdata_6x11.data,
/* Try avoiding this font if possible unless on MAC */ /* Try avoiding this font if possible unless on MAC */
.pref = -2000, .pref = -2000,
}; };

View File

@ -8,8 +8,8 @@
#define FONTDATAMAX 3584 #define FONTDATAMAX 3584
static const unsigned char fontdata_7x14[FONTDATAMAX] = { static struct font_data fontdata_7x14 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, /* 0000000 */ 0x00, /* 0000000 */
0x00, /* 0000000 */ 0x00, /* 0000000 */
@ -4105,8 +4105,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
0x00, /* 0000000 */ 0x00, /* 0000000 */
0x00, /* 0000000 */ 0x00, /* 0000000 */
0x00, /* 0000000 */ 0x00, /* 0000000 */
} };
};
const struct font_desc font_7x14 = { const struct font_desc font_7x14 = {
@ -4114,6 +4113,6 @@ const struct font_desc font_7x14 = {
.name = "7x14", .name = "7x14",
.width = 7, .width = 7,
.height = 14, .height = 14,
.data = fontdata_7x14, .data = fontdata_7x14.data,
.pref = 0, .pref = 0,
}; };

View File

@ -10,8 +10,8 @@
#define FONTDATAMAX 4096 #define FONTDATAMAX 4096
static const unsigned char fontdata_8x16[FONTDATAMAX] = { static struct font_data fontdata_8x16 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
@ -4619,8 +4619,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
} };
};
const struct font_desc font_vga_8x16 = { const struct font_desc font_vga_8x16 = {
@ -4628,7 +4627,7 @@ const struct font_desc font_vga_8x16 = {
.name = "VGA8x16", .name = "VGA8x16",
.width = 8, .width = 8,
.height = 16, .height = 16,
.data = fontdata_8x16, .data = fontdata_8x16.data,
.pref = 0, .pref = 0,
}; };
EXPORT_SYMBOL(font_vga_8x16); EXPORT_SYMBOL(font_vga_8x16);

View File

@ -9,8 +9,8 @@
#define FONTDATAMAX 2048 #define FONTDATAMAX 2048
static const unsigned char fontdata_8x8[FONTDATAMAX] = { static struct font_data fontdata_8x8 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
@ -2570,8 +2570,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
} };
};
const struct font_desc font_vga_8x8 = { const struct font_desc font_vga_8x8 = {
@ -2579,6 +2578,6 @@ const struct font_desc font_vga_8x8 = {
.name = "VGA8x8", .name = "VGA8x8",
.width = 8, .width = 8,
.height = 8, .height = 8,
.data = fontdata_8x8, .data = fontdata_8x8.data,
.pref = 0, .pref = 0,
}; };

View File

@ -3,7 +3,10 @@
#include <linux/font.h> #include <linux/font.h>
static const unsigned char acorndata_8x8[] = { #define FONTDATAMAX 2048
static struct font_data acorndata_8x8 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */ /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */
/* 01 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */ /* 01 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */
/* 02 */ 0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */ /* 02 */ 0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */
@ -260,14 +263,14 @@ static const unsigned char acorndata_8x8[] = {
/* FD */ 0x38, 0x04, 0x18, 0x20, 0x3c, 0x00, 0x00, 0x00, /* FD */ 0x38, 0x04, 0x18, 0x20, 0x3c, 0x00, 0x00, 0x00,
/* FE */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, /* FE */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; } };
const struct font_desc font_acorn_8x8 = { const struct font_desc font_acorn_8x8 = {
.idx = ACORN8x8_IDX, .idx = ACORN8x8_IDX,
.name = "Acorn8x8", .name = "Acorn8x8",
.width = 8, .width = 8,
.height = 8, .height = 8,
.data = acorndata_8x8, .data = acorndata_8x8.data,
#ifdef CONFIG_ARCH_ACORN #ifdef CONFIG_ARCH_ACORN
.pref = 20, .pref = 20,
#else #else

View File

@ -43,8 +43,8 @@ __END__;
#define FONTDATAMAX 1536 #define FONTDATAMAX 1536
static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = { static struct font_data fontdata_mini_4x6 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/*{*/ /*{*/
/* Char 0: ' ' */ /* Char 0: ' ' */
0xee, /*= [*** ] */ 0xee, /*= [*** ] */
@ -2145,14 +2145,14 @@ static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
0xee, /*= [*** ] */ 0xee, /*= [*** ] */
0x00, /*= [ ] */ 0x00, /*= [ ] */
/*}*/ /*}*/
}; } };
const struct font_desc font_mini_4x6 = { const struct font_desc font_mini_4x6 = {
.idx = MINI4x6_IDX, .idx = MINI4x6_IDX,
.name = "MINI4x6", .name = "MINI4x6",
.width = 4, .width = 4,
.height = 6, .height = 6,
.data = fontdata_mini_4x6, .data = fontdata_mini_4x6.data,
.pref = 3, .pref = 3,
}; };

View File

@ -14,8 +14,8 @@
#define FONTDATAMAX 2048 #define FONTDATAMAX 2048
static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = { static struct font_data fontdata_pearl8x8 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
@ -2575,14 +2575,13 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
0x00, /* 00000000 */ 0x00, /* 00000000 */
} };
};
const struct font_desc font_pearl_8x8 = { const struct font_desc font_pearl_8x8 = {
.idx = PEARL8x8_IDX, .idx = PEARL8x8_IDX,
.name = "PEARL8x8", .name = "PEARL8x8",
.width = 8, .width = 8,
.height = 8, .height = 8,
.data = fontdata_pearl8x8, .data = fontdata_pearl8x8.data,
.pref = 2, .pref = 2,
}; };

View File

@ -3,8 +3,8 @@
#define FONTDATAMAX 11264 #define FONTDATAMAX 11264
static const unsigned char fontdata_sun12x22[FONTDATAMAX] = { static struct font_data fontdata_sun12x22 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */
0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */
@ -6148,8 +6148,7 @@ static const unsigned char fontdata_sun12x22[FONTDATAMAX] = {
0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */
0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */
0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */
} };
};
const struct font_desc font_sun_12x22 = { const struct font_desc font_sun_12x22 = {
@ -6157,7 +6156,7 @@ const struct font_desc font_sun_12x22 = {
.name = "SUN12x22", .name = "SUN12x22",
.width = 12, .width = 12,
.height = 22, .height = 22,
.data = fontdata_sun12x22, .data = fontdata_sun12x22.data,
#ifdef __sparc__ #ifdef __sparc__
.pref = 5, .pref = 5,
#else #else

View File

@ -3,7 +3,8 @@
#define FONTDATAMAX 4096 #define FONTDATAMAX 4096
static const unsigned char fontdata_sun8x16[FONTDATAMAX] = { static struct font_data fontdata_sun8x16 = {
{ 0, 0, FONTDATAMAX, 0 }, {
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00,
@ -260,14 +261,14 @@ static const unsigned char fontdata_sun8x16[FONTDATAMAX] = {
/* */ 0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* */ 0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
}; } };
const struct font_desc font_sun_8x16 = { const struct font_desc font_sun_8x16 = {
.idx = SUN8x16_IDX, .idx = SUN8x16_IDX,
.name = "SUN8x16", .name = "SUN8x16",
.width = 8, .width = 8,
.height = 16, .height = 16,
.data = fontdata_sun8x16, .data = fontdata_sun8x16.data,
#ifdef __sparc__ #ifdef __sparc__
.pref = 10, .pref = 10,
#else #else

View File

@ -4,8 +4,8 @@
#define FONTDATAMAX 16384 #define FONTDATAMAX 16384
static const unsigned char fontdata_ter16x32[FONTDATAMAX] = { static struct font_data fontdata_ter16x32 = {
{ 0, 0, FONTDATAMAX, 0 }, {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x7f, 0xfc,
0x70, 0x1c, 0x70, 0x1c, 0x70, 0x1c, 0x70, 0x1c, 0x70, 0x1c, 0x70, 0x1c, 0x70, 0x1c, 0x70, 0x1c,
@ -2054,8 +2054,7 @@ static const unsigned char fontdata_ter16x32[FONTDATAMAX] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 255 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 255 */
} };
};
const struct font_desc font_ter_16x32 = { const struct font_desc font_ter_16x32 = {
@ -2063,7 +2062,7 @@ const struct font_desc font_ter_16x32 = {
.name = "TER16x32", .name = "TER16x32",
.width = 16, .width = 16,
.height = 32, .height = 32,
.data = fontdata_ter16x32, .data = fontdata_ter16x32.data,
#ifdef __sparc__ #ifdef __sparc__
.pref = 5, .pref = 5,
#else #else