Wednesday June 15, 2005 A Tour Through Devfs and Device Permissions
Admit it. You've always been curious to understand how the specifications in /etc/minor_perm get reflected in device permissions enforced at device access time. Perhaps even more than curious. Perhaps obsessed, even.
As a friend of mine would say with a sarcastic sneer: yeah, sure.
No doubt you're just like the rest of us and never given minor_perm any thought at all. Anyone who would want to spend even a nanosecond thinking about such a bland feature in an operating system when there's got to be a sitcom rerun playing on some channel would have to have a screw loose, right? Allow me to give you a brief tour describing how devfs manages the permissions specified in /etc/minor_perm before you reflexively answer that question in the affirmative.
Before Solaris 10 and devfs, the hierarchy below /devices was simply implemented in the root filesystem as a series of mkdir and mknod operations. Utilities such as devfsadm or drvconfig, responsible for creating the /devices hierarchy, would simply read /etc/minor_perm, applying any necessary changes with chmod and chown operations. This was simple but inefficient and relatively static.
Enter devfs. Devfs, as a filesystem mounted on top of /devices, has access to the files and directories of the underlying filesystem. The initial delivery of devfs still relied upon devfsadm to statically perform chmod/chown operations on device nodes as necessary. These attribute operations were implemented in devfs by simply pushing the operation down to the underlying root filesystem. All device access required checking the attributes of the underlying filesystem. This was necessary for two reasons: the information available in /etc/minor_perm was not available to devfs, and the only persistence mechanism available to devfs was to record the change in the underlying filesystem.
With the kernel-based filesystem implementation of devfs however, we had the opportunity to do something better. Well in time for the final builds of Solaris 10, we rewhacked the implementation of attributes management by pushing the minor perm information into the kernel. Together with a simple regular expression handler, this permits devfs to determine a minor node's ownership and permission attributes dynamically as a device is being configured on-demand.
Further, devfs gives us the opportunity to hard-wire certain aspects of system behavior so they can no longer be modified to operate incorrectly. For example, the permissions of traditional UNIX nodes such as /dev/null are now fixed so that it's impossible to remove write permission to this device. This is probably more of a performance optimization than a security feature but still it seems nice to simplify the operation of certain commonly-used and essential features in this fashion.
The actual ordering of ownership and permission attributes enforced within devfs is:
So, what's cool about this?
Solaris now no longer relies so heavily on the device nodes in the root filesystem underlying /devices. The system is more dynamic, scales a little better and requires less disk accesses to operate. In fact, Solaris can boot with an entirely empty base /devices hierarchy and yet the necessary permissions for all device nodes are being properly enforced. This was unimaginable only a few years ago. As delivered, /devices is not yet empty but that's just a matter of some more bug fixes here and there.
A minor_perm specification can now be applied dynamically to the system. Permissions derived from minor_perm were statically applied once. Now, an update to minor_perm performed via update_drv(1M) is applied dynamically to the system, and will be honored by all subsequent device accesses. Granted, most device permissions, with the exception of features such as logindevperm, are generally static, so this is for the most part a convenience to the occasional driver developer.
The administrator has explicit control. Device permissions can be modified for all minors, via update_drv(1M). Or a selected device can be changed via standard system tools. By the way, changing the permission of a minor node back to minor perm defaults is effected by removing the underlying attribute node, as minor perm specifications are automatically applied to a minor with no underlying attribute node override.
There, I bet that was more interesting than you initially thought it would be. Somehow I can hear my friend saying, yeah, sure, Jerry.
After the permission on a device is set via an explicit administrator override (chown or chmod), how do you undo the override so that /etc/minor_perm takes precedence? You mention removing the underlying attribute node, but I'm unclear how to do that. Thanks.
Posted by Roger Ripley on March 27, 2009 at 05:13 PM PDT #