Linux and automotive computing security
Linux and automotive computing security
Posted Oct 10, 2012 22:51 UTC (Wed) by SLi (subscriber, #53131)Parent article: Linux and automotive computing security
I am a Linux geek, and I work with safety critical systems (mostly safety critical methodology research). I think anyone who thinks Linux, or for that matter Windows or any other operating system most people here would have heard of, could run in a safety-critical setting in the foreseeable future simply misunderstands the nature of safety critical systems.
The first thing to understand is that safety is not the same as security. Most of this article talks about security. Security can affect safety, and certainly the safety critical industry should take it better into account, but it's only a very small part of the story. Also, many of the attacks mentioned in this paper do not concern safety at all. For example, someone being able to steal your car is not a safety concern. Safety concerns are exactly those that can lead to bodily harm or death of someone operating the system or other people.
As an example, a window closing mechanism in a car might be considered very slightly safety critical if it would be possible for it to chop off a finger if it malfunctions. Brakes would have a higher safety criticality level, since a car moving at a high speed without functional brakes can cause the death of not only the driver but also other people. The car stereos would generally be considered non-critical, but to certify the entire system, you will have to show sufficient separation between critical and non-critical systems, and also between less critical and more critical systems.
There are generally certain requirements that regulators require for safety critical code. Generally any code to be run in a safety critical context needs to be developed with an extraordinarily thorough and rigorous process. The entire process must be well documented, starting from the design, but also encompassing coding, testing, etc. There is a good rationale for this: Testing will never find all your bugs. Rigorous design and such things won't find them all either, but it won't hurt. The point is this: Safety is something that you need to build in from the beginning; you just cannot add it later.
This necessarily results in safety critical code being comparatively speaking very simple. The requirements also become more stringent when the criticality level (for example, SIL levels, where 1 is the least critical, such as car windows, and 4 would be the most critical, such as aeroplane control systems and nuclear reactors) rises. I would be surprised if there are very many high-criticality systems as complex as a TCP/IP stack, let alone the Linux kernel. You can run them in the car stereos, though.
Also, barring some very significant advance in program verification, the Linux kernel can never be even tested to the level required. Generally the lowest levels of criticality require things like a test suite with 100% coverage. To see the kind of testing required for higher levels, take a look at, for example, Modified Condition/Decision coverage (or see below). The only open source piece of software I know claims to have 100% MC/DC coverage is SQLite, and even they misunderstand it and basically only have plain Condition/Decision Coverage.
One of the requirements in MC/DC is that, for each source code level branching condition (boolean expression), you need to separately show (with tests in your test suite) for each subexpression that there is a pair of inputs where that expression only differs in the value of that subexpression such that different branches are taken. That is, if you have a condition:
if (a || (b && c)) { ... } else { ... }
you will have to write the following tests:
- A test that makes a true (e.g. a=1, b=0, c=0, branch taken=then)
- A test that makes a false with the same b and c as in the above test AND takes the other branch (e.g. a=0, b=0, c=0, branch taken=else)
- A test that makes b true (e.g. a=0, b=1, c=1, branch taken=then)
- A test that makes b false with the same a and c as in the above test AND takes the other branch (e.g. a=0, b=0, c=1, branch taken=else)
- A test that makes c true (the above a=0, b=1, c=1, branch taken=then test suffices for this)
- A test that makes c false with the same a and b as in the above test AND takes the other branch (e.g. a=0, b=1, c=0, branch taken=else)
- A test that makes (b && c) true (e.g. a=0, b=1, c=1, branch taken=then)
- A test that makes (b && c) false with the same a as in the above test AND takes the other branch (e.g. a=0, b=0, c=1, branch taken=else)
I hope you are starting to see the hopelessness of testing Linux, or basically any other piece of code that either is moderately large or not designed from the beginning to be so tested, to such a strict standard...
Note that the safety critical people do not claim this process is perfect. It just is a process that results in a lot of eyeballs staring at the code, the specification and the test cases and thinking about them and testing them from nearly every possible angle imaginable. It still happens that there are bugs, but they are certainly much more rare than bugs in Linux kernel :)