| Summary: | [Fix] syscons VT switching code errors | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | michiel.dewilde <michiel.dewilde> | ||||
| Component: | kern | Assignee: | yokota <yokota> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.2-STABLE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
Responsible Changed From-To: freebsd-bugs->yokota Over to sc maintainer. State Changed From-To: open->closed Fixed. Thanks! |
I ran across these minor errors in syscons: In src/sys/dev/syscons/syscons.c [rev. 1.336.2.3], lines 954-963: When using ioctl VT_WAITACTIVE, parameter "data" is checked to see if it references a valid vty on the same adapter as the vty used for the request (lines 961-962). This check is "one off", because "data" is decremented by one later on. Furthermore, when looking at the code at line 969, I presume a value of 0 was meant to block the calling process until the requesting vty is activated. The same initial parameter check at lines 961-962 doesn't like zero, however. Finally, for conformity with VT_WAITACTIVE, VT_ACTIVATE should also be adapted to interpret a vty index of zero as "the requesting vty". In src/usr.sbin/vidcontrol/vidcontrol.c [rev. 1.32] (line 326): When switching back to VESA mode, "_IO('V', cur_mode - M_VESA_BASE)" should be used instead of "_IO('V', cur_mode)". Please take a look at the bottom of include file <sys/consio.h> for the reason why this should be. Fix: You can apply the following patches (please check for correctness first, we all make mistakes and I in particular): First, in plain text (for easy reference). Use the uuencoded versions below for the real stuff. === BEGIN syscons.c.diff --- src/sys/dev/syscons/syscons.c 2000/10/29 16:59:27 1.336.2.3 +++ src/sys/dev/syscons/syscons.c 2001/01/10 10:14:54 @@ -955,11 +955,14 @@ s = spltty(); sc_clean_up(sc->cur_scp); splx(s); - return sc_switch_scr(sc, *(int *)data - 1); + if (*(int *)data != 0) + return sc_switch_scr(sc, *(int *)data - 1); + else + return sc_switch_scr(sc, scp->index); case VT_WAITACTIVE: /* wait for switch to occur */ - if ((*(int *)data >= sc->first_vty + sc->vtys) - || (*(int *)data < sc->first_vty)) + if (((*(int *)data > sc->first_vty + sc->vtys) + || (*(int *)data <= sc->first_vty)) && (*(int *)data != 0)) return EINVAL; s = spltty(); error = sc_clean_up(sc->cur_scp); === END syscons.c.diff === BEGIN vidcontrol.c.diff --- src/usr.sbin/vidcontrol/vidcontrol.c 2000/01/12 12:30:33 1.32 +++ src/usr.sbin/vidcontrol/vidcontrol.c 2001/01/10 10:04:15 @@ -323,7 +323,7 @@ if (ioctl(0, KDRASTER, size)) { ioerr = errno; if (cur_mode >= M_VESA_BASE) - ioctl(0, _IO('V', cur_mode), NULL); + ioctl(0, _IO('V', cur_mode - M_VESA_BASE), NULL); else ioctl(0, _IO('S', cur_mode), NULL); warnc(ioerr, "cannot activate raster display"); === END vidcontrol.c.diff Here they are again tar-gzip-uuencoded, because if GNATS chooses to wrap lines, you'd better use these instead: How-To-Repeat: syscons.c: Try to VT_WAITACTIVE the last vty and watch it fail. vidcontrol.c: (somewhat elaborate, sorry) Use a machine which hasn't compiled rastered text support into the kernel. Write an application to switch to some VESA mode and draw something, and quit the app without restoring text mode. Now you need vidcontrol to fix things. Try to switch back to rastered SW_VESA_800x600 using vidcontrol. It will fail, of course, but to which mode will it switch?