Select Page

Reliable and secure device drivers

The system is only as secure as its weakest driver.

Author: André Schmitz, Green Hills Software

Contribution – Embedded Software Engineering Congress 2015

The biggest vulnerabilities in a software system are usually the device drivers. They often have access to all hardware registers and the DMA controller, run in the CPU's supervisor mode, and are the first point of contact with incoming data. This is a major reason why many software vulnerabilities and crash causes are found in the drivers. This article presents methods and technologies for making device drivers "secure," meaning that the impact of an attack on the drivers or a malfunction caused by software errors can be minimized, thereby improving the overall system's robustness.

What is a driver?

I assume most readers know what a driver is. Nevertheless, I would like to briefly summarize the most important aspects. A device driver is the software component that has direct access to the hardware and provides the application with an abstraction in the form of a hardware-independent interface (API) [1]. As such, a driver can both signal events (interrupts) to the application and transfer data between the application and the hardware. This can then also be done, for example, using a DMA or PCI controller.

Occasionally, protocol stacks, such as TCP/IP or USB host stacks, are also considered driver components. It's debatable whether these are drivers or rather target-independent "middleware" that works closely with a driver. However, the considerations in this paper also apply to these stacks.

In simple embedded systems, a driver can be very basic, for example, only activating a few GPIOs or controlling a relay. Simple event-driven events can even be handled directly in the interrupt handler. More complex operations require more code, which then runs in one or more tasks. The code of these tasks then accesses the hardware directly and provides higher software layers with an abstract interface to the hardware.

Why are drivers critical components of software?

Nearly all data processed by an embedded system passes through a driver as it crosses the system's boundaries. Drivers often run in privileged CPU mode to directly access hardware registers and memory. In this case, however, the driver can also access other memory or registers unrelated to its primary task. Whether intentional or unintentional, there is a possibility that a device driver could access other devices or manipulate arbitrary memory. This gives the driver a significant impact on the overall system's reliability and security.

A driver malfunction can lead to unauthorized data modification (integrity). A software error can cause the system to crash (reliability) or give a potential attacker access to confidential data (confidentiality). Ultimately, drivers are therefore a vital component of the overall system.

When drivers operate close to the operating system or can directly access hardware, malfunctions can have serious consequences. A malfunction in the driver code in the CPU's supervisor mode (Figure 1, see...) PDFThis can crash the entire system. A vulnerability in this code can allow an attacker to gain control of the entire system. Even a virtual driver running in user mode (Figure 2, see PDF), can pose a problem if the process is granted too many rights.

When it comes to attack scenarios, buffer overflows are found to be the most frequent cause of software vulnerabilities. A search of the Vulnerability Notes Database for the most critical software vulnerabilities reveals that buffer overflows are the cause of more than half of the reported vulnerabilities [2].

methods for protection

The potential risks of a driver can be mitigated by leveraging the principles of high-assurance software engineering. These principles encompass topics such as

  1. minimal rights allocation
  2. Division of the software into components
  3. Minimizing software complexity
  4. Use of a safe development process

Specifically to protect against the notorious buffer overflows, there are ways to find vulnerable points in the software using static code analysis (during the development process). If this doesn't identify all the points, a suitable compiler can be used to incorporate automatic runtime checks into the code. These checks can detect overflows even during code execution and then halt the program's flow. This is very helpful during development but can also be used in production systems.

Microkernel

Points 1 and 2 can be addressed particularly well using a microkernel. Using a microkernel, or more precisely a separation kernel, allows drivers to run in user mode (minimal privileges) and to run individual drivers separately from each other and from the application (separation into components). This is then called a "user-mode driver." In a well-structured system based on a separation kernel, a user-mode driver only has access to the hardware components it actually needs for its correct function; that is, it only "sees" the registers of the hardware module it is controlling (Figure 2, see...). PDFFurthermore, it only has access to the memory areas it actually needs for its work, and no others. For example, the display controller only sees the frame buffer in RAM and the controller's configuration registers, or the Ethernet driver only sees the area containing the memory for the Ethernet buffers and their descriptors.

DMA

Things get really interesting, for example, when accessing a DMA controller, which can be beneficial from a performance perspective. Access becomes critical in a microkernel when the user-mode driver can directly configure the DMA controller. In this case, the driver has the ability to address any memory location and read from or write to it. And if this driver is then hacked and the attacker gains control of the driver process, the attacker also regains control of the entire system because they can access any memory location via the DMA controller. But that's precisely what you want to avoid with a user-mode driver on a microkernel.

In this case, point 4 must be addressed by developing all drivers that access the DMA controller using a secure development process, ensuring that the driver code has a high degree of trustworthiness. Alternatively, considerable effort can be saved by using a microkernel, which allows small, trusted fragments of a driver to run in privileged CPU mode, directly alongside the kernel (Figure 2, left, see Figure 2). PDFOf course, in this case the driver must also be very well validated (development process), but since it involves very little and very simple code (minimizing complexity), the associated effort is significantly less than that for the DMA driver in user mode.

Summary

As described above, poorly designed or carelessly programmed device drivers can make an embedded system vulnerable to attack or even cause it to crash. They offer a large attack surface and often have numerous privileges, giving a software error a high potential impact. Applying the fundamental principles of high-assurance software engineering can significantly mitigate this problem. This includes, not least, the use of a separation kernel that employs user-mode drivers but also allows trusted driver code to be executed in kernel mode when appropriate.

References

[1] https://de.wikipedia.org/wiki/Gerätetreiber

[2] https://www.kb.cert.org/vuls/bymetric?open&start=1&count=20

Download the article as a PDF


Implementation – our training & coaching

Do you want to bring yourself up to date with the latest technology?

Then find out more here MircoConsult offers training courses/seminars/workshops and individual coaching on the topic of implementation/embedded and real-time software development.

Training & coaching on the other topics in our portfolio can be found here. here.


Implementation – Expertise

Valuable expertise in the field of implementation/embedded and real-time software development is available. here Available for you to download free of charge.

To the specialist information

You can find expertise on other topics in our portfolio here. here.

MicroConsult Newsletter

With the MicroConsult newsletter, you'll stay on the pulse of the embedded world. Look forward to proven practical knowledge, real professional tips, and current events – directly from our experts for your project success.

Subscribe now!

Published by

weissblau media

weissblau media