<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>AdaCore - The GNAT Pro Company &#187; Devt log &#8211; Gem of the Week</title>
	<atom:link href="http://www.adacore.com/category/developers-center/gems/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.adacore.com</link>
	<description>AdaCore technology and news</description>
	<lastBuildDate>Sun, 14 Mar 2010 08:49:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Gem #81: GNAT Semaphores</title>
		<link>http://www.adacore.com/2010/03/08/gem-81/</link>
		<comments>http://www.adacore.com/2010/03/08/gem-81/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 11:00:42 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3689</guid>
		<description><![CDATA[Ada Gem #81 &#8212; A previous Gem (#70, "The Scope Lock Idiom") discussed the occasional necessity of using low-level synchronization mechanisms instead of the higher-level protected object construct.  The code in that Gem referenced the facilities of the Semaphores package located in the GNAT hierarchy.  In this Gem, we examine the abstractions provided by that package, focusing especially on the design choices. ]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>A number of semaphore definitions exist, although the general concept remains as introduced by Dijkstra in 1968.  We assume the reader has some familiarity with semaphores and their semantics, and so we will not cover them here.  Many books are available for those requiring additional information. See especially <em>Principles of Concurrent and Distributed Programming</em> by M. Ben-Ari.</p>



<p>The GNAT.Semaphores package defines two semaphore abstractions, both in terms of protected types.  We use protected types, rather than defining abstract data types based on operating-system facilities, for the sake of portability.  A simple wrapper around the facilities of an operating system or RTOS would be reasonable, but the resulting interface (and implementation, of course) would not have the portability required of the general-purpose GNAT hierarchy.</p>



<p>The first abstraction defines a &#8220;counting&#8221; semaphore, in which an integer count is maintained by the operations, such that the acquire operation only executes (and thus returns, allowing the caller to continue) when the count is greater than zero.  Counting semaphores are convenient for expressing condition synchronization in terms of the availability of some number of resources.  For example, with a circular bounded buffer, a semaphore&#8217;s count can represent the number of available buffer slots.  Callers must wait for the buffer to be non-full when attempting to insert a new item, and the blocking call to acquire the semaphore will achieve that effect directly.</p>



<p>The declaration for the counting semaphore is as follows.  Note that we have removed the in-line comments for the sake of brevity, but will cover their content.</p>

<pre>
   <b>protected</b> <b>type</b> Counting_Semaphore
      (Initial_Value : Natural;
      Ceiling : System.Priority)
   <b>is</b>
      <b>pragma</b> Priority (Ceiling);

      <b>entry</b> Seize;
      <b>procedure</b> Release;

   <b>private</b>
      Count : Natural := Initial_Value;
   <b>end</b> Counting_Semaphore;
</pre>


<p>The second type implements &#8220;binary&#8221; semaphores.  This kind of semaphore is less flexible than the counting semaphore, in that no notion of a count is maintained.  The abstraction is simply that of a flag indicating whether or not the semaphore is available.  (If the value of a counting semaphore varied between zero and one, the effect would be the same.)</p>

<pre>
   <b>protected</b> <b>type</b> Binary_Semaphore
     (Initially_Available : Boolean;
      Ceiling : System.Priority)
   <b>is</b>
      <b>pragma</b> Priority (Ceiling);

      <b>entry</b> Seize;
      <b>procedure</b> Release;

   <b>private</b>
      Available : Boolean := Initially_Available;
   <b>end</b> Binary_Semaphore;
</pre>



<p>In both cases, the provided operations consist of an entry &#8220;Seize&#8221; to acquire the semaphore with mutually exclusive access, and a protected procedure &#8220;Release&#8221; to release it.  The Seize operation must be an entry for the sake of the barrier expressing the required condition synchronization.  Releasing the semaphore has no such requirement, so it need not be an entry.</p>



<p>Both types are visibly defined as protected types so that users can make conditional and timed calls when appropriate.  This capability addresses one of the portability problems with semaphores.  Although the basic &#8220;acquire&#8221; and &#8220;release&#8221; operations will always be provided (by whatever name), there is no &#8220;standard&#8221; interface for other forms of interaction.  Language-defined constructs provide some of those kinds of interactions, and do so portably.</p>



<p>Both types require discriminants.  The counting semaphore type uses a discriminant to specify the initial nonnegative value of the count.  The binary semaphore type uses a Boolean discriminant to specify whether the semaphore should be initially available.  For example, a binary semaphore would be initially available when used to express mutual exclusion, but might not be initially available when used to express condition synchronization.</p>



<p>In addition, both types use another discriminant to specify the ceiling priority for objects of the type. The discriminant is then passed as the argument to pragma Priority.  If the Real-Time Systems Annex is in force this part is essential; otherwise it has no effect.  Note that a default value cannot be provided for the Ceiling discriminant because that would require a default for the other discriminant, too.  The best we can do is to define a convenient value to be used in declarations of individual objects when the Real-Time Annex is not in force, so the following constant is provided in GNAT.Semaphores:</p>

<pre>
   Default_Ceiling : <b>constant</b> System.Priority := System.Default_Priority;
</pre>


<p>However, subtypes can be used to enhance convenience, readability and robustness.  The earlier Gem (#70) provided an example:</p>

<pre>
   <b>subtype</b> Mutual_Exclusion <b>is</b> Binary_Semaphore
     (Initially_Available =&gt; True,
      Ceiling             =&gt; Default_Ceiling);
</pre>


<p>The subtype ensures that corresponding objects are initially available, but also conveniently supplies the Ceiling discriminant value (assuming the Real-Time Annex is not in force) and gives the reader an indication of the intended use.</p>



<p>As you can see, the declarations of protected types can be very expressive.  The discriminants are the part you might not have considered using, although that is by no means an unusual approach. The protected bodies of both types are trivial and will not be shown here.  You can see them in the GNAT hierarchy, along with the implementations of all the other GNAT hierarchy packages.</p>]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2010/03/08/gem-81/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gem #80: Speedy Shift and Rotate in SPARK</title>
		<link>http://www.adacore.com/2010/02/25/gem-80/</link>
		<comments>http://www.adacore.com/2010/02/25/gem-80/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 13:50:16 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3502</guid>
		<description><![CDATA[Ada Gem #80 &#8212; This Gem covers a topic that I recently encountered
while working on a crypto algorithm in SPARK: how
to use Ada's predefined shift and rotate functions
with modular types from a SPARK program.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>

<p><strong>Introduction</strong></p>


<p>Ada 95 brought us the predefined package Interfaces, with its standard
definitions for types like Unsigned_32 and so on.
It also defines various functions to do common
shift and rotate operations on those types, such as:</p>

<pre>
   <b>function</b> Shift_Left
     (Value  : Unsigned_32;
      Amount : Natural) <b>return</b> Unsigned_32;
</pre>


<p>In GNAT Pro, these function declarations are
also followed by a curious-looking pragma:</p>

<pre>
   <b>pragma</b> Import (Intrinsic, Shift_Left);
</pre>


<p>The Ada 95 RM (6.3.1) says:</p>



<p>   &#8216;The intrinsic calling convention represents subprograms that
    are &#8220;built in&#8221; to the compiler.&#8217;</p>



<p>This basically means that the code generator &#8220;knows&#8221; how
to implement these functions. In the case of shifts and rotates,
this means that a call to one of these functions results in
very few (possibly just one) machine instructions &#8212; giving the
performance you&#8217;d expect from such a simple operation.</p>



<p>Shifts and rotates are useful in a wide variety of applications, 
but are endemic in cryptographic algorithms, where they
appear all over the place.</p>



<strong><p>So how can we get at them in SPARK?</p></strong>


<p>Unfortunately, the standard specification of package Interfaces
is not legal SPARK, since the various shift and rotate functions
are overloaded for each of the modular types, and overloading
within a scope is not allowed.  Darn&#8230;</p>



<p>To get round this, we first introduce a &#8220;shadow&#8221; specification
of Interfaces that supplies the legal SPARK bits that
we&#8217;re interested in &#8212; specifically the type declarations,
thus:</p>

<pre>
   <b>package</b> Interfaces <b>is</b>
      <b>type</b> Unsigned_8  <b>is</b> <b>mod</b> 2**8;
      <b>type</b> Unsigned_16 <b>is</b> <b>mod</b> 2**16;
      <b>type</b> Unsigned_32 <b>is</b> <b>mod</b> 2**32;
      <b>type</b> Unsigned_64 <b>is</b> <b>mod</b> 2**64;
   <b>end</b> Interfaces;
</pre>


<p>This is legal SPARK, and goes in a file called
interfaces.shs.  We then use the Examiner&#8217;s index-file
mechanism to make sure that the Examiner sees
this version of the package specification.</p>



<p>To get at the shift and rotate functions, we need
to introduce a new package that &#8220;de-overloads&#8221;
the names.  Let&#8217;s call this package &#8220;SR&#8221; &#8212; this is
also a &#8220;shadow&#8221;, so it goes in sr.shs or a similar file.
It looks like this:</p>

<pre>
   <b>with</b> Interfaces;
   <EM>&#45;&#45;# inherit Interfaces;</EM>
   <b>package</b> SR <b>is</b>

      <b>function</b> Rotate_Left_16
        (Value  : Interfaces.Unsigned_16;
         Amount : Natural) <b>return</b> Interfaces.Unsigned_16;

      <b>function</b> Rotate_Left_32
        (Value  : Interfaces.Unsigned_32;
         Amount : Natural) <b>return</b> Interfaces.Unsigned_32;

      <EM>&#45;&#45; ...and so on for all required functions...</EM>
   <b>end</b> SR;
</pre>


<p>Note how we removed the overloading of the function names.</p>



<p>OK&#8230; so how do we glue package SR to the
predefined intrinsic functions in package Interfaces?</p>



<p>It&#8217;s tempting to just implement the body of SR (in Ada, not SPARK)
to &#8220;call through&#8221; to the appropriate function in Interfaces,
but this might involve the overhead of a full-blown
function call/return sequence, losing all that juicy performance
that the intrinsic functions give us.  We could try using
pragma Inline to get rid of that overhead, but, as car
salesmen say, &#8220;your mileage may vary&#8221; with that idea.</p>



<p>Fortunately, there is a way out that preserves the
efficiency of the intrinsic version.  Remember that the
specification of SR above is a shadow?  We supply
the following slightly different version to the
compiler in sr.ads:</p>

<pre>
   <b>with</b> Interfaces;
   <b>package</b> SR <b>is</b>

      <b>function</b> Rotate_Left_16
        (Value  : Interfaces.Unsigned_16;
         Amount : Natural) <b>return</b> Interfaces.Unsigned_16 <b>renames</b> Interfaces.Rotate_Left;

      <b>function</b> Rotate_Left_32
        (Value  : Interfaces.Unsigned_32;
         Amount : Natural) <b>return</b> Interfaces.Unsigned_32 <b>renames</b> Interfaces.Rotate_Left;

      <EM>&#45;&#45; ...and so on</EM>
   <b>end</b> SR;
</pre>


<p>The renaming here ensures that our SPARK-friendly &#8220;un-overloaded&#8221; functions
are synonymous with the intrinsic &#8220;built in&#8221; functions, getting us
the best of both worlds &#8212; the type safety of SPARK, with the efficiency
of intrinsic machine code!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2010/02/25/gem-80/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gem #79: Where did my memory go? (Part 3)</title>
		<link>http://www.adacore.com/2010/02/08/gem-79/</link>
		<comments>http://www.adacore.com/2010/02/08/gem-79/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 11:00:57 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3462</guid>
		<description><![CDATA[Ada Gem #79 &#8212; A number of tools and libraries exist to monitor memory usage,
detect memory leaks and more generally solve issues with memory management.
The Gems in this three-part series offer an overview of these issues and explain how you can benefit from these tools in your own development.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p><strong>Part III: External Tools</strong></p>



<p>The previous two Gems on memory monitoring explained the use of
GNAT.Debug_Pools and GNATCOLL.Memory to monitor memory access and
detect memory leaks.</p>



<p>Some very powerful external tools exist on some systems that
can be used to achieve similar goals. Very often, these tools will
simply replace the system calls malloc and free, although in some
cases they will in fact emulate a virtual machine in which your
application is run.</p>



<p>One common kind of tool, available on most systems, indicates how much
memory your application is using (such as the Process Manager on Windows
or &#8220;top&#8221; on Unix systems). This is however a very limited tool, since memory
that is properly freed by your application might in fact not be given
back to the system (for performance reasons, malloc keeps it and
reuses it for the next allocation). So it is very hard to discover
memory leaks that way, and of course even if you can see that there is a
leak, you have no way of knowing where it is in your code.</p>



<p>One very useful Linux application is valgrind. This is a virtual
machine, that you start with various tools. One of them is a memory
checker, which can detect invalid memory accesses, double deallocation,
use of uninitialized variables, and memory leaks. You do not need to do
anything special when compiling your application and you can simply
run it as follows:</p>


<pre>
valgrind <EM>&#45;&#45;tool=memcheck your_app app_arguments</EM>
</pre>



<p>If you also want to detect memory leaks, start your application with:</p>


<pre>
valgrind <EM>&#45;&#45;tool=memcheck --leak-check=full --leak-resolution=med your_app</EM>
</pre>



<p>Compared to the techniques we discussed in the previous Gems, valgrind
is much slower (since all code runs in a virtual machine), but more
accurate. For instance, when it reports memory leaks, it will only
report those chunks of memory that are no longer referenced anywhere
in your application. For instance, if you have a global constant
initialized once by calling &#8220;new &#8230;&#8221;, the Ada packages would
report it as a leak, whereas valgrind by default knows it is still
referenced and will not bother you with it (although, of course,
you have an option to see it, namely &#8211;show-reachable). Since it is
often very hard to free such memory (you have to do it at finalization
time), and generally not worth it since the memory will be reclaimed
by the system anyway, you generally want to ignore those chunks.</p>



<p>Likewise, if you have an allocated object that itself contains
accesses to dynamically allocated memory, valgrind will by default
only report the root object as a leak, since the other chunks are
accessible from the first. When you fix the leak for the first,
it is likely that you will at the same time fix the other leaks as
well.</p>



<p>Other sources of memory leaks, much harder to detect, are those that
occur in the graphical part of your application. On most systems,
graphical rendering is a client-server process, and the memory is
allocated on the server, not on the client. Therefore, tools like
valgrind or the GNAT packages would not be able to report it as a leak
(for instance if you have allocated a big pixmap but never freed it). On
Windows these are called &#8220;GID&#8221;, and are visible in the Process
Manager, so that you can actually monitor whether your application
seems to have such leaks. Once again, though, this provides no detail as to
the origin of the leak.</p>



<p>On Unix, you can use the &#8220;xrestop&#8221; application, which can tell you the
number of windows, cursors, graphic context, etc. that you have
allocated.</p>
 


<p>Many such tools like this exist, both commercial and free. Let us know if
you routinely use such tools, as they could be useful to other readers of
this Gem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2010/02/08/gem-79/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gem #78: Where did my memory go? (Part 2)</title>
		<link>http://www.adacore.com/2010/01/25/gem-78/</link>
		<comments>http://www.adacore.com/2010/01/25/gem-78/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 11:00:58 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3368</guid>
		<description><![CDATA[Ada Gem #78 &#8212; A number of tools and libraries exist to monitor memory usage,
detect memory leaks and more generally solve issues with memory management.
The Gems in this three-part series offer an overview of these issues and explain how you can benefit from these tools in your own development.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>Unless your coding standard forbids any dynamic allocation, memory
management is a constant concern during  system development. You might want to limit the amount of memory that your application requires, or you
might have memory leaks (allocation chunks that are never returned
to the system). The latter is a critical concern for long-running
applications.</p>



<p><strong>Part II: System.Memory</strong></p>


<p>In the previous Gem we discussed the use of GNAT.Debug_Pools to detect
memory problems. Another approach that is somewhat easier to use, because
it doesn&#8217;t require changes to the application, is to override
the System.Memory package. In GNAT and its run-time, all actual memory 
allocations are done via this package, which among other things
does the low-level system
calls to malloc() and free().</p>

<p>If you create your own
version of System.Memory, you will in fact short-circuit all memory
allocation and deallocation, and replace it with your own.
To do so, copy the file s-memory.adb to
one of your source directories, modify it as appropriate, and compile
your application, passing the &#8220;-a&#8221; switch to gnatmake (gprbuild
currently does not have an equivalent switch, although using project
files should work as expected). This ensures that GNAT will recompile
the library with your modified System.</p>



<p>Using this package does not provide the same safety as the debug
pools, since it does not check that dereferences are valid, and so
your code could still be accessing invalid memory. On the other hand,
the use of System.Memory is much less intrusive in your code. System.Memory
is best viewed as a performance analysis tool
rather than a debugging tool, although it will allow you to monitor
your code for memory leaks.</p>



<p>The GNATCOLL library (a recent addition to the GNAT technology, and
part of the latest customer and public releases) provides such an
implementation in the form of the GNATCOLL.Memory package. This
package is not a direct replacement for System.Memory, but only a
minimal amount of work is needed to make use of it, by creating
a version of s-memory.adb file that contains the following:</p>


<pre>
<b>with</b> GNATCOLL.Memory;
<b>package</b> <b>body</b> System.Memory <b>is</b>

   <b>package</b> M <b>renames</b> GNATCOLL.Memory;

   <b>function</b> Alloc (Size : size_t) <b>return</b> System.Address <b>is</b>
   <b>begin</b>
      <b>return</b> M.Alloc (M.size_t (Size));
   <b>end</b> Alloc;

   <b>procedure</b> Free (Ptr : System.Address) <b>renames</b> M.Free;

   <b>function</b> Realloc
      (Ptr  : System.Address;
       Size : size_t)
      <b>return</b> System.Address
   <b>is</b>
   <b>begin</b>
      <b>return</b> M.Realloc (Ptr, M.size_t (Size));
   <b>end</b> Realloc;

<b>end</b> System.Memory;
</pre>



<p>You then need to modify your code so that it properly initializes
GNATCOLL.Memory, which is done via a call like the following:</p>


<pre>
   GNATCOLL.Memory.Configure (Activate_Monitor =&gt; True);
</pre>



<p>The monitoring provided by this GNATCOLL package is not enabled by
default, to limit overhead on a running program. In your application,
monitoring could be activated through a command-line switch, or by
means of a specific environment variable. (This is all fully under your
control, though, so you&#8217;ll have to do the actual call to Getenv and
then to Configure.)</p>



<p>You can then instrument your code in one or more places to dump the
memory usage at that point. This is done through a call such as the following:</p>


<pre>
   GNATCOLL.Memory.Dump (Size =&gt; 3, Report =&gt; Memory_Usage);
</pre>



<p>Such a call will print on the console three backtraces for the code
that allocated the most memory (among the currently allocated memory).
Variants exist to dump the backtraces that executed the greatest
number of allocations (as opposed to the largest allocation size),
or the total amount of memory, even if that memory has since been released.</p>



<p>Such a dump includes a backtrace with addresses, which you can convert 
to a symbolic backtrace by using the external tool addr2line as follows:</p>

<pre>
    addr2line -e <executable> <backtrace>
</pre>


<p>This library has very light overhead (in particular when
not activated) so that you can distribute your application with
support for GNATCOLL.Memory built in, and then investigate any
issues that arise in production code. In fact, our own GPS IDE now includes
this support. Activation is controlled by an external variable,
and dumping the state of memory can be done through a Python command
at any point in time without the need to recompile GPS. (Note that GNATCOLL
also provides an interface to Python.)</p>



<p>Another feature of GNATCOLL.Memory is the capability of resetting all
counters to zero. For example, let&#8217;s assume we want to investigate
memory leaks while opening and closing editors in GPS. If we look at
the places that allocate memory, the biggest allocations that are displayed in
the console do not concern the editor itself, but rather memory
allocated when GPS started (if you are curious, this is generally
memory that is related to the cross-reference database). Therefore, we would
do the following: start GPS, reset GNATCOLL.Memory counters to 0, open
and close an editor, and dump memory usage. At that point, if Dump
prints any information on the console, we know that this is memory that has
been allocated since the call to Reset, and that wasn&#8217;t freed when the
editor was closed, and therefore is most likely a memory leak.</p>



<p>The appropriate use of Reset and Dump therefore allows the monitoring of
memory usage in specific parts of the code.</p>



<p>A separate tool called gnatmem is also distributed with GNAT. When you link your
application with the -lgmem switch, it will transparently instrument
all calls to the standard malloc and free (from the Ada code),
in a fashion similar
to GNATCOLL.Memory. On program exit, a disk file is created that
you can then analyze using gnatmem, to highlight the sources of
memory leaks in your application. This tool requires no change to your
code at all, but, on the other hand, does not provide a way to monitor
specific sections of your code like GNATCOLL.Memory does.</p>



<p>Gnatmem provides a number of command-line switches to control the
display of information. For instance, the switch &#8220;-m 0&#8243; lets you view
all places in your code that ever allocated memory, even if that
memory was properly deallocated afterwards. When one such place is
doing millions of allocations, it might sometimes be more efficient
to use a custom Storage_Pool and avoid the system call to malloc, by
reusing memory. The &#8220;-s&#8221; switch allows you to sort the output in
various ways.</p>



<p>In Part III of this series we will take a look at various commercially available
system tools for monitoring and analyzing memory usage.</p>]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2010/01/25/gem-78/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gem #77: Where did my memory go? (Part 1)</title>
		<link>http://www.adacore.com/2010/01/11/gem-77/</link>
		<comments>http://www.adacore.com/2010/01/11/gem-77/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 11:00:51 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3305</guid>
		<description><![CDATA[Ada Gem #77 &#8212; A number of tools and libraries exist to monitor memory usage,
detect memory leaks, and more generally solve issues with memory management.
This Gem, and others to follow, offer an overview of these issues and explain how you can benefit from these tools in your own development.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>Unless your coding standard forbids any dynamic allocation, memory
management is a constant concern during  system development. You might want to limit the amount of memory that your application requires, or you
might have memory leaks (allocation chunks that are never returned
to the system). The latter is a critical concern for long-running
applications.
</p>


<p><strong>Part I: Storage Pools</strong></p>


<p>The standard Ada memory management mechanism is the storage pool, as defined in package System.Storage_Pools. A storage pool is a tagged type that allows you to override the standard &#8220;new&#8221; operator and the associated Unchecked_Deallocation procedure. A given pool can be associated with one or more access types. The GNAT run-time comes
with a number of predefined storage pools, and you can also create
your own. One basic implementation, for instance, would be to instrument the
pool operations to print a trace to the console every time memory is allocated or freed, and then post-process those traces with an external tool afterward.</p>



<p>This is of course a little tedious, so GNAT provides the package GNAT.Debug_Pools
as a much more advanced storage pool implementation that can, at any time during
program execution, display the currently allocated memory (along with a backtrace of the code at the point of allocation). It will also detect invalid memory references (for instance, attempting to dereference a pointer to already deallocated memory). The implementation is efficient andl imposes only a very small overhead on your application.</p>


<p>Here is a short example demonstrating the use of debug pools:</p>


<pre>
<b>with</b> GNAT.Debug_Pools;

<b>package</b> My_Package <b>is</b>
   Pool : GNAT.Debug_Pools.Debug_Pool;

   <b>type</b> Integer_Access <b>is</b> <b>access</b> Integer;
   <b>for</b> Integer_Access'Storage_Pool <b>use</b> Pool;
<b>end</b> My_Package;

<b>with</b> My_Package;
<b>with</b> Ada.Unchecked_Deallocation;
<b>procedure</b> Main <b>is</b>
   <b>procedure</b> Unchecked_Free <b>is</b>
      <b>new</b> Ada.Unchecked_Deallocation (Integer, Integer_Access);
   Ptr : Integer_Access;
<b>begin</b>
   Ptr := <b>new</b> Integer;
   Ptr.<b>all</b> := 1;
   Unchecked_Free (Ptr);
   Ptr.<b>all</b> := 2;  <EM>&#45;&#45;  raises exception</EM>
<b>end</b> Main;
</pre>



<p>The variable My_Package.Pool should be shared as much as possible among all your
access types. It&#8217;s not necessary to create one per access type.</p>



<p>As noted in the main procedure, the last reference to Ptr is
invalid, and will result in an exception raised from the debug pool (rather
than some erroneous behavior depending on the system).</p>



<p>GNAT.Debug_Pools provides various subprograms to analyze current
memory usage, in particular the total amount of memory currently
allocated, as well as which part of the code did the allocations. The
backtraces are also useful when analyzing double-deallocation
scenarios, since a debug pool shows both where the memory was
allocated and by what piece of code it was first deallocated.</p>



<p>However, GNAT&#8217;s debug pools are rather heavy to put in place in existing
code, since you need to add a &#8220;for Type_Name&#8217;Storage_Pool use Pool&#8221;
to every access type, and there is no mechanism to define a single
default storage pool for all types. GNAT.Debug_Pools can also give false warnings when dereferencing a pointer to aliased data on the stack (which was never allocated via a &#8220;new&#8221; operator, but was accessed via an &#8216;Access attribute).</p>

<p>In the next Gem we will discuss an alternative approach to controlling and instrumenting dynamic allocation and deallocation, by overriding the low-level memory management support itself.</p>]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2010/01/11/gem-77/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Gem #76: Tokeneer Discovery &#8211; Lesson 6</title>
		<link>http://www.adacore.com/2009/12/14/gem-76/</link>
		<comments>http://www.adacore.com/2009/12/14/gem-76/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 10:00:29 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3228</guid>
		<description><![CDATA[Ada Gem #76 &#8212; In the previous Gem in this series, we saw how to deal with overflow
errors, based on source code from Tokeneer. In this Gem, we show how
to ensure secure information flow.<br/>
This Gem brings us to the end of this series on Tokeneer, and we would like to say a big thank you to the SPARK team at Praxis HIS for providing these resources. <br/>
We will now take a break for the holiday period and will return with more Gems on January 11, 2010. Very happy holidays to all Gem readers, wherever you are! <br/>]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>Error message information leak occurs when secure data is leaked,
through error messages, to unauthorised users, and is one of the top
twenty-five most dangerous programming errors according to SANS
Institute. The general problem is ensuring that information flow
adheres to certain policies &#8212; for example, certain data should never
be written in an error message to a log file that may be accessible by
unauthorised users.</p>



<p>The objective of this Gem is to demonstrate that the Examiner
detects information flow violations.</p>



<p><strong>Step-by-Step Instructions</strong></p>



<p>Step 1: Study a Contract from an Information Flow Perspective</p>



<p>The code below is from the procedure Verify in bio.adb. The out
variable MatchResult returns the result of whether a person&#8217;s
fingerprint matched their template. The local variable NumericReturn
is set to the enumerated value BioApiOk if the fingerprint
successfully matched; otherwise it returns an error code.</p>



<p>When a match is unsuccessful, a log record is written including the
variable NumericReturn, which is derived from the person&#8217;s Template.</p>

<pre>
      221  <b>procedure</b> Verify(Template       : <b>in</b>     IandATypes.TemplateT;
      222                   MaxFAR         : <b>in</b>     IandATypes.FarT;
      223                   MatchResult    :    <b>out</b> IandATypes.MatchResultT;
      224                   AchievedFAR    :    <b>out</b> IandATypes.FarT)
             ...
      230  <EM>&#45;&#45;# derives AuditLog.State,</EM>
      231  <EM>&#45;&#45;#         AuditLog.FileState from AuditLog.State,</EM>
      232  <EM>&#45;&#45;#                                 AuditLog.FileState,</EM>
      233  <EM>&#45;&#45;#                                 Template,</EM>
      234  <EM>&#45;&#45;#                                 Clock.Now,</EM>
      235  <EM>&#45;&#45;#                                 ConfigData.State,</EM>
      236  <EM>&#45;&#45;#                                 Interface.Input &amp;</EM>
             ...
      242  <b>is</b>
      243     NumericReturn : BasicTypes.Unsigned32T;
      244  <b>begin</b>
      245     <b>Interface</b>.Verify(Template     =&gt; Template,
      246                      MaxFAR       =&gt; MaxFAR,
      247                      MatchResult  =&gt; MatchResult,
      248                      AchievedFAR  =&gt; AchievedFAR,
      249                      BioReturn    =&gt; NumericReturn);
      250
      251     <b>if</b> NumericReturn /= ValueOf(BioAPIOk) <b>then</b>
      252        <EM>&#45;&#45; An error occurred, overwrite match information.</EM>

      253        MatchResult := IandATypes.NoMatch;
      254        AuditLog.AddElementToLog
      255          (ElementID    =&gt; AuditTypes.SystemFault,
      256           Severity     =&gt; AuditTypes.Warning,
      257           User         =&gt; AuditTypes.NoUser,
      258           Description  =&gt; MakeDescription (&quot;Biometric device failure &quot;,
      259                                            NumericReturn));
      260        <b>end</b> <b>if</b>;
      261  <b>end</b> Verify;
</pre>



<p>If the log were accessible to potential hackers, which is not the case
for Tokeneer, then this would be an example of an error message information
leak. Fingerprint templates should never be accessible by hackers.</p>



<p>Step 2: Change an Information Flow Aspect of the Contract</p>



<p>Change the contract for the procedure Verify to specify that no
information written to the log is derived from Template by deleting
line 233.</p>

<pre>
       230   <EM>&#45;&#45;# derives AuditLog.State,</EM>
       231   <EM>&#45;&#45;#         AuditLog.FileState from AuditLog.State,</EM>
       232   <EM>&#45;&#45;#                                 AuditLog.FileState,</EM>
       233   <EM>&#45;&#45;#                                                     </EM>
       234   <EM>&#45;&#45;#                                 Clock.Now,</EM>
       235   <EM>&#45;&#45;#                                 ConfigData.State,</EM>
       236   <EM>&#45;&#45;#                                 Interface.Input &amp;</EM>
</pre>



<p>The corresponding line (line 73) of code needs to be removed from the
file bio.ads.</p>

<pre>
       60   <b>procedure</b> Verify(Template       : <b>in</b>     IandATypes.TemplateT;
       61                    MaxFAR         : <b>in</b>     IandATypes.FarT;
       62                    MatchResult    :    <b>out</b> IandATypes.MatchResultT;
       63                    AchievedFAR    :    <b>out</b> IandATypes.FarT);
            ...
       69   <EM>&#45;&#45;# derives AuditLog.State,</EM>
       70   <EM>&#45;&#45;#         AuditLog.FileState from Input,</EM>
       71   <EM>&#45;&#45;#                                 AuditLog.State,</EM>
       72   <EM>&#45;&#45;#                                 AuditLog.FileState,</EM>
       73   <EM>&#45;&#45;#                                                     </EM>
       74   <EM>&#45;&#45;#                                 Clock.Now,</EM>
       75   <EM>&#45;&#45;#                                 ConfigData.State &amp;</EM>
</pre>



<p>Step 3: Use the SPARK Tools to Detect the Information Leak</p>



<p>Examine the file bio.adb and notice the Examiner reports the error
that information derived from the variable Template is written to the
log. This means that data derived from the template is being written
to the log! </p>
 
<pre>
bio.adb:261:8:
    Flow Error 601 - AuditLog.State may be derived from the imported value(s) of Template.
bio.adb:261:8:
    Flow Error 601 - AuditLog.FileState may be derived from the imported value(s) of Template.
</pre>



<p>Step 4: Introduce a Malicious Hack</p>



<p>The Examiner also detects when data has been incorrectly used. We now
add back door code in the procedure Verify (lines 248-251 below). It
returns a positive match independent of the user&#8217;s fingerprint when
the clock is at midnight.</p>

<pre>
      223  <b>procedure</b> Verify(Template       : <b>in</b>     IandATypes.TemplateT;
      224                   MaxFAR         : <b>in</b>     IandATypes.FarT;
      225                   MatchResult    :    <b>out</b> IandATypes.MatchResultT;
      226                   AchievedFAR    :    <b>out</b> IandATypes.FarT)
            ...
      232  <EM>&#45;&#45;# derives AuditLog.State,</EM>
      233  <EM>&#45;&#45;#         AuditLog.FileState from AuditLog.State,</EM>
      234  <EM>&#45;&#45;#                                 AuditLog.FileState,</EM>
      235  <EM>&#45;&#45;#                                 Template,</EM>
      236  <EM>&#45;&#45;#                                 Clock.Now,</EM>
      237  <EM>&#45;&#45;#                                 ConfigData.State,</EM>
      238  <EM>&#45;&#45;#                                 Interface.Input &amp;</EM>
               ...
      244  <b>is</b>
      245     NumericReturn : BasicTypes.Unsigned32T;
      246     T             : Clock.TimeT;
      247  <b>begin</b>
      248     T := Clock.GetNow;
      249     <b>if</b> T = Clock.ZeroTime <b>then</b>
      250        MatchResult := IandATypes.Match;
      251        AchievedFAR := 0;
      252     <b>else</b>
      253
      254        <b>Interface</b>.Verify(Template     =&gt; Template,
      255                         MaxFAR       =&gt; MaxFAR,
      256                         MatchResult  =&gt; MatchResult,
      257                         AchievedFAR  =&gt; AchievedFAR,
      258                         BioReturn    =&gt; NumericReturn);
      259
              ...
      272    <b>end</b> <b>if</b>; 
             ...
      275  <b>end</b> Verify;
</pre>



<p>Step 5: Use the SPARK Tools to Detect the Weakness</p>



<p>Examine the file bio_bad.adb and notice that the Examiner reports the
error that MatchResult is dependent on the current time (Clock.now),
which is inconsistent with the procedure&#8217;s contract. The Examiner has
identified an information flow inconsistency due to the presence of
the back door. </p>
 
<pre>
bio_bad.adb:243:40:
    Flow Error   4 - The dependency of the exported value of AuditLog.State on the imported value
    of  Verify.Template has not been previously stated.
bio_bad.adb:243:40:
    Flow Error   4 - The dependency of the exported value of AuditLog.FileState on the imported value
    of Verify.Template has not been previously stated.
bio_bad.adb:275:8:
    Flow Error 601 - MatchResult may be derived from the imported value(s) of Clock.Now.
bio_bad.adb:275:8:
    Flow Error 601 - AchievedFAR may be derived from the imported value(s) of Clock.Now.
</pre>


<p>Summary</p>



<p>In this Gem we have learnt about information flow contracts and we
have seen the SPARK tools detect a malicious hack. SPARK programs are
free from information leaks when the contract accurately specifies the
desired information flow between variables.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/12/14/gem-76/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gem #75: Tokeneer Discovery &#8211; Lesson 5</title>
		<link>http://www.adacore.com/2009/11/30/gem-75/</link>
		<comments>http://www.adacore.com/2009/11/30/gem-75/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 11:00:06 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3226</guid>
		<description><![CDATA[Ada Gem #75 &#8212; In the previous Gem in this series, we saw how the SPARK Toolset can
verify application-specific safety and security properties, based on
source code from Tokeneer. In this Gem, we show how to deal with
overflow errors.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>An overflow error occurs when the capacity of a device is
exceeded. Overflow errors are a source of quality and security
concerns. For instance, when an arithmetic overflow occurs, a
calculated value does not fit in its specified size, and the
calculation (and the program) just stops. Buffer overflow happens when
a process stores data in a buffer outside of the memory that the
programmer set aside for it. Buffer overflow errors are widely known
to present a vulnerability to malicious hackers, who might exploit the
error to sneak their own code onto a victim&#8217;s disk, storing it
outside of the intended buffer.</p>



<p>The SPARK tools detect all potential arithmetic and buffer overflow
errors. In the Gem about input validation, we saw an example of an
arithmetic overflow. In this Gem, we will study how the SPARK tools
find a buffer overflow error that we have injected into the Tokeneer
code.  </p>



<p><strong>Step-by-Step Instructions</strong></p>


<p>We will introduce a buffer overflow error into auditlog.adb and show
how the SPARK Toolset detects it.</p>



<p>Step 1: Inject a Buffer Overflow Error</p>



<p>The procedure AddElementToCurrentFile increments the element indexed
by CurrentLogFile in the array LogFileEntries &#8211; see below.</p>

<pre>
      775  <EM>&#45;&#45;# post LogFileEntries(CurrentLogFile) =</EM>
      776  <EM>&#45;&#45;#             LogFileEntries~(CurrentLogFile) + 1;</EM>
              ...
      790     LogFileEntries(CurrentLogFile) := LogFileEntries(CurrentLogFile) + 1;
</pre>



<p>Change the code on line 790 and the postcondition on 775 to 776 so the
procedure copies the value in the CurrentLogFile+1th element into the
CurrentLogFileth element of the array. The modified code is shown
below.</p>

<pre>
      774  <EM>&#45;&#45;# pre LogFileEntries(CurrentLogFile) &lt; MaxLogFileEntries;</EM>
      775  <EM>&#45;&#45;# post LogFileEntries(CurrentLogFile) =</EM>
      776  <EM>&#45;&#45;#             LogFileEntries~(CurrentLogFile+1);</EM>
           ...
      790  LogFileEntries(CurrentLogFile) := LogFileEntries(CurrentLogFile+1) ;
</pre>



<p>Step 2: Analyse and Study the Verification Output</p>



<p>Analyse Tokeneer. The SPARK Toolset identifies, on lines 587 to 597
(see below), that there is a potential problem with the procedure
AddElementToCurrentFile.</p>

<pre>
 659    VCs <b>for</b> procedure_addelementtocurrentfile :
 660    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
 661          |       |                     |  <EM>&#45;&#45;---Proved In-----  |       |       |</EM>
 662    #    | From  | To                  | vcg | siv | plg | prv | False | TO <b>DO</b> |
 663    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
 664     1    | start | rtc check @ 781     |     | YES |     |     |       |       | 
 665     2    | start | rtc check @ 782     |     | YES |     |     |       |       | 
 666     3    | start | rtc check @ 788     |     | YES |     |     |       |       | 
 667     4    | start | rtc check @ 790     |     |     |     |     |       |  YES  |
 668     5    | start |    assert @ finish  |     | YES |     |     |       |       | 
 669    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
</pre>



<p>The Simplifier failed to show that CurrentLogFile+1 is always within
range of the index type, because it is not true &#8211; it goes outside its
range when CurrentLogFile = LogFileIndexType&#8217;Last, which then causes a
buffer overflow.  </p>



<p>Summary</p>



<p>Buffer overflow errors are common and present a security
vulnerability. The SPARK Toolset can verify that a SPARK program is
free from arithmetic as well as buffer overflow errors. In this Gem we
have seen how the SPARK tools can be used to detect a buffer overflow
error. In the next Gem, we will see how SPARK can be used in Ensuring
Secure Information Flow.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/11/30/gem-75/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Gem #74: Tokeneer Discovery &#8211; Lesson 4</title>
		<link>http://www.adacore.com/2009/11/16/gem-74/</link>
		<comments>http://www.adacore.com/2009/11/16/gem-74/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 10:00:00 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3208</guid>
		<description><![CDATA[Ada Gem #74 &#8212; In the previous Gem in this series, we saw how to validate input in
SPARK, based on source code from Tokeneer. In this Gem, we show how
the SPARK Toolset can verify application-specific safety and security
properties.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>In this Gem, we will see how the SPARK tools detect any differences
between a program&#8217;s intended behaviour, as specified in its contract,
and its actual behaviour, as implemented in the code. Thus the SPARK
tools can be used either to find defects in the contract, to find
defects in the implementation, to find defects in both, or to show
conformance between intended and actual behaviour.  </p>



<p><strong>Step-by-Step Instructions </strong></p>



<p>Step 1: Analyse the Correct Version of the Code</p>



<p>The precondition for procedure AddElementToCurrentFile in
auditlog.adb (lines 772 &#8211; 774 in the code below) specifies that the
array element LogFileEntries (CurrentLogFile)
is less than MaxLogFileEntries and the postcondition
specifies that the array element is incremented by 1.</p>

<pre>
      751        <b>procedure</b> AddElementToCurrentFile
      752          (ElementID    : <b>in</b>     AuditTypes.ElementT;
      753           Severity     : <b>in</b>     AuditTypes.SeverityT;
      754           User         : <b>in</b>     AuditTypes.UserTextT;
      755           Description  : <b>in</b>     AuditTypes.DescriptionT)
      756          <EM>&#45;&#45;# global in     Clock.Now;</EM>
      757          <EM>&#45;&#45;#        in     CurrentLogFile;</EM>
      758          <EM>&#45;&#45;#        in out AuditSystemFault;</EM>
      759          <EM>&#45;&#45;#        in out LogFiles;</EM>
      760          <EM>&#45;&#45;#        in out LogFileEntries;</EM>
      761          <EM>&#45;&#45;# derives AuditSystemFault,</EM>
      762          <EM>&#45;&#45;#         LogFiles         from *,</EM>
      763          <EM>&#45;&#45;#                               Description,</EM>
      764          <EM>&#45;&#45;#                               LogFiles,</EM>
      765          <EM>&#45;&#45;#                               Clock.Now,</EM>
      766          <EM>&#45;&#45;#                               ElementID,</EM>
      767          <EM>&#45;&#45;#                               Severity,</EM>
      768          <EM>&#45;&#45;#                               User,</EM>
      769          <EM>&#45;&#45;#                               CurrentLogFile &amp;</EM>
      770          <EM>&#45;&#45;#         LogFileEntries   from *,</EM>
      771          <EM>&#45;&#45;#                               CurrentLogFile;</EM>
      772          <EM>&#45;&#45;# pre LogFileEntries(CurrentLogFile) &lt; MaxLogFileEntries;</EM>
      773          <EM>&#45;&#45;# post LogFileEntries(CurrentLogFile) =</EM>
      774          <EM>&#45;&#45;#             LogFileEntries~(CurrentLogFile) + 1;</EM>
      775  
      776        <b>is</b>
      777           TheFile : File.T ;
      778        <b>begin</b>
      779           TheFile := LogFiles (CurrentLogFile);
      780           AddElementToFile
      781             (TheFile =&gt; TheFile,
      782              ElementID    =&gt; ElementID,
      783              Severity     =&gt; Severity,
      784              User         =&gt; User,
      785              Description  =&gt; Description);
      786           LogFiles (CurrentLogFile) := TheFile;
      787  
      788           LogFileEntries(CurrentLogFile) := LogFileEntries(CurrentLogFile) + 1;
      789        <b>end</b> AddElementToCurrentFile;
</pre>



<p>Analyse Tokeneer with the SPARK Toolset. The result of the analysis
shows (see below) that the SPARK Toolset has identified no problems
with the code in the procedure AddElementToLogFile &#8211; the columns False
and TO DO are empty.</p>

<pre>
 659    VCs for procedure_addelementtocurrentfile :
 660    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
 661          |       |                     |  <EM>&#45;&#45;---Proved In-----  |       |       |</EM>
 662     #    | From  | To                  | vcg | siv | plg | prv | False | TO DO |
 663    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
 664     1    | start | rtc check @ 781     |     | YES |     |     |       |       | 
 665     2    | start | rtc check @ 782     |     | YES |     |     |       |       | 
 666     3    | start | rtc check @ 788     |     | YES |     |     |       |       | 
 667     4    | start | rtc check @ 790     |     | YES |     |     |       |       | 
 668     5    | start |    assert @ finish  |     | YES |     |     |       |       | 
 669    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
</pre>



<p>Step 2: Change the Contract &#8211; But not the Implementation</p>



<p>Let us change the postcondition so the procedure&#8217;s contract no longer
matches its implementation. The SPARK Toolset will then detect the
inconsistency. Change the postcondition to specify that the array
element LogFileEntries(CurrentLogFile) should be incremented by 10.
The modified code is shown below.</p>

<pre>
      772          <EM>&#45;&#45;# pre LogFileEntries(CurrentLogFile) &lt; MaxLogFileEntries;</EM>
      773          <EM>&#45;&#45;# post LogFileEntries(CurrentLogFile) =</EM>
      774          <EM>&#45;&#45;#             LogFileEntries~(CurrentLogFile) + 10;</EM>
      775  
</pre>



<p>Step 3: Re-Analyse and Study the Results</p>



<p>Re-analyse Tokeneer. The results of the analysis for the procedure
AddElementToLogFile has changed &#8211; the columns False and TO DO are no
longer empty (see below).</p>

<pre>
 659    VCs for procedure_addelementtocurrentfile :
 660    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
 661          |       |                     |  <EM>&#45;&#45;---Proved In-----  |       |       |</EM>
 662    #    | From  | To                  | vcg | siv | plg | prv | False | TO DO |
 663    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
 664     1    | start | rtc check @ 781     |     | YES |     |     |       |       | 
 665     2    | start | rtc check @ 782     |     | YES |     |     |       |       | 
 666     3    | start | rtc check @ 788     |     | YES |     |     |       |       | 
 667     4    | start | rtc check @ 790     |     | YES |     |     |       |       | 
 668     5    | start |    assert @ finish  |     |     |     |     |  YES  |       | 
 669    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
</pre>



<p>The SPARK Toolset has identified a potential problem with the code. The
problem is that the procedure&#8217;s contract and implementation don&#8217;t
match.</p>


<p>Step 4: Revert the Contract &#8211; But Change the Implementation</p>



<p>Undo the changes to the postcondition and change line 788 so that the
input value is preserved.</p>

<pre>
     774           <EM>&#45;&#45;# pre LogFileEntries(CurrentLogFile) &lt; MaxLogFileEntries;</EM>
     775           <EM>&#45;&#45;# post LogFileEntries(CurrentLogFile) =</EM>
     776           <EM>&#45;&#45;#             LogFileEntries~(CurrentLogFile) + 1 </EM>
                     ...
     791           LogFileEntries(CurrentLogFile) := LogFileEntries(CurrentLogFile) + 0;
     792        <b>end</b> AddElementToCurrentFile;
</pre>



<p>Re-analyse Tokeneer. The analysis of the procedure is unchanged, as the
implementation, like previously, does not match the procedure&#8217;s
contract.</p>



<p>Step 5: Strengthen the Contract</p>



<p>Revert the code to its original state.</p>



<p>In SPARK, we can strengthen the procedure&#8217;s contract and say more
about the properties of the procedure. Let&#8217;s add extra code assigning
the value 10 to the first element of the array LogFileEntries if
CurrentLogFile is not LogFileIndexType&#8217;First (lines 789 &#8211; 791 below).</p>

<pre>
      788         LogFileEntries(CurrentLogFile) := LogFileEntries(CurrentLogFile) + 1;
      789         <b>if</b> CurrentLogFile /= LogFileIndexType'First <b>then</b>
      790            LogFileEntries(LogFileIndexType'First) := 10;
      791         <b>end</b> <b>if</b>;
      792      <b>end</b> AddElementToCurrentFile;
</pre>



<p>Re-analyse Tokeneer and notice that no errors are reported, as the
procedure&#8217;s implementation is not inconsistent with its contract. The
postcondition says nothing about the effects of the procedure on any
of the array elements except the one indexed by CurrentLogEntry.</p>



<p>We can strengthen the postcondition (lines 775 and 776 below) to
specify that only the entry indexed by CurrentLogFile is incremented
and all other elements remain unchanged.</p>

<pre>
 772   <EM>&#45;&#45;# pre LogFileEntries(CurrentLogFile) &lt; MaxLogFileEntries;</EM>
 773   <EM>&#45;&#45;# post LogFileEntries = LogFileEntries~[CurrentLogFile =&gt; LogFileEntries~(CurrentLogFile)+1]; </EM>
</pre>



<p>Re-analyse Tokeneer and notice, on lines 659 to 671, that the mismatch
between the implementation and contract has been detected. </p>

<pre>
 657    VCs for procedure_addelementtocurrentfile :
 658    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
 659          |       |                     |  <EM>&#45;&#45;---Proved In-----  |       |       |</EM>
 660     #    | From  | To                  | vcg | siv | plg | prv | False | TO DO |
 661    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
 662     1    | start | rtc check @ 783     |     | YES |     |     |       |       | 
 663     2    | start | rtc check @ 784     |     | YES |     |     |       |       | 
 664     3    | start | rtc check @ 790     |     | YES |     |     |       |       | 
 665     4    | start | rtc check @ 792     |     | YES |     |     |       |       | 
 666     5    | start | rtc check @ 794     |     | YES |     |     |       |       | 
 667     6    | start |    assert @ finish  |     |     |     |     |       |  YES  |
 668     7    | start |    assert @ finish  |     | YES |     |     |       |       | 
 669    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
</pre>



<p>Summary</p>



<p>This Gem demonstrates that the more precise the specification, the
more bugs the SPARK Toolset can detect. The use of the SPARK Toolset
during development to verify code is, in our experience, more
effective than compiling and testing, since the analysis is for all
input data and not just a few specific test cases. In the next Gem we will see
how SPARK deals with overflow errors.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/11/16/gem-74/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gem #73: Tokeneer Discovery &#8211; Lesson 3</title>
		<link>http://www.adacore.com/2009/11/02/gem-73-tokeneer-discovery-lesson-3/</link>
		<comments>http://www.adacore.com/2009/11/02/gem-73-tokeneer-discovery-lesson-3/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 10:00:28 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3192</guid>
		<description><![CDATA[Ada Gem #73 &#8212; In the previous Gem in this series, we saw how to identify ineffective
statements in SPARK, based on source code from Tokeneer. In this Gem,
we show how to validate input.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>Input validation ensures that your program&#8217;s input conforms to
expectations &#8211; for example, to ensure that the input has the right
type. But validation requirements can be much more complicated than
that. Incorrect input validation can lead to security and safety
problems since many applications live in a &#8220;hostile&#8221; environment and
the input might be constructed by an attacker. &#8220;It&#8217;s the number one
killer of healthy software&#8230;&#8221; according to the CWE/SANS list of the
top twenty-five most dangerous programming errors.</p>


<p>For example, consider the following few lines of code from the
original release of the Tokeneer code:</p>

<pre>
         233      <b>if</b> Success <b>and</b> <b>then</b>
         234         (RawDuration * 10 &lt;= Integer(DurationT'Last) <b>and</b> 
         235          RawDuration * 10 &gt;= Integer(DurationT'First)) <b>then</b> 
         236         Value := DurationT(RawDuration * 10);
         237      <b>else</b>
</pre>


<p>This code has a check that the input RawDuration is in the right range
before the value is updated &#8211; an example of so called defensive
coding, according to the advice from the software experts who compiled
the list of dangerous programming errors. Can you see the problem with
this code?</p>



<p>The SPARK tools will identify a serious defect in this code, which
could impact on security.</p>



<p>In this Gem, the above code will be investigated using the SPARK
tools. This Gem shows the challenges in ensuring the absence of input
validation errors, and the benefits of using SPARK to do so.</p>



<strong><p>Step-by-Step Instructions</p></strong>


<p>First, we will familiarize ourselves with two more advanced SPARK
tools by running them on the correct version of the code. Then we
inject the defect shown above into the Tokeneer code, rerun the SPARK
tools, and interpret the results.  </p>



<p>Step 1: Analyse the Correct Version of the Code</p>



<p>The correct lines of code are the following:</p>

<pre>
         233      <b>if</b> Success <b>and</b> <b>then</b>
         234         (RawDuration &lt;= Integer(DurationT'Last) / 10 <b>and</b> 
         235          RawDuration &gt;= Integer(DurationT'First) / 10) <b>then</b> 
         236         Value := DurationT(RawDuration * 10);
         237      <b>else</b>
</pre>


<p>Analyse Tokeneer using the following steps:</p>



<p>   * Run the Examiner on the file configdata.adb.</br>
   * Run the Simplifier, a more advanced tool in the SPARK tool suite, which 
     tries to show the absence of certain run-time errors by theorem proving.</br>
   * Run POGS, which gives a summary of the verification just performed. </br>
</p>


<p>Now let us inspect the verification summary, where an overall summary
of the Tokeneer verification is given. It shows that there are no
errors which is expected as we ran the tools on the correct version of
the code. Furthermore, it shows a number of tables describing details
for the verification. For example, lines 2750 to 2766 of core.sum,
shown below, are the results from the analysis of the procedure
ReadDuration.</p>

<pre>
2750    VCs <b>for</b> procedure_readduration :
2751    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
2752          |       |                     |  <EM>&#45;&#45;---Proved In-----  |       |       |</EM>
2753     #    | From  | To                  | vcg | siv | plg | prv | False | TO <b>DO</b> |
2754    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
2755     1    | start | rtc check @ 220     |     | YES |     |     |       |       | 
2756     2    | start | rtc check @ 221     |     | YES |     |     |       |       | 
2757     3    | start | rtc check @ 221     |     | YES |     |     |       |       | 
2758     4    | start | rtc check @ 233     |     | YES |     |     |       |       | 
2759     5    | start | rtc check @ 237     |     | YES |     |     |       |       | 
2760     6    | start | rtc check @ 243     |     | YES |     |     |       |       | 
2761     7    | start | rtc check @ 243     |     | YES |     |     |       |       | 
2762     8    | start |    assert @ finish  | YES |     |     |     |       |       | 
2763     9    | start |    assert @ finish  | YES |     |     |     |       |       | 
2764     10   | start |    assert @ finish  | YES |     |     |     |       |       | 
2765     11   | start |    assert @ finish  | YES |     |     |     |       |       | 
2766    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
</pre>



<p>Note that the columns False and TO DO are empty, which means that the
SPARK tools found no errors in the verification of procedure
ReadDuration.</p>



<p>Step 2: Inject Erroneous Input Validation Code</p>


<p>Now, replace lines 234 and 235 in the file configdata.adb with the
erroneous code:</p>

<pre>
         233      <b>if</b> Success <b>and</b> <b>then</b>
         234         (RawDuration * 10 &lt;= Integer(DurationT'Last) <b>and</b>
         235          RawDuration * 10 &gt;= Integer(DurationT'First)) <b>then</b>
         236         Value := DurationT(RawDuration * 10);
         237      <b>else</b>
</pre>



<p>Essentially this code concerns the validation of an input &#8211; an integer
value RawDuration &#8211; that is read from a file, and is expected to be in
the range 0..200 seconds before it is converted into a number of
tenths of seconds in the range 0..2000.</p>



<p>Step 3: Re-Analyse the Faulty Code</p>


<p>Re-analyse Tokeneer.</p>



<p>The results from the analysis of the procedure ReadDuration is shown below.</p>
<pre>
2750    VCs <b>for</b> procedure_readduration :
2751    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
2752          |       |                     |  <EM>&#45;&#45;---Proved In-----  |       |       |</EM>
2753     #    | From  | To                  | vcg | siv | plg | prv | False | TO <b>DO</b> |
2754    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
2755     1    | start | rtc check @ 220     |     | YES |     |     |       |       | 
2756     2    | start | rtc check @ 221     |     | YES |     |     |       |       | 
2757     3    | start | rtc check @ 221     |     | YES |     |     |       |       | 
2758     4    | start | rtc check @ 233     |     |     |     |     |       |  YES  | 
2759     5    | start | rtc check @ 237     |     | YES |     |     |       |       | 
2760     6    | start | rtc check @ 243     |     | YES |     |     |       |       | 
2761     7    | start | rtc check @ 243     |     | YES |     |     |       |       | 
2762     8    | start |    assert @ finish  | YES |     |     |     |       |       | 
2763     9    | start |    assert @ finish  | YES |     |     |     |       |       | 
2764     10   | start |    assert @ finish  | YES |     |     |     |       |       | 
2765     11   | start |    assert @ finish  | YES |     |     |     |       |       | 
2766    <EM>&#45;&#45;--------------------------------------------------------------------------</EM>
</pre>



<p>Notice that this time there is one YES in the TO DO column. The SPARK
Toolset has detected a potential problem with the procedure
ReadDuration.</p>



<p>Step 4: Investigate the Verification Output
</p>


<p>Now, let us have look into what the error that the SPARK tools have
found really means.</p>



<p>The file readduration.siv contains the Simplifier&#8217;s analysis of the
procedure. Lines 38 to 55 (shown below) of the file show the potential
problem the SPARK Toolset has identified. The Simplifier, on line 54,
is trying to check no arithmetic overflow errors will occur when
evaluating the expression RawDuration * 10 &#8211; that is, when Success is
True then RawDuration * 10 >= -2147483648 (Integer&#8217;First) and
RawDuration * 10 <= 2147483648 (Integer'Last).</p>

<pre>
38      procedure_readduration_4.
39      H1:    rawduration__1 &gt;= - 2147483648 .
40      H2:    rawduration__1 &lt;= 2147483647 .
    ... 
52             -&gt;
53      C1:    success__1 -&gt; rawduration__1 * 10 &gt;= - 2147483648 <b>and</b> rawduration__1 * 
54                10 &lt;= 2147483647 .
55      
</pre>



<p>Here the SPARK theorem prover is trying to prove that RawDuration
times 10 is within the limits of Integer, assuming only that it was
within the limits before it was multiplied by 10. This should not be
possible to prove. Think about a scenario where Tokeneer was given an
input floppy disk where RawDuration was set to 1000000000. Both the
assumptions H1 and H2 would be true, but C1 &#8211; the conclusion &#8211; would
be false!
</p>


<p>This is a serious defect since a malicious user holding the &#8220;security
officer&#8221; role can deliberately attack the system by supplying a file
that contains a malformed configuration data file &#8211; one that contains
a value for RawDuration that is greater than Integer&#8217;Last/10.
</p>

<p>Summary</p>


<p>In SPARK, developers need to be explicit about the intended input and
output of program components. This has the benefit of the SPARK tools
being able to automatically find defects that are hard to prevent,
hard to detect, and with important security consequences. In this Gem
we have seen this exemplified with input validation. In the next Gem,
we will look into SPARK contracts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/11/02/gem-73-tokeneer-discovery-lesson-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gem #72: Tokeneer Discovery &#8211; Lesson 2</title>
		<link>http://www.adacore.com/2009/10/19/gem-72/</link>
		<comments>http://www.adacore.com/2009/10/19/gem-72/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 10:00:12 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
				<category><![CDATA[Ada / Ada 2005]]></category>
		<category><![CDATA[Development Log]]></category>
		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=3117</guid>
		<description><![CDATA[Ada Gem #72 &#8212; In the previous Gem in this series we saw how to deal with improper
initialization in SPARK, based on source code from Tokeneer. In this
Gem, we show how to identify ineffective statements.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>Every statement should have a purpose. An ineffective statement has no
effect on any output variable and therefore has no effect on the
behaviour of the code. The presence of ineffective statements reduces
the quality and the maintainabiliy of the code. The SPARK Toolset
identifies all ineffective statements.</p>



<p>In this Gem, we show how the SPARK Toolset finds ineffective
statements to ensure that SPARK programs are free from them.
We will inject an ineffective statement into the Tokeneer code and use
the Examiner to locate it.  </p>
</br>


<p>Step 1: Inject an ineffective statement</p>



<p>We will inject an ineffective statement into the implementation of the
function NextListIndex in auditlog.adb.</p>

<pre>
       189  <b>function</b> NextListIndex(Value : LogFileIndexT) <b>return</b>  LogFileIndexT
       190  <b>is</b>
       191     Result : LogFileIndexT;
       192  <b>begin</b>
       193     <b>if</b> Value = LogFileIndexT'Last <b>then</b>
       194        Result := LogFileIndexT'First;
       195     <b>else</b>
       196        Result := Value + 1;
       197     <b>end</b> <b>if</b>;
       198     <b>return</b> Result;
       199  <b>end</b> NextListIndex;
</pre>



<p>Let&#8217;s modify the above code by adding the new variable Result_Tmp of type
LogFileTypeT (line 191) and change line 196 so that Value + 1 is
assigned to the variable Result_Tmp instead of Result (see code
below).</p>


<pre>
       189  <b>function</b> NextListIndex(Value : LogFileIndexT) <b>return</b>  LogFileIndexT
       190  <b>is</b>
       191     Result, Result_Tmp: LogFileIndexT;
       192  <b>begin</b>
       193     <b>if</b> Value = LogFileIndexT'Last <b>then</b>
       194        Result := LogFileIndexT'First;
       195     <b>else</b>
       196        Result_Tmp := Value + 1;
       197     <b>end</b> <b>if</b>;
       198     <b>return</b> Result;
       199  <b>end</b> NextListIndex;
</pre>



<p>The statement on line 196 is ineffective because Result_Tmp is never
used. Furthermore, the value for Result may be undefined when Value /=
LogFileIndexT&#8217;Last. </p>
</br>

<p>Step 2: See how the Examiner finds the problem</p>



<p>Run the Examiner for auditlog.adb and, as expected, it finds the
ineffective statement as well as the possible undefined value for
Result.  </p>

<pre>
auditlog.adb:196:10:
  Flow Error  10 - Ineffective statement.
auditlog.adb:198:14:
  Flow Error 501 - Expression contains reference(s) to variable Result, which may have an undefined value.
auditlog.adb:199:8:
  Flow Error  33 - The variable Result_Tmp is neither referenced nor exported.
auditlog.adb:199:8:
  Flow Error 602 - The undefined initial value of Result may be used in the derivation of the function value.
</pre>



<p>Summary</p>



<p>In this Gem we have seen an example of the SPARK tools finding an
ineffective statement. The SPARK tools will find all ineffective
statements. In the next Gem we will study Input Validation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/10/19/gem-72/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
