Rev 183 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 183 | Rev 184 | ||
---|---|---|---|
Line 2... | Line 2... | ||
2 | \usepackage{graphicx} |
2 | \usepackage{graphicx} |
3 | 3 | ||
4 | \title{A Road to a Formally Verified General-Purpose Operating System} |
4 | \title{A Road to a Formally Verified General-Purpose Operating System} |
5 | \author{Martin D\v{e}ck\'{y}} |
5 | \author{Martin D\v{e}ck\'{y}} |
6 | \institute{Department of Distributed and Dependable Systems\\ |
6 | \institute{Department of Distributed and Dependable Systems\\ |
7 | Faculty of Mathematics and Physics, Charles University\\ |
7 | Faculty of Mathematics and Physics, Charles University\\ |
8 | Malostransk\'{e} n\'{a}m\v{e}st\'{i} 25, Prague 1, 118~00, Czech Republic\\ |
8 | Malostransk\'{e} n\'{a}m\v{e}st\'{i} 25, Prague 1, 118~00, Czech Republic\\ |
9 | \email{martin.decky@d3s.mff.cuni.cz}} |
9 | \email{martin.decky@d3s.mff.cuni.cz}} |
10 | 10 | ||
11 | \begin{document} |
11 | \begin{document} |
12 | \maketitle |
12 | \maketitle |
13 | |
13 | |
14 | \begin{abstract} |
14 | \begin{abstract} |
Line 130... | Line 130... | ||
130 | Many development projects such as task snapshoting and migration, support for MMU-less |
130 | Many development projects such as task snapshoting and migration, support for MMU-less |
131 | platforms and performance monitoring are currently underway. |
131 | platforms and performance monitoring are currently underway. |
132 | |
132 | |
133 | \medskip |
133 | \medskip |
134 | |
134 | |
135 | HelenOS can be briefly described as microkernel multiserver design. However, the actual design |
135 | HelenOS can be briefly described as microkernel multiserver OS. However, the actual design |
136 | guiding principles of the HelenOS are more elaborate: |
136 | guiding principles of the HelenOS are more elaborate: |
137 | |
137 | |
138 | \begin{description} |
138 | \begin{description} |
139 | \item[Microkernel principle] Every functionality of the OS that does not |
139 | \item[Microkernel principle] Every functionality of the OS that does not |
140 | have to be necessary implemented in the kernel should be implemented in user space. This |
140 | have to be necessary implemented in the kernel should be implemented in user space. This |
Line 149... | Line 149... | ||
149 | It contains features such as AVL and B+ trees, hashing tables, SLAB memory allocator, multiple |
149 | It contains features such as AVL and B+ trees, hashing tables, SLAB memory allocator, multiple |
150 | in-kernel synchronization primitives, fine-grained locking and so on. |
150 | in-kernel synchronization primitives, fine-grained locking and so on. |
151 | \item[Multiserver principle] Subsystems in user space should be decomposed with the smallest |
151 | \item[Multiserver principle] Subsystems in user space should be decomposed with the smallest |
152 | reasonable granularity. Each unit of decomposition should be encapsulated in a separate task. |
152 | reasonable granularity. Each unit of decomposition should be encapsulated in a separate task. |
153 | The tasks represent software components with isolated address spaces. From the design point of |
153 | The tasks represent software components with isolated address spaces. From the design point of |
154 | view the kernel can be seen as a separate component, too. |
154 | view the kernel can be seen as a separate software component, too. |
155 | \item[Split of mechanism and policy] The kernel should only provide low-level mechanisms, |
155 | \item[Split of mechanism and policy] The kernel should only provide low-level me\-chanisms, |
156 | while the high-level policies which are built upon these mechanisms should be defined in |
156 | while the high-level policies which are built upon these mechanisms should be defined in |
157 | user space. This also implies that the policies should be easily replaceable while keeping |
157 | user space. This also implies that the policies should be easily replaceable while keeping |
158 | the low-level mechanisms intact. |
158 | the low-level mechanisms intact. |
159 | \item[Encapsulation principle] The communication between the tasks/components should be |
159 | \item[Encapsulation principle] The communication between the tasks/components should be |
160 | implemented only via a set of well-defined interfaces. In the user-to-user case the preferred |
160 | implemented only via a set of well-defined interfaces. In the user-to-user case the preferred |
Line 225... | Line 225... | ||
225 | architecture to the programmer in a very straightforward, but still relatively portable way. |
225 | architecture to the programmer in a very straightforward, but still relatively portable way. |
226 | |
226 | |
227 | However, what is the biggest advantage of C in terms of run-time performance is also the biggest weakness |
227 | However, what is the biggest advantage of C in terms of run-time performance is also the biggest weakness |
228 | for formal reasoning. The permissive memory access model of C, the lack of any reference safety |
228 | for formal reasoning. The permissive memory access model of C, the lack of any reference safety |
229 | enforcement, the weak type system and generally little semantic information in the code -- all these |
229 | enforcement, the weak type system and generally little semantic information in the code -- all these |
230 | properties that do not allow to make many general assumptions about the code. |
230 | properties do not allow to make many general assumptions about the code. |
231 | |
231 | |
232 | Programming languages which target controlled environments such as Java or C\(\sharp\) are |
232 | Programming languages which target controlled environments such as Java and C\(\sharp\) are |
233 | generally easier for formal reasoning because they provide a well-known set of primitives |
233 | generally easier for formal reasoning because they provide a well-known set of primitives |
234 | and language constructs for object ownership, threading and synchronization. Many non-imperative |
234 | and language constructs for object ownership, threading and synchronization. Many non-imperative |
235 | programming languages can be even considered to be a form of ``executable specification'' and thus |
235 | programming languages can be even considered to be a form of ``executable specification'' and thus |
236 | very suitable for formal reasoning. In C, almost everything is left to the programmer who |
236 | very suitable for formal reasoning. In C, almost everything is left to the programmer who |
237 | is free to set the rules. |
237 | is free to set the rules. |
Line 271... | Line 271... | ||
271 | |
271 | |
272 | Some of the proposed methods cannot be called ``formal methods'' in the rigorous understanding |
272 | Some of the proposed methods cannot be called ``formal methods'' in the rigorous understanding |
273 | of the term. However, even methods which are based on semi-formal reasoning and non-exhaustive |
273 | of the term. However, even methods which are based on semi-formal reasoning and non-exhaustive |
274 | testing provide some limited guarantees in their specific context. A valued property |
274 | testing provide some limited guarantees in their specific context. A valued property |
275 | of the formal methods is to preserve these limited guarantees even on the higher levels |
275 | of the formal methods is to preserve these limited guarantees even on the higher levels |
276 | of abstraction, thus complementing the formal guarantees where the formal methods do not provide |
276 | of abstraction, thus allowing the semi-formal methods to complement the big picture |
277 | any feasible verification so far. This increases the coverage of the set of all hypothetical |
277 | where the formal methods do not provide any feasible verification so far. This increases |
278 | interesting properties of the system (although it is probably impossible to formally define |
278 | the coverage of the set of all hypothetical interesting properties of the system (although |
279 | this set). |
279 | it is probably impossible to formally define this entire set). |
280 | |
280 | |
281 | \medskip |
281 | \medskip |
282 | |
282 | |
283 | Please note that the titles of the following sections do not follow any particular established |
283 | Please note that the titles of the following sections do not follow any particular established |
284 | taxonomy. We have simply chosen the names to be intuitively descriptive. |
284 | taxonomy. We have simply chosen the names to be intuitively descriptive. |
Line 290... | Line 290... | ||
290 | programming language specification and passes only the basic semantic checks (proper number |
290 | programming language specification and passes only the basic semantic checks (proper number |
291 | and types of arguments passed to functions, etc.). It is perhaps not very surprising that |
291 | and types of arguments passed to functions, etc.). It is perhaps not very surprising that |
292 | these decisions can be made by any plain C compiler. However, with the current implementation |
292 | these decisions can be made by any plain C compiler. However, with the current implementation |
293 | of HelenOS even this is not quite trivial. |
293 | of HelenOS even this is not quite trivial. |
294 | |
294 | |
295 | Besides the requirement to support 7 hardware platforms, the system's compile-time configuration |
295 | Besides the requirement to support 7 hardware platforms, the system's com\-pile-time configuration |
296 | can be also affected by approximately 65 configuration options, most of which are booleans, |
296 | can be also affected by approximately 65 configuration options, most of which are booleans, |
297 | the rest are enumerated types. |
297 | the rest are enumerated types. |
298 | |
298 | |
299 | These configuration options are bound by logical propositions in conjunctive or disjunctive |
299 | These configuration options are bound by logical propositions in conjunctive or disjunctive |
300 | normal forms and while some options are freely configurable, the value of others gets inferred |
300 | normal forms and while some options are freely configurable, the value of others gets inferred |
Line 431... | Line 431... | ||
431 | On the first sight it does not seem to be reasonable to consider general model checkers as |
431 | On the first sight it does not seem to be reasonable to consider general model checkers as |
432 | relevant independent tools for formal verification of an existing OS. While many different |
432 | relevant independent tools for formal verification of an existing OS. While many different |
433 | tools use model checkers as their backends, verifying a complete model of the entire |
433 | tools use model checkers as their backends, verifying a complete model of the entire |
434 | system created by hand seems to be infeasible both in the sense of time required for the model |
434 | system created by hand seems to be infeasible both in the sense of time required for the model |
435 | creation and resources required by the checker to finish the exhaustive traversal of the model's |
435 | creation and resources required by the checker to finish the exhaustive traversal of the model's |
436 | address space. |
436 | state space. |
437 | |
437 | |
438 | Nevertheless, model checkers on their own can still serve a good job verifying abstract |
438 | Nevertheless, model checkers on their own can still serve a good job verifying abstract |
439 | properties of key algorithms without dealing with the technical details of the implementation. |
439 | properties of key algorithms without dealing with the technical details of the implementation. |
440 | Various properties of synchronization algorithms, data structures and communication protocols |
440 | Various properties of synchronization algorithms, data structures and communication protocols |
441 | can be verified in the most generic conditions by model checkers, answering the |
441 | can be verified in the most generic conditions by model checkers, answering the |
Line 472... | Line 472... | ||
472 | \item[Horizontal compliance] Also called \emph{compatibility}. The goal is to check |
472 | \item[Horizontal compliance] Also called \emph{compatibility}. The goal is to check |
473 | whether the specifications of components that are bound together are semantically |
473 | whether the specifications of components that are bound together are semantically |
474 | compatible. All required interfaces need to be bound to provided interfaces and |
474 | compatible. All required interfaces need to be bound to provided interfaces and |
475 | the communication between the components cannot lead to \emph{no activity} (a deadlock), |
475 | the communication between the components cannot lead to \emph{no activity} (a deadlock), |
476 | \emph{bad activity} (a livelock) or other communication and synchronization errors. |
476 | \emph{bad activity} (a livelock) or other communication and synchronization errors. |
477 | \item[Vertical compliance] Also called \emph{substituability}. The goal is to check whether |
477 | \item[Vertical compliance] Also called \emph{substituability}. The goal is to check whe\-ther |
478 | it is possible to replace a set of primitive components that are nested inside a composite |
478 | it is possible to replace a set of primitive components that are nested inside a composite |
479 | component by the composite component itself. In other words, this compliance can answer the |
479 | component by the composite component itself. In other words, this compliance can answer the |
480 | questions whether the architecture description of the system is sound with respect to the hierarchical |
480 | question whether the architecture description of the system is sound with respect to the hierarchical |
481 | composition of the components. |
481 | composition of the components. |
482 | \item[Compliance between the specification and the implementation] Using various means |
482 | \item[Specification and implementation compliance] Using various means |
483 | for generating artificial environments for an isolated component the checker is able to |
483 | of generating artificial environments for an isolated component a checker is able to |
484 | partially answer the question whether the implementation of the component is an instantiation |
484 | partially answer the question whether the implementation of the component is an instantiation |
485 | of the component specification. |
485 | of the component specification. |
486 | \end{description} |
486 | \end{description} |
487 | \item[Description as abstraction] Generating the behavior and architecture description from the |
487 | \item[Description as abstraction] Generating the behavior and architecture description from the |
488 | source code by means of abstract interpretation can serve the purpose of verifying various |
488 | source code by means of abstract interpretation can serve the purpose of verifying various |
489 | properties of the implementation such as invariants, preconditions and postconditions. |
489 | properties of the implementation such as invariants, preconditions and postconditions. |
490 | This is similar to static verification, but on the level of component interfaces. |
490 | This is similar to static verification, but on the level of component interfaces. |
491 | \end{description} |
491 | \end{description} |
492 | |
492 | |
493 | Unfortunately, most of the behavior and architecture formalisms are static, which is not quite suitable |
493 | Unfortunately, most of the behavior and architecture formalisms are static, which is not quite suitable |
494 | for the dynamic of most OSes. This limitation can be circumvented by considering a relevant |
494 | for the dynamic nature of most OSes. This limitation can be circumvented by considering a relevant |
495 | snapshot of the dynamic run-time architecture. This snapshot fixed in time is equivalent to |
495 | snapshot of the dynamic run-time architecture. This snapshot fixed in time is equivalent to |
496 | a statically defined architecture. |
496 | a statically defined architecture. |
497 | |
497 | |
498 | \medskip |
498 | \medskip |
499 | |
499 | |
Line 555... | Line 555... | ||
555 | |
555 | |
556 | \medskip |
556 | \medskip |
557 | |
557 | |
558 | We have spoken only about the functional properties. In general, we cannot apply the same formalisms |
558 | We have spoken only about the functional properties. In general, we cannot apply the same formalisms |
559 | and methods on extra-functional properties (e.g. timing properties, performance properties, etc.). |
559 | and methods on extra-functional properties (e.g. timing properties, performance properties, etc.). |
560 | And although it probably does make a good sense to reason about component composition for the extra-functional |
560 | And although it probably does make a good sense to reason about component composition for the extra-functi\-onal |
561 | properties, the exact relation might be different compared to the functional properties. |
561 | properties, the exact relation might be different compared to the functional properties. |
562 | |
562 | |
563 | The extra-functional properties need to be tackled by our future work. |
563 | The extra-functional properties need to be tackled by our future work. |
564 | |
564 | |
565 | \section{Evaluation} |
565 | \section{Evaluation} |
Line 582... | Line 582... | ||
582 | most of the verification checks of the compilers. The compilers trip on common bug antipatterns such |
582 | most of the verification checks of the compilers. The compilers trip on common bug antipatterns such |
583 | as implicit typecasting of pointer types, comparison of signed and unsigned integer values (danger |
583 | as implicit typecasting of pointer types, comparison of signed and unsigned integer values (danger |
584 | of unchecked overflows), the usage of uninitialized variables, the presence of unused local variables, |
584 | of unchecked overflows), the usage of uninitialized variables, the presence of unused local variables, |
585 | NULL-pointer dereferencing (determined by conservative local control flow analysis), functions |
585 | NULL-pointer dereferencing (determined by conservative local control flow analysis), functions |
586 | with non-void return typed that do not return any value and so on. We treat all compilation warnings |
586 | with non-void return typed that do not return any value and so on. We treat all compilation warnings |
587 | as fatal errors, thus the code base must pass without any warnings. |
587 | as fatal errors (\texttt{-Werror}), thus the code base must pass without any warnings. |
588 | |
588 | |
589 | We also turn on several more specific and strict checks. These checks helped to discover several |
589 | We also turn on several more specific and strict checks. These checks helped to discover several |
590 | latent bugs in the source code: |
590 | latent bugs in the source code: |
591 | |
591 | |
592 | \begin{description} |
592 | \begin{description} |
Line 634... | Line 634... | ||
634 | \subsection{Instrumentation} |
634 | \subsection{Instrumentation} |
635 | We are in the process of implementing our own code instrumentation framework which is motivated mainly |
635 | We are in the process of implementing our own code instrumentation framework which is motivated mainly |
636 | by the need to support MMU-less architectures in the future. But this framework might be also very helpful |
636 | by the need to support MMU-less architectures in the future. But this framework might be also very helpful |
637 | in detecting memory and generic resource leaks. We have not tried \emph{Valgrind}~\cite{valgrind} or any similar |
637 | in detecting memory and generic resource leaks. We have not tried \emph{Valgrind}~\cite{valgrind} or any similar |
638 | existing tool because of the estimated complexity to adopt it for the usage in HelenOS. |
638 | existing tool because of the estimated complexity to adopt it for the usage in HelenOS. |
639 | |
- | |
640 | HelenOS was also scanned by \emph{Coverity}~\cite{coverity} in 2006 when no errors were detected. However, since |
- | |
641 | that time the code base has not been analyzed by Coverity. |
- | |
642 | |
639 | |
643 | \subsection{Static Analyzer} |
640 | \subsection{Static Analyzer} |
644 | The integration of various static analyzers into the HelenOS continuous integration process is underway. |
641 | The integration of various static analyzers into the HelenOS continuous integration process is underway. |
645 | For the initial evaluation we have used \emph{Stanse}~\cite{stanse} and \emph{Clang Analyzer}~\cite{clanganalyzer}. |
642 | For the initial evaluation we have used \emph{Stanse}~\cite{stanse} and \emph{Clang Analyzer}~\cite{clanganalyzer}. |
646 | Both of them showed to be moderately helpful to point out instances of unreachable dead code, use of language |
643 | Both of them showed to be moderately helpful to point out instances of unreachable dead code, use of language |
647 | constructs which have ambiguous semantics in C and one case of possible NULL-pointer dereference. |
644 | constructs which have ambiguous semantics in C and one case of possible NULL-pointer dereference. |
648 | |
645 | |
649 | The open framework of Clang seems to be very promising for implementing domain-specific checks (and at |
646 | The open framework of Clang seems to be very promising for implementing domain-specific checks (and at |
650 | the same time it is also a very promising compiler framework). Our mid-term goal is to incorporate some of the features |
647 | the same time it is also a very promising compiler framework). Our mid-term goal is to incorporate some of the features |
651 | of Stanse and VCC (see Section \ref{staticverifier2}) into Clang Analyzer. |
648 | of Stanse and VCC (see Section \ref{staticverifier2}) into Clang Analyzer. |
- | 649 | |
|
- | 650 | HelenOS was also scanned by \emph{Coverity}~\cite{coverity} in 2006 when no errors were detected. However, since |
|
- | 651 | that time the code base has not been analyzed by Coverity. |
|
652 | |
652 | |
653 | \subsection{Static Verifier} |
653 | \subsection{Static Verifier} |
654 | \label{staticverifier2} |
654 | \label{staticverifier2} |
655 | We have started to extend the source code of HelenOS kernel with annotations understood |
655 | We have started to extend the source code of HelenOS kernel with annotations understood |
656 | by \emph{Frama-C}~\cite{framac} and \emph{VCC}~\cite{vcc}. Initially we have targeted simple kernel data structures |
656 | by \emph{Frama-C}~\cite{framac} and \emph{VCC}~\cite{vcc}. Initially we have targeted simple kernel data structures |