Skip to content

Commit

Permalink
video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name()
Browse files Browse the repository at this point in the history
[ Upstream commit 78482af ]

This code has two bugs:
1) "cnt" is 255 but the size of the buffer is 256 so the last byte is
   not used.
2) If we try to print more than 255 characters then "cnt" will be
   negative and that will trigger a WARN() in snprintf(). The fix for
   this is to use scnprintf() instead of snprintf().

We can re-write this code to be cleaner:
1) Rename "offset" to "off" because that's shorter.
2) Get rid of the "cnt" variable and just use "size - off" directly.
3) Get rid of the "read" variable and just increment "off" directly.

Fixes: 96fe6a2 ("fbdev: Add VESA Coordinated Video Timings (CVT) support")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Dan Carpenter authored and gregkh committed Apr 8, 2022
1 parent c19c542 commit a9e1c8d
Showing 1 changed file with 21 additions and 32 deletions.
53 changes: 21 additions & 32 deletions drivers/video/fbdev/core/fbcvt.c
Expand Up @@ -214,53 +214,42 @@ static u32 fb_cvt_aspect_ratio(struct fb_cvt_data *cvt)
static void fb_cvt_print_name(struct fb_cvt_data *cvt)
{
u32 pixcount, pixcount_mod;
int cnt = 255, offset = 0, read = 0;
u8 *buf = kzalloc(256, GFP_KERNEL);
int size = 256;
int off = 0;
u8 *buf;

buf = kzalloc(size, GFP_KERNEL);
if (!buf)
return;

pixcount = (cvt->xres * (cvt->yres/cvt->interlace))/1000000;
pixcount_mod = (cvt->xres * (cvt->yres/cvt->interlace)) % 1000000;
pixcount_mod /= 1000;

read = snprintf(buf+offset, cnt, "fbcvt: %dx%d@%d: CVT Name - ",
cvt->xres, cvt->yres, cvt->refresh);
offset += read;
cnt -= read;
off += scnprintf(buf + off, size - off, "fbcvt: %dx%d@%d: CVT Name - ",
cvt->xres, cvt->yres, cvt->refresh);

if (cvt->status)
snprintf(buf+offset, cnt, "Not a CVT standard - %d.%03d Mega "
"Pixel Image\n", pixcount, pixcount_mod);
else {
if (pixcount) {
read = snprintf(buf+offset, cnt, "%d", pixcount);
cnt -= read;
offset += read;
}
if (cvt->status) {
off += scnprintf(buf + off, size - off,
"Not a CVT standard - %d.%03d Mega Pixel Image\n",
pixcount, pixcount_mod);
} else {
if (pixcount)
off += scnprintf(buf + off, size - off, "%d", pixcount);

read = snprintf(buf+offset, cnt, ".%03dM", pixcount_mod);
cnt -= read;
offset += read;
off += scnprintf(buf + off, size - off, ".%03dM", pixcount_mod);

if (cvt->aspect_ratio == 0)
read = snprintf(buf+offset, cnt, "3");
off += scnprintf(buf + off, size - off, "3");
else if (cvt->aspect_ratio == 3)
read = snprintf(buf+offset, cnt, "4");
off += scnprintf(buf + off, size - off, "4");
else if (cvt->aspect_ratio == 1 || cvt->aspect_ratio == 4)
read = snprintf(buf+offset, cnt, "9");
off += scnprintf(buf + off, size - off, "9");
else if (cvt->aspect_ratio == 2)
read = snprintf(buf+offset, cnt, "A");
else
read = 0;
cnt -= read;
offset += read;

if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) {
read = snprintf(buf+offset, cnt, "-R");
cnt -= read;
offset += read;
}
off += scnprintf(buf + off, size - off, "A");

if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
off += scnprintf(buf + off, size - off, "-R");
}

printk(KERN_INFO "%s\n", buf);
Expand Down

0 comments on commit a9e1c8d

Please sign in to comment.