Page 379 -
P. 379

362   Chapter 13   Dependability engineering


                                    Guideline 6: Check array bounds
                                    All programming languages allow the specification of arrays—sequential data struc-
                                    tures that are accessed using a numeric index. These arrays are usually laid out in
                                    contiguous areas within the working memory of a program. Arrays are specified to
                                    be of a particular size, which reflects how they are used. For example, if you wish to
                                    represent the ages of up to 10,000 people, then you might declare an array with
                                    10,000 locations to hold the age data.
                                      Some programming languages, such as Java, always check that when a value is
                                    entered into an array, the index is within that array. So, if an array A is indexed from
                                    0 to 10,000, an attempt to enter values into elements A [-5] or A [12345] will lead to
                                    an exception being raised. However, programming languages such as C and C++ do
                                    not automatically include array bound checks and simply calculate an offset from the
                                    beginning of the array. Therefore, A [12345] would access the word that was 12345
                                    locations from the beginning of the array, irrespective of whether or not this was part
                                    of the array.
                                      The reason why these languages do not include automatic array-bound checking
                                    is that this introduces an overhead every time the array is accessed. The majority of
                                    array accesses are correct so the bound check is mostly unnecessary and increases
                                    the execution time of the program. However, the lack of bound checking leads to
                                    security vulnerabilities, such as buffer overflow, which I discuss in Chapter 14. More
                                    generally, it introduces a vulnerability into the system that can result in system fail-
                                    ure. If you are using a language that does not include array-bound checking, you
                                    should always include extra code that ensures the array index is within bounds. This
                                    is easily accomplished by implementing the array as an abstract data type, as I have
                                    discussed in Guideline 1.



                                    Guideline 7: Include timeouts when calling external components
                                    In distributed systems, components of the system execute on different computers and
                                    calls are made across the network from component to component. To receive some
                                    service, component A may call component B. A waits for B to respond before con-
                                    tinuing execution. However, if component B fails to respond for some reason, then
                                    component A cannot continue. It simply waits indefinitely for a response. A person
                                    who is waiting for a response from the system sees a silent system failure, with no
                                    response from the system. They have no alternative but to kill the waiting process
                                    and restart the system.
                                      To avoid this, you should always include timeouts when calling external com-
                                    ponents. A timeout is an automatic assumption that a called component has failed
                                    and will not produce a response. You define a time period during which you expect
                                    to receive a response from a called component. If you have not received a response
                                    in that time, you assume failure and take back control from the called component.
                                    You can then attempt to recover from the failure or tell the system user what has
                                    happened and allow them to decide what to do.
   374   375   376   377   378   379   380   381   382   383   384