mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 13:23:02 -04:00
fbdev: bound mode sysfs output to the sysfs buffer
mode_string() uses snprintf() which can return a value larger than the remaining buffer space. show_modes() accumulates the return value into i without checking whether i has reached PAGE_SIZE, causing the offset to advance past the sysfs buffer if the modelist is long enough. Add a size parameter to mode_string() and use scnprintf() to return only the bytes actually written. Add an early return when offset already exceeds the buffer. In show_modes(), stop accumulating once the buffer is full. Cc: stable@vger.kernel.org # v7.1+ Signed-off-by: Melbin K Mathew <mlbnkm1@gmail.com> Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
committed by
Helge Deller
parent
075b74841b
commit
d15d51fb26
@@ -27,12 +27,15 @@ static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mode_string(char *buf, unsigned int offset,
|
||||
static int mode_string(char *buf, size_t size, unsigned int offset,
|
||||
const struct fb_videomode *mode)
|
||||
{
|
||||
char m = 'U';
|
||||
char v = 'p';
|
||||
|
||||
if (offset >= size)
|
||||
return 0;
|
||||
|
||||
if (mode->flag & FB_MODE_IS_DETAILED)
|
||||
m = 'D';
|
||||
if (mode->flag & FB_MODE_IS_VESA)
|
||||
@@ -45,7 +48,7 @@ static int mode_string(char *buf, unsigned int offset,
|
||||
if (mode->vmode & FB_VMODE_DOUBLE)
|
||||
v = 'd';
|
||||
|
||||
return snprintf(&buf[offset], PAGE_SIZE - offset, "%c:%dx%d%c-%d\n",
|
||||
return scnprintf(&buf[offset], size - offset, "%c:%dx%d%c-%d\n",
|
||||
m, mode->xres, mode->yres, v, mode->refresh);
|
||||
}
|
||||
|
||||
@@ -64,7 +67,7 @@ static ssize_t store_mode(struct device *device, struct device_attribute *attr,
|
||||
|
||||
list_for_each_entry(modelist, &fb_info->modelist, list) {
|
||||
mode = &modelist->mode;
|
||||
i = mode_string(mstr, 0, mode);
|
||||
i = mode_string(mstr, sizeof(mstr), 0, mode);
|
||||
if (strncmp(mstr, buf, max(count, i)) == 0) {
|
||||
|
||||
var = fb_info->var;
|
||||
@@ -86,7 +89,7 @@ static ssize_t show_mode(struct device *device, struct device_attribute *attr,
|
||||
if (!fb_info->mode)
|
||||
return 0;
|
||||
|
||||
return mode_string(buf, 0, fb_info->mode);
|
||||
return mode_string(buf, PAGE_SIZE, 0, fb_info->mode);
|
||||
}
|
||||
|
||||
static ssize_t store_modes(struct device *device,
|
||||
@@ -136,7 +139,9 @@ static ssize_t show_modes(struct device *device, struct device_attribute *attr,
|
||||
i = 0;
|
||||
list_for_each_entry(modelist, &fb_info->modelist, list) {
|
||||
mode = &modelist->mode;
|
||||
i += mode_string(buf, i, mode);
|
||||
i += mode_string(buf, PAGE_SIZE, i, mode);
|
||||
if (i >= PAGE_SIZE - 1)
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user