<<

Autocorrelation-Based Detection of Infinite Loops at Runtime

Andreas Ibing, Julian Kirsch and Lorenz Panny Chair for IT Security TU Munchen¨ Boltzmannstrasse 3, 85748 Garching, Germany

Abstract—We present a new for the detection of implemented with a watchdog timer in embedded systems: infinite loop bugs in software. Source code is not needed. The A watchdog timer has to be actively reset by the software algorithm is based on autocorrelation of a program execution’s perpetually, otherwise the watchdog triggers a system restart. branch target address sequence. We describe the implementa- tion of the algorithm in a dynamic binary instrumentation tool; A more recent example is found in dynamic symbolic the result is lightweight enough to be applied continuously at execution tools [3], [4]. Dynamic symbolic execution is a runtime. Functionality of the tool is evaluated with infinite testing approach where program execution is automatically loop bug test cases from the Juliet test suite for program driven into different program paths. The corresponding analyzers. Applicability of the algorithm to production software program input is automatically generated with a constraint is demonstrated by using the tool to detect previously known infinite loop bugs in cgit, Avahi and PHP. solver, typically a Satisfiability Modulo Theories (SMT, [5]) solver. These symbolic execution tools also set a maximum Keywords-Program analysis; infinite loops; dynamic binary duration of unresponsiveness, after which an infinite loop instrumentation bug is reported. The second approach is to prove termination or non- I.INTRODUCTION termination using an automated theorem prover, again typ- Infinite loop bugs are both an issue of software safety and ically an SMT solver. While (non-)termination can not be of software security. A program that runs into an infinite decided for all loops in general, it can be decided often loop becomes unresponsive, which violates safety properties. enough to be of practical use. Prominent tools include [6]– If an infinite loop can be triggered with program input by [11]. Because these tools are not perfect, there is still an an attacker, the program is vulnerable to a denial of service interest in detecting infinite loops at runtime. The process of attack. Under the common weakness enumeration [1], infinite translating a program into logic equations and especially loops are known as CWE-835 (‘loop with unreachable exit theorem proving itself is too complex to be applicable condition’). continuously at runtime. In [12] it is proposed to connect a Possible mitigation approaches to infinite loop bugs include symbolic execution tool called Looper at a user’s request the usage of testing tools in order to detect and remove to an unresponsive process. The tool would then single-step bugs before deployment, or to use light-weight program with symbolic execution and try to prove that an infinite loop instrumentation to catch an infinite loop when in occurs at is executed. runtime. The third approach uses hash values of concrete program The problem of finding infinite loops in programs is states to verify the execution of an infinite loop by finding a as old as computing itself. A perfect bug checker would recurrence program state [13]. The tool presented in [13] is detect all infinite loops in any program without false connected at a user’s request to an unresponsive process negative detections, without false positive detections, and and single-steps this process. At branches, the program with bounded runtime. Because the Halting Problem is known state including register and memory contents is hashed and to be undecidable in general [2], such a perfect bug checker compared to previous hash values. If a hash appears more can not exist. Any real detection algorithm must therefore than once, an infinite loop is reported. drop at least one of the three properties and tolerate either This paper presents a new algorithm for automated false positive detections, false negative detections, or running detection of infinite loops. It is sufficiently lightweight into non-termination itself. to be applied continuously at runtime. It does not need Nevertheless, three principle approaches to automated constraint solver, program source code or hash values over infinite loop detection have been developed and are in program states. The algorithm is based on autocorrelation, practical use today. The oldest one is to set a maximum a computation commonly used in many areas of applied duration after which an unresponsive program is assumed statistics: One example is in time series analysis to identify to be stuck in an infinite loop. This approach is most often periodic changes. Another example is in processing, 1 i n t main ( i n t argc , char ∗∗ argv ) { where p is the period length. The autocorrelation function 2 unsigned int i , j , k = 0 ; 3 /∗ I n f i n i t e loop: incrementi instead ofj ∗/ Rff (l) always has a peak value for l = 0. For a periodic 4 f o r ( j = 1 ; j < 0x10000; i++) function of period p, the autocorrelation also peaks at the 5 f o r ( i = 0 ; i < 0x10 ; i ++) 6 k ++; period length l = p and its integer multiples. For the 7 } detection of infinite loops in programs, we slightly adapt the autocorrelation as described in the following sections. Figure 1: Sample program containing an infinite loop A. Detecting periodic infinite loops A path through a program can be represented by the 1 004004 b6

