Subject: kern/16300: unprivileged PCI config space access considered harmful
To: None <>
From: Klaus Klein <>
List: netbsd-bugs
Date: 04/11/2002 16:29:01
>Number:         16300
>Category:       kern
>Synopsis:       unprivileged PCI config space access considered harmful
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 11 07:36:00 PDT 2002
>Originator:     Klaus Klein
>Release:        2002-04-11
Frobozz Magic Packet Co.

	With the new pci(4) interface, it is possible for any process
	that can open a pci(4) device node for reading to arbitrarily
	read from configuration space.

	This is not necessarily without side effects.

	As set up by MAKEDEV(8), it is possible for any user to do so:
	crw-r--r--  1 root  wheel  83, 0 Nov 30 00:40 /dev/pci0


	503 3 we-the-jury:kleink Thu Apr 11 16:15:38 ~
	$ pcictl /dev/pci0 list
	000:11:0: Intel 82378ZB System I/O (SIO) (miscellaneous prehistoric, revision 0x03)
	000:12:0: Symbios Logic 53c810 (miscellaneous prehistoric, revision 0x01)
	000:14:0: Weitek P9100 (VGA display)
	504 4 we-the-jury:kleink Thu Apr 11 16:15:43 ~
	$ pcictl /dev/pci0 dump -d 12 >/dev/null

	Then observe:

	siop0:parity error
	siop0: scsi bus reset
	sd0: async, 8-bit transfers, tagged queueing
	sd0: sync (100.0ns offset 8), 8-bit (10.000MB/s) transfers, tagged queueing

	One can easily imagine more interesting side effects, depending on
	the device in question, but I didn't dare to find out.

	Three options that immediately come to my mind:

	1) Make pci(4) device nodes non-accessible in the standard setup.

	   This is probably a bit too drastic, and defeats one of the
	   interface's purposes.

	2) In pciioctl(), restrict access to registers free of side effects
	   defined in the PCI specification.

	   Ugly, but might do for most users.

	3) Use a device minor number bit as a flag to select a restriction
	   such as outlined in 2), and have an alternate device node, say,
	   /dev/pciuN accessible to all, with access permissions of the
	   /dev/pciN device nodes being restricted.

	   While this is the most flexible solution of the three, I guess
	   some will call it unintuitive...