Summary: | v86d segfaults since version 0.1.8 | ||
---|---|---|---|
Product: | Gentoo Linux | Reporter: | Arthur Spitzer <arthapex> |
Component: | Current packages | Assignee: | Michal Januszewski (RETIRED) <spock> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | orlovm, pageexec, spock |
Priority: | High | ||
Version: | unspecified | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Package list: | Runtime testing required: | --- | |
Attachments: |
Allow writing to the video/system BIOS area.
Make mode info block retrieval failures non-fatal in testvbe. patched version of uvesafb.c my video bios |
Description
Arthur Spitzer
2008-11-02 09:25:22 UTC
Created attachment 170530 [details, diff]
Allow writing to the video/system BIOS area.
Could you please apply this patch to a clean v86d-0.1.9 source and see whether it fixes the segfault-right-after-start problem in testvbe?
patch(In reply to comment #1) took the 0.1.9 archive from your homepage. extracted and applied proposed patch. No segfault: v86d-0.1.9 # ./testvbe VBE Version: 3.00 OEM String: Intel(r)852MG/852MGE/855MG/855MGE Graphics Chip Accelerated VGA BIOS OEM Vendor Name: Intel Corporation OEM Prod. Name: Intel(r)852MG/852MGE/855MG/855MGE Graphics Controller OEM Prod. Rev: Hardware Version 0.0 ID attr mode --------------------------- Getting Mode Info Block for mode 0136 failed with eax = 014f (In reply to comment #2) > ID attr mode > --------------------------- > Getting Mode Info Block for mode 0136 failed with eax = 014f OK, good. Could you please try to use this patched version of v86d with a kernel tree patched with [1]? The patch in [1] will be included in 2.6.28 and it makes these "getting mode info block" errors non-fatal, which should allow the driver to work on your card (provided there are some modes for which the mode info block _is_ actually available). [1] http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff_plain;h=9350cc90ca8a72bc1974f76a9922f91ced84a5cf Ok. I copied my linux-2.6.25-gentoo-r8 folder and applied your proposed patch. This is what I get after modprobe uvesafb: uvesafb: Intel Corporation, Intel(r)852MG/852MGE/855MG/855MGE Graphics Controller, Hardware Version 0.0, OEM: Intel(r)852MG/852MGE/855MG/855MGE Graphics Chip Accelerated VGA BIOS, VBE v3.0 uvesafb: Getting mode info block for mode 0x136 failed (eax=0x14f, err=0) uvesafb: vbe_init() failed with -22 uvesafb: probe of uvesafb.0 failed with error -22 I realized, that I compiled v86d without klibc. If I enable klibc I get an error during compilation: Travelmate v86d-0.1.9 # ./configure --with-klibc --with-debug --with-x86emu config.h successfully created. You can run `make` now. Travelmate v86d-0.1.9 # make make -w -C libs/x86emu make[1]: Entering directory `/home/ich/Downloads/v86d-0.1.9/libs/x86emu' make[1]: »libx86emu.a« ist bereits aktualisiert. ( = is the current version) make[1]: Leaving directory `/home/ich/Downloads/v86d-0.1.9/libs/x86emu' klcc -Llibs/x86emu v86_x86emu.o v86_mem.o v86_common.o v86.o -lx86emu -o v86d v86_mem.o: In function `map_file': /home/ich/Downloads/v86d-0.1.9/v86_mem.c:92: undefined reference to `__errno_location' /home/ich/Downloads/v86d-0.1.9/v86_mem.c:99: undefined reference to `__errno_location' v86_mem.o: In function `get_bytes_from_phys': /home/ich/Downloads/v86d-0.1.9/v86_mem.c:214: undefined reference to `getpagesize' v86_mem.o: In function `v86_mem_init': /home/ich/Downloads/v86d-0.1.9/v86_mem.c:267: undefined reference to `getpagesize' v86.o: In function `netlink_send': /home/ich/Downloads/v86d-0.1.9/v86.c:44: undefined reference to `__errno_location' v86.o: In function `main': /home/ich/Downloads/v86d-0.1.9/v86.c:115: undefined reference to `__errno_location' make: *** [v86d] Fehler 1 An another info: If I compile without x86emu, then I get the segfault error again: Travelmate v86d-0.1.9 # ./configure --with-debug config.h successfully created. You can run `make` now. Travelmate v86d-0.1.9 # make make -e -w -C libs/lrmi-0.10 liblrmi.a make[1]: Entering directory `/home/ich/Downloads/v86d-0.1.9/libs/lrmi-0.10' make[1]: »liblrmi.a« ist bereits aktualisiert. make[1]: Leaving directory `/home/ich/Downloads/v86d-0.1.9/libs/lrmi-0.10' cc -Llibs/lrmi-0.10 -static -Wl,--section-start,vm86_ret=0x9000 v86_lrmi.o v86_common.o v86.o -llrmi -o v86d cc -Llibs/lrmi-0.10 -static -Wl,--section-start,vm86_ret=0x9000 v86_lrmi.o v86_common.o testvbe.o -llrmi -o testvbe Travelmate v86d-0.1.9 # ./testvbe Speicherzugriffsfehler If I use v86d version 0.1.8 with your patch the compilation runs fine. debug + x86emu + klibc enabled. Running the patched kernel I get following from dmesg after modprobe uvesafb: v86d: EBDA at 9f800-9ffff v86d: VBIOS at c0000-ccdff v86d: task flags: 0x01 v86d: EAX=0x00004f00 EBX=0x00000000 ECX=0x00000000 EDX=0x00000000 v86d: ESP=0x00000000 EBP=0x00000000 ESI=0x00000000 EDI=0x00000000 v86d: The mode list is in the buffer at 00012140. uvesafb: Intel Corporation, Intel(r)852MG/852MGE/855MG/855MGE Graphics Controller, Hardware Version 0.0, OEM: Intel(r)852MG/852MGE/855MG/855MGE Graphics Chip Accelerated VGA BIOS, VBE v3.0 v86d: task flags: 0x0a v86d: EAX=0x00004f01 EBX=0x00000000 ECX=0x00000136 EDX=0x00000000 v86d: ESP=0x00000000 EBP=0x00000000 ESI=0x00000000 EDI=0x00000000 uvesafb: Getting mode info block for mode 0x136 failed (eax=0x14f, err=0) uvesafb: vbe_init() failed with -22 uvesafb: probe of uvesafb.0 failed with error -22 (In reply to comment #5) > If I use v86d version 0.1.8 with your patch the compilation runs fine. debug + > x86emu + klibc enabled. > > uvesafb: Getting mode info block for mode 0x136 failed (eax=0x14f, err=0) > uvesafb: vbe_init() failed with -22 > uvesafb: probe of uvesafb.0 failed with error -22 Are you sure the patch has been applied correctly and the kernel binary has been compiled using the patched sources? The patch is supposed to make the exact error you just posted non-fatal. Sorry, somehow I mixed up things. Please forget the last two posts. Sorry for the spam. Another try: I took another fresh v86d-0.1.9 folder, and applied the proposed patch. Compiled with all three flags enabled. Compilation went fine, except some warnings. testvbe works as described in comment #2. Running the patched kernel, I get following after modprobe uvesafb: v86d: EBDA at 9f800-9ffff v86d: VBIOS at c0000-ccdff v86d: task flags: 0x01 v86d: EAX=0x00004f00 EBX=0x00000000 ECX=0x00000000 EDX=0x00000000 v86d: ESP=0x00000000 EBP=0x00000000 ESI=0x00000000 EDI=0x00000000 v86d: The mode list is in the buffer at 00012140. uvesafb: Intel Corporation, Intel(r)852MG/852MGE/855MG/855MGE Graphics Controller, Hardware Version 0.0, OEM: Intel(r)852MG/852MGE/855MG/855MGE Graphics Chip Accelerated VGA BIOS, VBE v3.0 v86d: task flags: 0x0a v86d: EAX=0x00004f01 EBX=0x00000000 ECX=0x00000136 EDX=0x00000000 v86d: ESP=0x00000000 EBP=0x00000000 ESI=0x00000000 EDI=0x00000000 uvesafb: Getting mode info block for mode 0x136 failed (eax=0x14f, err=0) uvesafb: vbe_init() failed with -22 uvesafb: probe of uvesafb.0 failed with error -22 Created attachment 170626 [details, diff]
Make mode info block retrieval failures non-fatal in testvbe.
Could you please apply this patch against your v86d sources, rebuild testvbe, run it and post its output?
(In reply to comment #8) > Could you please apply this patch against your v86d sources, rebuild testvbe, > run it and post its output? VBE Version: 3.00 OEM String: Intel(r)852MG/852MGE/855MG/855MGE Graphics Chip Accelerated VGA BIOS OEM Vendor Name: Intel Corporation OEM Prod. Name: Intel(r)852MG/852MGE/855MG/855MGE Graphics Controller OEM Prod. Rev: Hardware Version 0.0 ID attr mode --------------------------- Getting Mode Info Block for mode 0136 failed with eax = 014f Getting Mode Info Block for mode 0147 failed with eax = 014f Getting Mode Info Block for mode 0156 failed with eax = 014f 013c 009a 1920x1440-8 014d 009a 1920x1440-16 015c 009a 1920x1440-32 013a 009a 1600x1200-8 014b 009a 1600x1200-16 015a 009a 1600x1200-32 0107 009b 1280x1024-8 011a 009b 1280x1024-16 011b 009b 1280x1024-32 0105 009b 1024x768-8 0117 009b 1024x768-16 0118 009b 1024x768-32 0112 009b 640x480-32 0114 009b 800x600-16 0115 009b 800x600-32 0101 009b 640x480-8 0103 009b 800x600-8 0111 009b 640x480-16 (In reply to comment #9) > 0107 009b 1280x1024-8 > 011a 009b 1280x1024-16 > 011b 009b 1280x1024-32 > 0105 009b 1024x768-8 > 0117 009b 1024x768-16 > 0118 009b 1024x768-32 > 0112 009b 640x480-32 > 0114 009b 800x600-16 > 0115 009b 800x600-32 > 0101 009b 640x480-8 > 0103 009b 800x600-8 > 0111 009b 640x480-16 This is inconsistent with the results you're getting from uvesafb. If you are sure the kernel patch has been applied correctly and that you are running the correct kernel binary, could you please post your drivers/video/uvesafb.c? Created attachment 170634 [details]
patched version of uvesafb.c
sorry my fault. I forgot to install the patched module, so in the last posts, I always used the old unpatched module. I hope I didn't make you trouble. But the patched module works fine. Even compiled into the kernel. Now I have a working framebuffer again: uvesafb: Intel Corporation, Intel(r)852MG/852MGE/855MG/855MGE Graphics Controller, Hardware Version 0.0, OEM: Intel(r)852MG/852MGE/855MG/855MGE Graphics Chip Accelerated VGA BIOS, VBE v3.0 uvesafb: Getting mode info block for mode 0x136 failed (eax=0x14f, err=0) uvesafb: Getting mode info block for mode 0x147 failed (eax=0x14f, err=0) uvesafb: Getting mode info block for mode 0x156 failed (eax=0x14f, err=0) uvesafb: VBIOS/hardware doesn't support DDC transfers uvesafb: no monitor limits have been set, default refresh rate will be used uvesafb: scrolling: redraw Switched to high resolution mode on CPU 0 Console: switching to colour frame buffer device 160x64 uvesafb: framebuffer at 0xe8000000, mapped to 0xf8b80000, using 10240k, total 32576k By the way: is there a way to make uvesafb use a resolution of 1400x1050 even if this resolution is not present in the vbios list? Because it's the native resolution of my laptop-screen. If not, and if you don't need any more testing or infomation, I'll mark this bug as fixed. (In reply to comment #12) > By the way: is there a way to make uvesafb use a resolution of 1400x1050 even > if this resolution is not present in the vbios list? Because it's the native > resolution of my laptop-screen. Since you're using an Intel video card -- yes. You need to run the 855resolution program (or whatever it is called) to patch your Video BIOS with the native resolution, and load uvesafb afterwards (this implies you need to be using uvesafb as a module of course). > If not, and if you don't need any more testing or infomation, I'll mark this > bug as fixed. OK, I guess I will just mark it as fixed now, since: - the uvesafb part of the problem is fixed in the latest vanilla kernel, - I've just added the mem-write patch to Portage. (In reply to comment #13) ok. thank you very much for your patience i think this self-modifying BIOS problem deserves a bit more attention because, frankly, the BIOS cannot modify itself under normal circumstances, whether it runs from EEPROM or shadowed RAM. so it may very well be a problem with the v86d emulation instead, especially since this segfault doesn't seem to occur without it (correct?). (In reply to comment #15) > runs from EEPROM or shadowed RAM. so it may very well be a problem with the > v86d emulation instead, especially since this segfault doesn't seem to occur > without it (correct?). https://bugs.gentoo.org/show_bug.cgi?id=196848#c54 seems to indicate that the problem is independent of the used emulation backend. Arthur: could you please confirm that testvbe still segfaults when compiled with USE="-x86emu"? (In reply to comment #16) > https://bugs.gentoo.org/show_bug.cgi?id=196848#c54 seems to indicate that the > problem is independent of the used emulation backend. Arthur: could you please > confirm that testvbe still segfaults when compiled with USE="-x86emu"? yes, that'd be useful info along with the actual kernel logs showing the fault info (eip/fault address/etc) so we can compare the two cases. (In reply to comment #16) > Arthur: could you please confirm that testvbe still segfaults when compiled with USE="-x86emu"? Sorry for the late reply. And confirmed suggestion. When I build v86d with USE="-x86emu" testvbe segfaults without any output: testvbe[8254]: segfault at c42c1 ip 000042d3 sp 00000fb0 error 7 in testvbe[9000+1000] (In reply to comment #18) > Sorry for the late reply. And confirmed suggestion. > When I build v86d with USE="-x86emu" testvbe segfaults without any output: > > testvbe[8254]: segfault at c42c1 ip 000042d3 sp 00000fb0 error 7 in > testvbe[9000+1000] could you dump and upload your video bios? something like a dd if=/dev/mem of=dump bs=4096 skip=192 count=16 would do it. Created attachment 171300 [details]
my video bios
here is a dump of my video bios
(In reply to comment #20) > Created an attachment (id=171300) [edit] > my video bios > > here is a dump of my video bios thanks, this is amazing but your BIOS does want to write to itself it seems: BIOS:42D3 mov cs:word_C42C1, ax intel must be pulling some tricks to keep the video BIOS mapped as writable... unfortunately it's bad news for PaX users, they'll either need to disable MPROTECT on v86d (and v86d will have to mmap with PROT_WRITE|PROT_EXEC) or resort to the now fixed emulation mode. bad intel, very bad ;P (In reply to comment #21) > intel must be pulling some tricks to keep the video BIOS mapped as writable... > unfortunately it's bad news for PaX users, they'll either need to disable > MPROTECT on v86d (and v86d will have to mmap with PROT_WRITE|PROT_EXEC) or > resort to the now fixed emulation mode. bad intel, very bad ;P Any advice on what is the best thing to do here? My personal preference would be to keep lrmi broken (with an added warning in the documentation and the ebuild) but secure. That means that for those people with self-modifying BIOS-es, x86emu would be the only option. If having v86d without mprotect is not considered a large security risk or is in some other way irrelevant, we can of course also fix lrmi to map the BIOS with PROT_WRITE. (In reply to comment #22) > Any advice on what is the best thing to do here? My personal preference would > be to keep lrmi broken (with an added warning in the documentation and the > ebuild) but secure. That means that for those people with self-modifying > BIOS-es, x86emu would be the only option. yes, that's the best approach for v86d i think. the real issue with a writable BIOS region is much worse however because it means that if an attacker can mmap that region, he can modify it, trigger a video BIOS call and bingo, he's got his code executed in ring-0 (read: full kernel compromise). this will work even on systems that otherwise restrict access to /dev/mem even for root since devmem_is_allowed() makes an explicit exception for the lower 1MB range. one could argue that root can do anything anyway, but that's not quite true on secure setups using MAC or even just STRICT_DEVMEM. anyway, this is not your problem really, i just wanted to point out that there's always a lesson in little things like an unexpected segfault and it's worth the time to investigate it, you never know what you'll uncover ;). funny thing is, based on my casual look at the BIOS disassembly, this code that writes to the BIOS doesn't seem to do anything useful at all (sets some flag if it isn't already, but that flag doesn't seem to be used anywhere else), probably some leftover debug code or something like that. > If having v86d without mprotect is not considered a large security risk or is > in some other way irrelevant, we can of course also fix lrmi to map the BIOS > with PROT_WRITE. v86d is a security risk because it's executed by the kernel directly and it runs as root (for the same reason init/udev/etc are all in the same category). so the prudent approach is what you have now, allow only emulation to write to the BIOS. note that i still don't like it that much because you're mapping it as shared (is it really needed?) therefore it does go back to the shadow ram copy of the BIOS (and hence visible from any process context as well), so an exploitable bug in v86d may result in the kernel compromise i mentioned above (same applies to the X server that also mmaps the same range). Just wanted to comment here, since this bug seems the most relevant to the problem I experienced. When moving from PaX-enabled hardened-sources 2.6.32-r9 to 2.6.32-r22 (the only change), with klibc-1.5.12-r1 and v86d-0.1.9, under qemu-kvm-0.12.5-r1 with vgabios.bin, all compiled with hardened gcc-4.4.4-r2, uvesafb failed to start with: (no segfault) uvesafb: Getting VBE info block failed (eax=0x4f00, err=1) uvesafb: vbe_init() failed with -22 uvesafb: probe of uvesafb.0 failed with error -22 the reason deduced to (citing from memory): # v86d mmap: operation not permitted Running "paxctl -m /sbin/v86d" removed the mmap error and fixed the issue. Recompiling v86d with +x86emu removed the mmap error and fixed the issue as well. After reading the discussion here, I understand that it is best to have +x86emu in any case for BIOSes who want to have self-modifying code, but it is strange that the problem manifested in QEMU's vgabios.bin (which I assume is not self-modifying), and with a revision-level upgrade of the kernel. |