safe_iop - a safe integer operation library for C
Chris Hutchinson <portmaster_AT_BSDforge.com>
Will Drewry <redpig@dataspill.org>

= Copyright and Licensing
Copyright 2008-2021, Chris Hutchinson <portmaster_AT_BSDforge.com>
Copyright 2007-2008, Will Drewry <redpig@dataspill.org>
Some portions copyright 2008 Google Inc
Released into the public domain with no warranty and no guarantees

= Introduction

Unsafe integer operations are a major cause of software defects even in
modern day software. C is the underlying language for most high level
languages (Ruby, Python, Java, etc) in addition to being in widespread
general use. C is a preferred language for high performance programming
and is often used for media file parsing and manipulation.

Integer overflows occur when the calculated integer requires more storage
from the computing platform than is available. If a number is too large,
not all of its information can be stored. This has dangerous side effects.
For a detailed and thorough discussion on integer overflows, please check
out CERT's website on Secure Coding[1] and even Wikipedia[2].

[1] https://www.securecoding.cert.org/confluence/display/seccode/CERT+C+Secure+Coding+Standard
[2] http://en.wikipedia.org/wiki/Integer_overflow

= Requirements

safe_iop was designed explicitly with GNU GCC in mind and has only been
tested with it. Your mileage may vary. Please let me know if it works for
you with different compilers or on different platforms, and I'll update
the Compatibility section below!

In addition, your system must supply limits.h and assert.h for safe_iop
to function as expected.  It is possible to remove the dependence on both,
but it breaks general portability.

= Usage

safe_iop comes in two pieces, safe_iop.h and safe_iop.c.  safe_iop.h
provides extensive macros for performing safe integer operations quickly
and easily. safe_iop.c contains some testing code to make sure the package
works on your system and a preliminary format string interface, safe_iopf.
safe_iopf is not for the faint of heart as it is currently under development.
The remainder of this document will focus on safe_iop.h.

In order to use safe_iop, you will need to place safe_iop.h in your
compiler's include path either by copying it somewhere like /usr/include,
using an include flag -I/opt/safe_iop/include, or whatever other way you
prefer. You will then need to include the header in the source file you
will use the functions from.
E.g., #include <safe_iop.h>

safe_iop provides macros which check the validity of a given integer
operation. It supports the following operations:
- multiplication: safe_mul()
- division:       safe_div()
- addition:       safe_add()
- subtraction:    safe_sub()

All of these macros take a result pointer, or NULL, as the first argument.
The subsequent argument should be the two values to operate on. They then
return true or false depending on if the operation is safe or not.
(If NULL is given, a true or false value will be returned.)

  uint32_t a = 100, b = 200, c = 0;
  if (safe_mul(&c, a, b)) printf("c is %u\n", c);

In addition, there are versions of these functions for multiple sequential
operations:

  uint32_t a = 100, b = 200, c = 300, d = 0;
  if (safe_mul3(&d, a, b, c)) printf("d is %u\n", d);

safe_<op>3-5() are all available.

It is important to note that if the types of integers passed to safe_iop
do not match, the operation will return false (0) with -DNDEBUG defined.
If it is not defined, assert() is called and the program will abort if
these mismatch is seen!

For example,
  uint32_t a = 100, c = 0;
  uint8_t b = 20;
  if (safe_add(&c, a, b)) /* I will return false! */

Examples can be found in the examples/ directory.

== safe_iopf

If you'd like to use the format string function, do so at your own peril :-)
If you like it and would like to send me a patch to make it awesome, I'd
appreciate it!  To use, just include the c file in your build, or build
the shared library and link it to your app:
  make so # or make dylib for OS X
  ...
  gcc yourapp.c ... -lsafe_iop

More to come!

= Compatibility

Tests pass on the following platforms:

- OS X Tiger, x86, GNU GCC 4.0.1
- OS X Leopard, x86, GNU GCC 4.0.1
- GNU/Linux, x86, GNU GCC 4.0.3
- GNU/Linux, x86_64, GNU GCC 4.0.3
- OpenBSD, VAX, GNU GCC 2.95.3
- OpenBSD, sparc, GNU GCC 2.95.3
- OpenBSD, alpha, GNU GCC 3.3.5
- OpenBSD, sparc, GNU GCC 2.95.3
- OpenBSD, macppc, GNU GCC 3.3.5
- OpenBSD, arm, GNU GCC 3.3.5
~ OpenBSD, sparc64, GNU GCC 3.3.5 [1]

[1] For sparc64, there is an optimization bug which causes tests to fail if
    -O<level> exceeds 1.

= Credit where credit is do

- The functions used in this library were largely drawn from the examples
  provided in CERT's secure coding standard.
- Thanks to peter@valchev.net for reviews, comments, enthusiasm, and
  multiple platform tests!
- Thanks to taviso@sdf.lonestar.org for the pointing out stupid API
  decisions and cross-checking my logic.

= Changes

The changes and todo list can be found in include/safe_iop.h

= Contributions, corrections, suggestions, flames . . .

Please drop me an email if I'm doing something completely stupid, you
love using the library, you have a patch or recommendation, or for whatever
other reason. I hope this software helps out a bit!
