The Linux Driver Model (LxDM) project aims to standardize kernel-level interfaces for loadable modules so that drivers not part of the monolithic tree can be designed on a guaranteed ABI and, ultimately, can become loadable by all future kernel releases.
The current design of the Linux kernel is a monolithic design; all drivers act as a part of the core kernel, even loadable modules. Because of this design, drivers often are faced with a different Applications Binary Interface (ABI) for each kernel version. This means that drivers often must be compiled against the current kernel sources to function properly.
If a standard ABI for drivers was supplied, such device drivers using that and only that ABI could be loaded on any kernel version supporting that ABI. Drivers supplied by vendors could remain closed and separated from the kernel, only relying on the headers for the ABI. This would facilitate third party vendor support, giving users a solution to hardware compatibility while OSS developers implement open sourced versions of the drivers. It would also allow OSS developers to keep their experimental, non-mainline drivers outside the tree without having to constantly chase new kernel interfaces.
The LxDM headers would define the API as a set of functions supplied by the ABI and a set of macros which use those functions supplied by the ABI. This is the primary separation between API and ABI: The API includes the symbols in the ABI as well as the macros which use those symbols, while the ABI is only the binary interface between modules and the kernel and thus must not change.
With the LxDM, closed source hardware drivers would more easily proliferate. This may not sit well with many open source developers who believe in open source drivers; however, currently, most if not all open source drivers are written by kernel developers rather than vendors. If open source drivers are important, then open source developers can write drivers to replace vendor-supplied ones.
The LxDM will only require minimal if any implementation. The goal of the LxDM project is to standardize the functions of existing kernel ABIs; the only potential changes would apply to module loading, or to the implementation details of the API—some API macros may be more suited as functions for this purpose, and may be changed or just cloned.
LxDM is not designed to be a cross-platform driver development model; it is intended to be a cross-version driver compatibility interface. In driver code, specific low-level operations will need to be separated. Drivers can and should supply themselves functions such as mydrv_write_data(void *data, int dlen) which are affected by conditional compiling based on the target platform to alleviate portability issues to some degree.
Because not all systems do low-level operations identically (mmio, pio), it is impossible for the LxDM to supply generic functions for some operations; functions for each method are supplied per platform.
LxDM has several modules, which can freely be used in whole or in part by any driver.
Hardware LxDM functions supply hardware access, such as reading and writing from and to hardware. Hardware may be split up into several modules, such as USB, PCI, etc.
Filesystem LxDM functions supply raw access to logical units. All write access below 0x10000 is prohibited for a device by default; although this limit can be altered by the driver. It is set as a simple bounds check to prevent writes to the first 128 sectors, where boot loaders may reside.
Meta-drivers are drivers that do things inside the kernel, but not necessarily with hardware. They are your /dev/ block and character devices. The Linux Driver Model re-implements the API required to create IOCTLs and file operation handlers on these devices. Initially this is done with wrapper calls or however necessary; our goal is to solidify or replace the current infrastructure.
This framework will also solidify the existing functionality of kmalloc() and vmalloc() and friends.
LxDM will be testing the waters for security modules. Initially, LxDM will use the LSM hooks as a simple proof-of-concept to determine the viability of creating a stackable LxDM interface for security. Our approach will be to consider any failure in any module as a failure overall, and thus require all LxDM security modules to return not-denied (success) for any access attempt to be successful. As with the rest of LxDM, the principal goal of LxDM security will be to supply a stable, extensible interface to security modules which will allow LxDM security modules to be loaded by any LxDM-capable kernel.
LxDM-security aims for security. The LxDM project must always remain focussed on this goal. In particular, REMEMBER THAT YOU ARE NOT THE ONLY SECURITY EXPERTS IN THE WORLD. The LxDM project must always accept and consider strongly outside help from credible security sources, especially taking into considerations systems which would use LxDM.
Lending an ear to the grsecurity, RSBAC, Hardened/Trusted BSD and Linux distribution, and regular Linux Kernel maintainers should always be a priority; these people understand what their systems need, and do things those ways for a reason.
If an interface poses a security hazard, remove it; things will break, but it's better than creating a vulnerability in the kernel. If an interface is needed for one obscure project, and doesn't pose a security hazard, add it.
Don't be proud; just be secure.
--John Moser, LxDM Founder
LxDM Security Modules will supply stacked, unordered hooks in the kernel; that is, any number of registered functions for each hook are executed in any order. The order does not change the outcome; any failure along the line indicates a lack of permission for that check.
The advantage of LxDM Security Modules over LSM is that LxDM interfaces stay binarily compatible accross kernel versions, even with extensions. The only breakage that could potentially occur would be if interfaces supplied created a security vulnerability, and thus were removed. Other than those cases, which should ideally never occur, the ABI should always be 100% compatible.
Each task, upon its creation, is given an array of structures each consisting of an LxDM-SM ID and a pointer to data for that module for that task. This array is passed when a check is made to determine which LxDM-SM modules affect the task.
LxDM-SM IDs will be managed with a 32 bit identifier consisiting of two parts, Order:ID. The Order will indicate the offset in the array of loaded LxDM-SM modules that the module's data exists at; and the ID will indicate the actual unique ID given at load time to the module. This facilitates accelerated look-ups and safe error recovery.
Each call to a module checks the ID of the module at Order first; if this ID is wrong, then the LxDM-SM code parses the entire array of loaded modules to find that ID. It then corrects the Order in the task. In this way, any call to an LxDM-SM hook will usually be handled expediently; however, if modules have been added and removed in such a way as to change the Order, the task's data will be updated to reflect it after a slightly slower check.
Loading and unloading of LxDM-SM modules will be lockable with a sysctl. The LSM project decided that stackable modules could be dangerous; LxDM-SM will support this decision, but it will also support stackable modules. The choice of whether to lock module stacking is up to the system administrator.
LxDM-SM modules are held in reference by any task using those modules. They cannot be immediately unloaded; however, LxDM will implement a module unloading function to slate a module for unloading when it becomes free.