Bug 196510 - [Patch] Fixing panic in vt_fb_blank() if fb_size is not a multiple of fb_stride
Summary: [Patch] Fixing panic in vt_fb_blank() if fb_size is not a multiple of fb_stride
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 9.3-RELEASE
Hardware: i386 Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-01-05 13:53 UTC by Andre Albsmeier
Modified: 2015-01-13 17:53 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andre Albsmeier 2015-01-05 13:53:07 UTC
[According to emaste@ this has been fixed in -HEAD in a different way
but needs MFC to -STABLE. If an MFC is not possible, the fix in this
PR should do it.]

I can reliably crash an older notebook (Fujitsu E8310) with Intel
graphics (GM965) by loading i915kms after having booted but only
if vt(4) is used instead of old syscons.

Reason for the crash is a page fault in vt_fb_blank() which is
in /sys/dev/vt/hw/fb/vt_fb.c:

#7  0xc08c929e in bcopy () at /src/src-9/sys/i386/i386/support.s:198
#8  0xc08d93e0 in memmove (dest=0xedfd3c00, src=0xeda30000, n=5632) at /src/src-9/sys/libkern/memmove.c:36
#9  0xc053fac7 in vt_fb_mem_copy (sc=0xc6919500, offset_to=5913600, offset_from=0, size=5632) at /src/src-9/sys/dev/fb/fbd.c:205
#10 0xc060370e in vt_fb_blank (vd=0xc09c3c40, color=<value optimized out>) at /src/src-9/sys/dev/vt/hw/fb/vt_fb.c:179
#11 0xc0603b10 in vt_fb_init (vd=0xc09c3c40) at /src/src-9/sys/dev/vt/hw/fb/vt_fb.c:306
#12 0xc06098db in vt_allocate (drv=0xc09c3b80, softc=0xc6919500) at /src/src-9/sys/dev/vt/vt_core.c:1970

in vt_fb_blank() we find:

        for (o = info->fb_stride; o < info->fb_size; o += info->fb_stride) {
                info->copy(info, o, 0, info->fb_stride);
        }

fb_size gets calculated in intelfb_create() which is in
/sys/dev/drm2/i915/intel_fb.c as

        size = mode_cmd.pitches[0] * mode_cmd.height;
        size = roundup2(size, PAGE_SIZE);

with fb_stride being the result of

        mode_cmd.pitches[0] =  roundup2( (mode_cmd.width * ((sizes->surface_bpp + 7) / 8), 64);

So with my funky resolution of 1400 x 1050 @32bit we get

fb_stride = 5632
fb_size = 5914624

We see that fb_stride won't fit into fb_size in whole numbers
(5914624 / 5632 = 1050.18181818181818181818) so this is why
the loop runs beyond fb_size and gives a page fault.

I am now using this modified loop in vt_fb_blank() which does
not try to run to the end of the fb by replacing

info->fb_size

by

info->fb_height * info->fb_stride

        for (o = info->fb_stride; o < info->fb_height * info->fb_stride; o += info->fb_stride) {
                info->copy(info, o, 0, info->fb_stride);
        }
Comment 1 Andre Albsmeier 2015-01-05 14:00:02 UTC
The changes in HEAD which should fix the problem are r268771 and r268796.
Comment 2 commit-hook freebsd_committer freebsd_triage 2015-01-12 18:38:51 UTC
A commit references this bug:

Author: emaste
Date: Mon Jan 12 18:38:10 UTC 2015
New revision: 277083
URL: https://svnweb.freebsd.org/changeset/base/277083

Log:
  Avoid crash in vt_blank() and improve performance

  MFC of r268771 (partial), r268796

  PR:		196510
  Reported by:	Andre Albsmeier
  Sponsored by:	The FreeBSD Foundation

Changes:
_U  stable/9/sys/
_U  stable/9/sys/dev/
  stable/9/sys/dev/vt/hw/fb/vt_fb.c
Comment 3 Ed Maste freebsd_committer freebsd_triage 2015-01-12 19:46:21 UTC
Fixed in HEAD in r268771 and r268796
Fixed in stable/10 in r270980
Fixed in stable/9 in r277083
Comment 4 Andre Albsmeier 2015-01-13 17:53:53 UTC
Confirmed to be fixed, thanks!