: 2 004004 b6 : push rbp corresponding sequence of branches, i.e., the sequence 3 004004 b7 : mov rbp,rsp of branch target addresses. The branches comprise both 4 5 004004 ba : mov DWORD PTR [rbp −0x14 ] ,edi conditional branches and unconditional branches (jumps). 6 004004 bd : mov QWORD PTR [rbp −0x20 ] ,rsi A branch target address sequence is denoted as: 7 004004 c1 : mov DWORD PTR [rbp −0x8 ] , 0 x1 8 004004 c8 : jmp 4004 e5 b(n) n ∈ [0, m] 9 004004 ca : mov DWORD PTR [rbp −0x4 ] , 0 x0 10 004004 d1 : jmp 4004 db 11 where b(0) is the first branch after the program’s entry point, 12 004004 d3 : add DWORD PTR [rbp −0xc ] , 0 x1 and b(m) is the last taken branch, leading to the current 13 004004 d7 : add DWORD PTR [rbp −0x4 ] , 0 x1 14 004004 db : cmp DWORD PTR [rbp −0x4 ] , 0 xf program execution state. The idea is to detect an infinite 15 004004 df : jbe 4004 d3 loop through the branch sequence, which is assumed to 16 004004 d7 : add DWORD PTR [rbp −0x4 ] , 0 x1 17 become periodic. To this end, the autocorrelation of the 18 004004 e5 : cmp DWORD PTR [rbp −0x8],0xffff branch sequence is computed on-the-fly during program 19 004004 ec : jbe 4004 ca 20 004004 ee : mov eax,0x0 execution. 21 004004 f3 : pop rbp m 22 004004 f4 : r e t X Rbb(l, m) = b(n)b(n − l) , l = 0..m n=1 Figure 2: Compiled version of the sample program The value for l = 0 is not of interest and not computed, because an infinite loop has a positive period length. If the program runs into an infinite loop with period length p, the for synchronization in communication systems. We apply autocorrelation will show a peak at Rbb(l = p, m), where autocorrelation as an efficient way to identify suspicious the peak value increases with the number of branches m. branch sequences on-the-fly. Unlike in other applications of autocorrelation where a The remainder of this paper is organized as follows. periodic function undergoes some time variance due to noise, Section II describes and illustrates the algorithm in detail. here we have identical periods. Therefore, we replace the Section III presents an implementation using dynamic binary multiplication with Kronecker’s delta function: instrumentation. Algorithm properties are described in detail ( in Section IV. Experiments with the resulting tool are 1 if i = j δ(i, j) = i, j ∈ Z described in section V. The tool is evaluated with infinite 0 else loop test cases from the Juliet suite [14], and it is used to That yields: detect known infinite loop bugs in Avahi, cgit and PHP. m Related work is reviewed in section VI. Results of the tool X   evaluation are discussed in section VII. Rbb(l, m) = δ b(n), b(n − l) , l = 0..m n=1 II.ALGORITHM: MODIFIED AUTOCORRELATION FOR i.e., the autocorrelation value is only increased if the branch BRANCH TARGET ADDRESS SEQUENCE ANALYSIS target address is identical to the target address of l branches Autocorrelation is the correlation of a function f(n) with before. The recursive version for on-the-fly computation is: itself at different points in time. It computes the similarity   R (l, m) = R (l, m − 1) + δ b(m), b(m − l) between the function and a time-lagged version of itself, bb bb where the time lag l is variable. The (discrete) autocorrelation We also want to consider the falsification of an infinite Rff at lag l for a real-valued function f(n) is: loop hypothesis. If a periodic sequence is broken, we reset the X corresponding correlation value(s). The recursive computation Rff (l) = f(n)f(n − l) becomes: n∈Z ( Rbb(l, m − 1) + 1 if b(m) = b(m − l) For a periodic function f(n) we have: Rbb(l, m) = 0 else f(n + p) = f(n) (1) Figure 3: A static snapshot of the autocorrelation val- Figure 4: A selected time frame observing two dynamically ues Rbb(l, lmax ) at forcibly induced program termination changing values (Rbb(18, lmax ), Rbb(19, lmax )) during pro- (Rbb(18, lmax ) ≥ T ) gram execution

An infinite loop candidate is identified if the correlation exceeds a pre-defined threshold value T : p which are non-zero multiples of 19 clearly indicate the periodicity of the generated assembly code: To perform Rbb(l, m) > T for any l (2) one complete iteration of the outer loop, the conditional 0x4004df the period of the infinite loop is p = l, i.e., the index of branch at corresponding to the inner loop is the correlation value that first exceeds the threshold T . The considered 17 times (16 times taken, once not taken) by the 0x4004ec location of the infinite loop is given by the p last branch algorithm, and with the conditional jump at and 0x4004d1 target addresses. the unconditional jump at this results in a total of 19 branches. The diagram in Figure 4 visualizes the behaviour Correlation length: In order to limit the buffer length of two selected autocorrelation values while the instrumented for branch target addresses and autocorrelation values to a program is executing. We chose one autocorrelation value at a constant size independent of the length of a program path, position congruent to the periodicity of the sample program the autocorrelation length can be limited. R (l, m) is then bb and the direct neighbouring value and plot the different only computed for indices l ∈ [1..l ]. With such a fixed max behaviours over time. The diagram shows that the first value correlation length, the algorithm detects infinite loops with a increases steadily while the second autocorrelation value period of up to p = l . max follows a sawtooth-like shape. Illustration: We provide a sample program as depicted in Figure 1 to clarify how the algorithm behaves during program execution. To understand the results, we briefly consider the x86 assembly code (Figure 2 generated out B. Detecting certain non-periodic infinite loops of 1 by the GNU C (version 4.9.2): The outer (infinite) loop is transformed into an unconditional branch at virtual address 0x4004c8 and a conditional one at There are non-periodic infinite loops, i.e., infinite loops address 0x4004ec. Similarly, the branches at 0x4004d1 whose branch sequence depends on input. An example is and 0x4004df represent the inner loop. Local variables i, shown in Figure 5 in assembly. Every second branch targets j and k are addressed relatively to the base pointer rbp .loop, but the branch in between is random. at offsets -0x4, -0x8 and -0xc within the current stack The algorithm can be generalized to also detect infinte frame. Figure 3 shows the autocorrelation values at the time of loops with non-deterministic branches, as long as the branch (forced) program termination (that is ∃l : Rbb(l, lmax ) ≥ T ) sequences in the loop have equal length. The following 8 when choosing lmax = T = 2 . The peaks at positions recursive correlation detects re-visited branches with constant b(m) 1 . l o o p : 2 r d r a n d %ax 3 t e s t $1 , %ax R (l,f) bb 4 j n z . o n e 5 . z e r o : 6 jmp . l o o p 7 . o n e : 8 jmp . l o o p

Figure 5: Example non-periodic infinite loop in x86 assembly m l f Figure 6: Triangular coefficient matrix branch sequence length:  Rbb(l, f, m − 1) for f 6≡ m (mod l)  program at runtime. This is typically achieved by injecting Rbb(l, f, m − 1) + 1 for f ≡ m (mod l)  callback functions into a Just-In-Time (JIT) compiled version Rbb(l, f, m) = ∧ b(m) = b(m − l)  of the instrumented program which can then observe and/or 0 for f ≡ m (mod l)  manipulate the internal state of the program. Dynamic binary  ∧ b(m) 6= b(m − l) instrumentation lends itself very well towards program anal- (3) ysis as it allows for fine-grained inspection of arbitrary code where f is an offset modulo l. The coefficent vector becomes without having to rely on the presence of the executable’s a triangular matrix (compare Figure 6). source code. Programs based on instrumentation frameworks The number of coefficient computations is the same as are usually referred to as tools. before, i.e., for every new branch and for each l, only one The source code of our implementation can be seen in coefficient is updated (the one for which f ≡ m (mod l)). Figure 7: The code adds a callback function Branch() But the number of coefficients increases to: to all conditional and unconditional branches that reside in l the virtual address space of the main executable program N = max (l − 1), coeff 2 max image. It is the injected handler function’s responsibility to i.e., the space for coefficient storage increases quadratically re-compute each autocorrelation value Rbb (line 15) and to with correlation length. The example non-periodic infinite store the most recent branch target. Moreover, the Branch() loop is detected with the extended algorithm (triangular function ensures that T is still the upper bound of all values R coefficient matrix) with lmax ≥ 2. residing in bb. In case of a violation of this last constraint, the Pin tool outputs a warning in line 18. C. Avoiding false positives: optional SMT-based verification of candidate loops IV. PROPERTIES Depending on the theshold value and the application, the A. Complexity presented algorithm has false positive detections. If false positives are not tolerable, there is a possibility for verification 1) Time: The number of operations performed by the or falsification of infinite loop candidates. One iteration of algorithm per branch depends on the correlation length lmax. the candidate loop is executed with symbolic execution, and The algorithm updates lmax coefficients for every new branch, an SMT solver is used to check whether the loop is indeed and compares them against the threshold. It can therefore be infinite. If the candidate is not verified, the threshold can assumed, that the computation overhead increases linearly be increased by some factor. The SMT check for an infinite with correlation length lmax , and is independent of program loop is the same as described in [12] for the LOOPER tool. length. To confirm this, we instrumented an infinite-loop- This optional candidate verification however differs from free (terminating) version of the sample program with our LOOPER in that LOOPER searches for an infinite loop with algorithm implementation as Pin tool (using equation (1), i.e., unknown period length and unknown location. Therefore, without the modulo addressing of equation (3)) and measured LOOPER needs a number of solver checks that increases the total runtime for different values lmax . In the changed exponentially with period length, while the work at hand sample program, line 6 was updated to increment the local only needs one check for the infinite loop candidate. variable j instead of i. Benchmark results can be seen in Figure 8. III.IMPLEMENTATION WITH BINARY INSTRUMENTATION 2) Space: The amount of memory required to store branch We implemented our algorithm based on dynamic binary target addresses increases linearly with correlation length. instrumentation engine Pin [15]. The amount of memory required to store autocorrelation Dynamic binary instrumentation provides a mechanism to values increases linearly with correlation length when using monitor, inspect and alter the execution of any given binary equation (1), and quadratically when using equation (3). 1 #include ”pin.H” /∗ A l l other includes (terminating) test program running without instrumentation. o m i t t e d for readability reasons ∗/ 2 The same program takes about 200 ms running within an 3 #define T ( 5 0 0 ) /∗ T h r e s h o l d triggering empty Pin instance. We further obtain a runtime of about an abort ∗/ 4 #define M ( 1 6 ) /∗ Number of values ∗/ 450 ms for the sample program running within Pin using a 5 #define MASK(X) ((X) %M) correlation length of 100. This implies a slowdown of factor 6 450 7 s i z e t c u r = 0 ; 2 = 225 for the example correlation length. 8 unsigned long d s t [M] = { 0 }; /∗ Them last branch If faster execution is desirable, we consider to implement t a r g e t s ∗/ 9 unsigned long c n t [M] = { 0 }; /∗ Them valuesR bb(l, the described algorithm as compiler instrumentation (static m) ∗/ binary instrumentation at compile time). This gets rid of 10 11 void Branch ( unsigned long ip , bool taken , unsigned long the overhead introduced by Pin. The overhead added by Pin t a r g e t , unsigned long fallthrough) { are the fixed one-time overhead introduced by Pin’s JIT as 12 i f (!taken) target = fallthrough; 13 well as the dynamic part that depends on the number of 14 /∗ Check ifT has been surpassed by any of the branches within the target program. Both are independent of c o u n t e r s and update autocorrelation values ∗/ 15 f o r ( s i z e t i = 0 ; i < M; i ++) { the correlation length lmax . We thus argue that a compiler 16 cnt[i] = (dst[MASK(cur − i)] == target) ? cnt[i] + based instrumentation shows the same slope in dependence 1 : 0 ; 17 i f ( cnt [MASK( cur − i ) ] >= T) on lmax . This runtime is depicted as a dashed (green) line in 18 e r r o r (−1, 0 ,” detected. Figure 8, below the blue linear regression curve for measured Instruction:%p Target:%p \n”, ip, target ); values with Pin instrumentation. The blue line is the graph 19 } of the linear function t(lmax ) = 2156.2·lmax +302700 (t in 20 21 /∗ S t o r e most recent branch target ∗/ milliseconds). For lmax = 100 the slowdown factor decreases 22 cur = MASK(cur); to about 100 by changing from dynamic instrumentation to 23 dst[cur++] = target; 24 } static instrumentation. Additionally, our example program 25 consists of an unnaturally high fraction of branches compared 26 void Instruction(INS ins , void ∗v ) { 1 27 /∗ For any newly translated branch instruction in the to control-flow presevering instructions of ≈ 3 . For real- main image, adda callback to Branch() ∗/ world programs, one would expect this fraction between 28 i f (INS Category(ins) == XED CATEGORY COND BR | | INS Category(ins) == XED CATEGORY UNCOND BR) { 10% and 20%. This would decrease the slowdown factor 29 IMG img = IMG FindByAddress(INS Address(ins)); again, resulting in a slowdown factor of about 50 to 70 30 i f (IMG Valid(img) && IMG IsMainExecutable(img)) 31 INS InsertCall(ins , IPOINT BEFORE , (AFUNPTR) for real-world programs with compiler instrumentation and Branch , IARG INST PTR , IARG BRANCH TAKEN, correlation length 100. 32 IARG BRANCH TARGET ADDR, IARG FALLTHROUGH ADDR, IARG END) ; B. Incompleteness 33 } 34 } Completeness would mean the detection of all infinite 35 loops, i.e., that there are no false negative detections. Since 36 i n t main ( i n t argc , char ∗∗ argv ) { 37 i f (PIN Init(argc , argv)) return −1; there are non-periodic infinite loops that are not detected by 38 INS AddInstrumentFunction(Instruction , 0); the presented algorithm, and since periodic infinite loops with 39 PIN StartProgram() ; 40 } periodicity larger than correlation length are not detected, the presented algorithm is not complete. Figure 7: Implementation of the algorithm based on the PIN C. Soundness binary instrumentation framework Soundness means that any loop which is reported as infinite by the algorithm is indeed infinite, i.e., that there are no false positive detections. The presented algorithm uses a 3) Runtime Overhead: The runtime overhead of the Pin threshold comparison to select infinite loop candidates. This based instrumentation consists of three parts. A one-time candidate selection is not sound. It could arguably be seen overhead independent of program length and a dynamic as ‘asymptotically sound’ with an increasing threshold value. constant overhead for every branch are due to Pin. The The algorithm becomes sound by applying an SMT check third part is the actual autocorrelation, that causes a constant for a candidate and by only reporting loops whose non- overhead for every branch, where the overhead increases termination was proven by the check. linearly with correlation length (using equation (1)). The Intel Pin creators estimate the runtime overhead added D. Trade-offs by the instrumentation engine at a factor of 2.8 with just the The tool user can set the two algorithm paramters lmax JIT compiler enabled and at an average factor of 7.8 for a for correlation length and T as detection threshold. There basic-block counting instrumentation tool in the worst case are two trade-offs. The first trade-off concerns the number [15]. Figure 8 shows a run time of about 2 ms for the modified of false negative candidate detections versus algorithm 25 Instrumentation with Pin (linear regression) Expected using compiler instrumentation Run time without instrumentation 20

(s) 15 t

10 Runtime

5

0 0 2000 4000 6000 8000 10000

Correlation Length lmax Figure 8: Runtimes of the algorithm applied to a modified (terminating) version of the sample program. complexity. By increasing correlation length, the number of false negative detections. The runtimes until detection of the false negative candidate detections is reduced at the expense respective infinite loop are given in Table I. of increased program overhead. The second trade-off concerns The Juliet infinite loop tests have also been used in [16] the number of false positive detections versus detection delay. to test detection based on static symbolic execution on the By increasing the threshold T , the number of false positive source code level. An SMT solver is used to check for candidate detections is reduced at the expense of increased fixed-point satisfiability. Compared to [16], our tool achieves detection delay. An infinite loop must then be executed for correct detection an order of magnitude faster. For bigger more iterations until the threshold is reached. In our practical test programs, we would expect a larger speed-up with our tests, the threshold could be set very high (106 or more) tool, because on the small Juliet test programs a considerable without causing any significant detection delay. portion of the runtime is used to perform the instrumentation.

V. EXPERIMENTS B. Real-world programs Benchmark results are obtained on an Intel Core i7- To show that the algorithm scales to real-world problems, 2600 (3.4 GHz) on 64bit Linux kernel 3.16.0-4-amd64. The we triggered publicly known infinite-loop vulnerabilities in algorithm is run with equation (1). three widely-used open-source programs and successfully detected all of them using our implementation. The three A. Juliet suite vulnerabilities outlined below have been selected based on The Juliet test suite [14] is currently the most comprehen- the ease of triggering the bug. 1 sive test suite for C/C++ program analyzers. It is developed by • cgit is a web frontend for git repositories written in C. the United States National Security Agency’s (NSA) Center Prior to version 0.8.3.5, cgit contained an infinite loop for Assured Software and the National Institute of Standards bug that could be triggered by clients sending an invalid (NIST). The suite is freely available and consists of C/C++ hex escape in the URL query to the remote side. This source code covering over 100 common weaknesses. The test bug has been assigned CVE-2011-1027. cases are artificial and systematically combine basic bugs • Avahi is a Unix daemon providing service discovery in with different control and data flow variants. We use the local networks which is enabled by default in many 2 current Juliet version 1.2. For infinite loops it contains 6 test popular Linux distributions. Before version 0.6.29, programs, each with ‘good’ (bug-free) and ‘bad’ functions Avahi would enter an infinite loop upon receiving a (containing a bug). zero-length UDP packet (CVE-2011-1002). An example is shown in Figure 9. The infinite loop has a • PHP: Hypertext Processor is a highly popular server- 3 period of 1. The terminating ‘good’ loop is breaked after 10 side scripting language for web development. All ver- iterations. sions before 5.2.17/5.3.5 infinitely when processing We compile the programs and apply our tool with param- 1http://git.zx2c4.com/cgit/ eters T = 500 and lmax = 16. The tool correctly detects the 2http://avahi.org/ contained infinite loops without false positive and without 3http://php.net/ 1 void do 01 good1 ( ) { Testcase Runtime (s) 2 i n t i = 0 ; 3 do { Infinite_Loop__do_01 0.20 4 i f ( i == 10) { Infinite_Loop__do_true_01 0.20 5 break ; Infinite_Loop__for_01 0.14 6 } Infinite_Loop__for_empty_01 0.19 7 printIntLine(i); Infinite_Loop__while_01 0.14 8 i = (i + 1)%256; Infinite_Loop__while_true_01 0.14 9 } while ( i >= 0) ; 10 } 11 Table I: Error detection runtimes of the infinite loop test 12 void do 01 bad ( ) { cases from the Juliet suite 13 i n t i = 0 ; 14 do { 15 printIntLine(i); 16 i = (i + 1)%256; 17 } while ( i >= 0) ; while the proposed algorithm is applied to an individual 18 } program path. The prominent tools use static symbolic execution of the program source code, with loop invariant Figure 9: Example from Juliet test suite [14] generation [7], [8] and/or checking for satisfiable fixed-points or more generally recurrence sets [7], [11]. Proving non- termination is sound, i.e., it does not yield any false positive the string representation of the floating-point value infinite loop detections. In Looper [12], it is proposed to −308 2.2250738585072011 · 10 . This infinite loop bug is use a theorem prover to verify that a program is stuck in referenced as CVE-2010-4645. an infinite loop. The tool is to be run at user’s request, The results of our evaluation are compiled in Table II. and single-steps the unresponsive program with symbolic It features the detected jump target address period length execution. The work at hand for detection of infinite loop (as defined by the l value which caused Rbb(l, lmax ) to candidates with autocorrelation does not need a solver, and is exceed the threshold T ) as well as the wall-clock time orthogonal to the theorem proving approach. The presented difference between triggering the bug and forced termination algorithm spots unresponsiveness automatically by checking of the instrumented program using our implementation of the iteration number threshold. The theorem proving approach the algorithm. is much more complex, which makes it suited for analysis In all three cases, we used the threshold value T = 1024 before deployment. The presented algorithm on the other and initially conducted tests with lmax = 64. This yielded hand is lightweight enough for detection at runtime. positive results for the cgit and Avahi tests, detecting the The work at hand also differs from the approach of infinite loops of periodicities 22 and 3 within 0.23 and 0.07 finding concrete fixed-points by comparing program states at seconds, respectively. We discovered lmax = 64 to be too branches, as proposed in [13]. Program states can become few for the PHP test, since that bug exhibits a period length quite big, which makes this approach too complex to be run of 69 branches: After increasing lmax to 128, the infinite continuously. In [13], it is proposed to apply program state loop was detected within 0.78 seconds. comparisons only on demand in case a process becomes VI.RELATED WORK unresponsive. As noted in [13], this approach misses infinite loops where program states are not identical. Comparing Previous work on infinite loop detection relies on a process states as described in [13] is also not sound, i.e., it threshold for a maximum duration of unresponsiveness (e.g., might false positively report an infinite loop, because there is [3], [4]), on automated theorem proving [7]–[12], [16], or on also a kernel state (packet queues etc.) for a running process. comparing program states at branches [13]. The presented The kernel state is not included in the state comparisons. algorithm clearly differs from these approaches. On the one hand, specifying a threshold for maximum VII.DISCUSSION number of loop iterations does bear some resemblance to specifying a maximum duration of unresponsiveness. On Unlike previous work for sound detection, the presented the other hand, it is not straight-forward to predict an algorithm is lightweight enough for continuous detection of adequate time threshold, as execution speed depends on many infinite loops at runtime. While a watchdog timer needs to parameters like the underlying hardware, program input or be actively used by the programmer, the presented algortihm system load. This is why watchdogs are mainly used in can be used to monitor any program. embedded systems, where these parameters are predictable. In order to reduce the average overhead introduced by An iteration threshold is independent of such parameters, and the presented infinite loop detection, the correlation length could additionally be inferred from program source code if could be adaptively changed during program execution. One available (to avoid false detections). possibility is to introduce a lower-complexity ‘search mode’, The main difference to the theorem proving approach is where no correlation is computed at all. Instead, counters that it reasons about a multitude of program paths at once, can be increased for how often the program execution CVE Name lmax T Detection Time Measured Periodicity CVE-2011-1027 cgit 64 1024 0.23 s 22 CVE-2011-1002 Avahi 64 1024 0.07 s 3 CVE-2010-4645 PHP 128 1024 0.78 s 69

Table II: Selected CVEs passes individual branch locations. This essentially reduces [7] A. Gupta, A. Rybalchenko, T. Henzinger, R. Xu, and R. Ma- the algorithm overhead to an overhead value required by jumdar, “Proving non-termination,” in Symp. Principles of instrumentation to trace code coverage, like, e.g., gcov. If Programming Languages (POPL), 2008. any branch counter exceeds a pre-defined threshold Ts, the [8] H. Velroyen and P. Rummer, “Non-termination checking for algorithm can change into ‘correlation mode’. imperative programs,” in Tests and Proofs (TAP), 2008. There is the possibility of integrating the presented algo- rithm in CPUs, in order to benefit from hardware acceleration. [9] E. Payet and F. Spoto, “Experiments with non-termination Most CPUs already have a branch target address cache. analysis for Java Bytecode,” in BYTECODE, 2009, pp. 83–96. Detection of an infinite loop could be signaled with an [10] M. Brockschmidt, T. Stroder,¨ C. Otto, and J. Giesl, “Automated (to the ) and an operating system detection of non-termination and NullPointerExceptions for signal (to a process). The operating system could perform Java Bytecode,” in Int. Conf. Formal Verification of Object- verification / falsification with an SMT check to eliminate Oriented Software, 2011, pp. 123–141. false positives. Hardware acceleration would eliminate the [11] H. Chen, B. Cook, C. Fuhs, K. Nimkar, and P. O’Hearn, runtime software overhead of the proposed algorithm for “Proving nontermination via safety,” in Tools and correlation at the expense of some extra transistors. for the Construction and Analysis of Systems, 2014, pp. 156– Future work could be the re-implementation of the algo- 171. rithm with static binary instrumentation, and integration into the GNU compiler (gcc). gcc already features an address [12] J. Burnim, N. Jalbert, C. Stergiou, and K. Sen, “Looper: Lightweight detection of infinite loops at runtime,” in Int. sanitizer [17] and a thread sanitizer [18], but not yet a loop Conf. Automated Software Engineering, 2009. sanitizer. It seems further possible to combine the presented algo- [13] M. Carbin, S. Misailovic, M. Kling, and M. Rinard, “Detecting rithm with dynamic symbolic execution based testing. The and escaping infinite loops with Jolt,” in European Conf. synergy would be that symbolic execution drives the program Object-Oriented Programming, 2011, pp. 609–633. into different paths, where the presented algorithm could [14] T. Boland and P. Black, “Juliet 1.1 C/C++ and Java test suite,” perform lightweight detection of infinite loop candidates. IEEE Computer, vol. 45, no. 10, 2012.

REFERENCES [15] C. Luk, R. Cohn, R. Muth, H. Patil, A. Klauser, G. Lowney, [1] R. Martin, S. Barnum, and S. Christey, “Being explicit about S. Wallace, V. Reddi, and K. Hazelwood, “Pin: Building cus- security weaknesses,” CrossTalk The Journal of Defense tomized program analysis tools with dynamic instrumentation,” Software Engineering, vol. 20, pp. 4–8, 3 2007. in Proc. ACM Conf. Programming Language Design and Implementation, 2005, pp. 190–200. [2] A. Turing, “On computable numbers, with an application to the Entscheidungsproblem,” Proceedings of the London [16] A. Ibing and A. Mai, “A fixed-point algorithm for automated Mathematical Society, vol. 42, pp. 230–265, 1937. static detection of infinite loops,” in IEEE Int. Symp. High Assurance Systems Eng., 2015, pp. 44–51. [3] P. Godefroid, N. Klarlund, and K. Sen, “DART: Directed automated random testing,” in Conference on Programming [17] K. Serebryany, D. Bruening, A. Potapenko, and D. Vyukov, Language Design and Implementation, 2005, pp. 213–223. “AddressSanitizer: A fast address sanity checker,” in USENIX Annual Technical Conference, 2012, pp. 28–28. [4] K. Sen, D. Marinov, and G. Agha, “CUTE: A concolic unit testing engine for C,” in European Software Engineering [18] K. Serebryany and T. Iskhodzhanov, “ThreadSanitizer: data Conference and International Symposium on Foundations of race detection in practice,” in Workshop on Binary Instrumen- Software Engineering, 2005, pp. 263–272. tation and Applications, 2009, pp. 62–71.

[5] L. deMoura and N. Bjorner, “Satisfiability modulo theories: Introduction and applications,” Communications of the ACM, vol. 54, no. 9, 2011.

[6] A. Podelski and A. Rybalchenko, “A complete method for the synthesis of linear ranking functions,” in Int. Conf. Verification, Model Checking, and Abstract Interpretation (VMCAI), 2004.