Message ID | 20220131065719.1552958-1-yzhai003@ucr.edu |
---|---|
State | New |
Headers | show |
Series | fbdev: fbmem: Fix the implicit type casting | expand |
Hi Helge, On Tue, Feb 01, 2022 at 04:02:40PM +0100, Helge Deller wrote: > On 1/31/22 07:57, Yizhuo Zhai wrote: > > In function do_fb_ioctl(), the "arg" is the type of unsigned long, > > yes, because it comes from the ioctl framework... > > > and in "case FBIOBLANK:" this argument is casted into an int before > > passig to fb_blank(). > > which makes sense IMHO. > > > In fb_blank(), the comparision if (blank > FB_BLANK_POWERDOWN) would > > be bypass if the original "arg" is a large number, which is possible > > because it comes from the user input. > > The main problem I see with your patch is that you change the behaviour. > Let's assume someone passes in -1UL. > With your patch applied, this means the -1 (which is e.g. 0xffffffff on 32bit) > is converted to a positive integer and will be capped to FB_BLANK_POWERDOWN. > Since most blank functions just check and react on specific values, you changed > the behaviour that the screen now gets blanked at -1, while it wasn't before. > > One could now argue, that it's undefined behaviour if people > pass in wrong values, but anyway, it's different now. We should just plug this hole and in case an illegal value is passed then return -EINVAL. Acceptable values are FB_BLANK_UNBLANK..FB_BLANK_POWERDOWN, anything less than or greater than should result in -EINVAL. We miss this kind or early checks in many places, and we see the effect of this in some drivers where they do it locally for no good. Sam
On 2/2/22 18:27, Sam Ravnborg wrote: > Hi Helge, > > On Tue, Feb 01, 2022 at 04:02:40PM +0100, Helge Deller wrote: >> On 1/31/22 07:57, Yizhuo Zhai wrote: >>> In function do_fb_ioctl(), the "arg" is the type of unsigned long, >> >> yes, because it comes from the ioctl framework... >> >>> and in "case FBIOBLANK:" this argument is casted into an int before >>> passig to fb_blank(). >> >> which makes sense IMHO. >> >>> In fb_blank(), the comparision if (blank > FB_BLANK_POWERDOWN) would >>> be bypass if the original "arg" is a large number, which is possible >>> because it comes from the user input. >> >> The main problem I see with your patch is that you change the behaviour. >> Let's assume someone passes in -1UL. >> With your patch applied, this means the -1 (which is e.g. 0xffffffff on 32bit) >> is converted to a positive integer and will be capped to FB_BLANK_POWERDOWN. >> Since most blank functions just check and react on specific values, you changed >> the behaviour that the screen now gets blanked at -1, while it wasn't before. >> >> One could now argue, that it's undefined behaviour if people >> pass in wrong values, but anyway, it's different now. > > We should just plug this hole and in case an illegal value is passed > then return -EINVAL. > > Acceptable values are FB_BLANK_UNBLANK..FB_BLANK_POWERDOWN, > anything less than or greater than should result in -EINVAL. Yes, that's the best solution. Yizhuo Zhai, would you mind to resend with that solution? Helge > We miss this kind or early checks in many places, and we see the effect > of this in some drivers where they do it locally for no good. > > Sam
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 0fa7ede94fa6..a5f71c191122 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1064,7 +1064,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) EXPORT_SYMBOL(fb_set_var); int -fb_blank(struct fb_info *info, int blank) +fb_blank(struct fb_info *info, unsigned long blank) { struct fb_event event; int ret = -EINVAL;
In function do_fb_ioctl(), the "arg" is the type of unsigned long, and in "case FBIOBLANK:" this argument is casted into an int before passig to fb_blank(). In fb_blank(), the comparision if (blank > FB_BLANK_POWERDOWN) would be bypass if the original "arg" is a large number, which is possible because it comes from the user input. Signed-off-by: Yizhuo Zhai <yzhai003@ucr.edu> --- drivers/video/fbdev/core/fbmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)