Skip to content
This repository has been archived by the owner on Nov 15, 2022. It is now read-only.

Commit

Permalink
external/safe-iop 0.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Upstream committed Jan 12, 1970
0 parents commit 4fd3728
Show file tree
Hide file tree
Showing 5 changed files with 2,076 additions and 0 deletions.
44 changes: 44 additions & 0 deletions Makefile
@@ -0,0 +1,44 @@
#
# safe_iop - Makefile
#
# Author:: Will Drewry <redpig@dataspill.org>
# Copyright 2007,2008 redpig@dataspill.org
# Some portions copyright 2008 Google Inc.
#
# Unless required by applicable law or agreed to in writing, software
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
# OF ANY KIND, either express or implied.
#

CC = gcc
VERSION = 0.3
TESTNAME = safe_iop_test
# For sparc64, _only_ use -O1 or -O0
CFLAGS = -Wall -O2 -Iinclude
SOURCES = src/safe_iop.c

all: $(TESTNAME)

# This may be built as a library or directly included in source.
# Unless support for safe_iopf is needed, header inclusion is enough.

$(TESTNAME): src/safe_iop.c include/safe_iop.h
$(CC) $(CFLAGS) -DNDEBUG=1 -DSAFE_IOP_TEST=1 $(SOURCES) -o $@

askme: examples/askme.c include/safe_iop.h
$(CC) $(CFLAGS) examples/askme.c -o $@

so: src/safe_iop.c include/safe_iop.h
$(CC) -shared -Wl,-soname,libsafe_iop.so.$(VERSION) $(CFLAGS) $(SOURCES) -o libsafe_iop.so.$(VERSION)

dylib: src/safe_iop.c include/safe_iop.h
$(CC) -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,$(VERSION),-current_version,$(VERSION),-install_name,/usr/local/lib/libsafe_iop.$(VERSION).dylib $(CFLAGS) $(SOURCES) -o libsafe_iop.$(VERSION).dylib


test: $(TESTNAME)
@./$(TESTNAME)
@rm $(TESTNAME)

clean:
rm $(TESTNAME)

136 changes: 136 additions & 0 deletions README
@@ -0,0 +1,136 @@
safe_iop - a safe integer operation library for C
Will Drewry <redpig@dataspill.org>

= Copyright and Licensing
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!
20 changes: 20 additions & 0 deletions examples/askme.c
@@ -0,0 +1,20 @@
#include <stdio.h> /* for printf, fgets */
#include <stdlib.h> /* for atoi */
#include <stdint.h> /* for uint32_t */
#include <safe_iop.h> /* for awesomeness */

int main(int argc, char **argv) {
char buf[1024];
uint32_t width = 0, height = 0, pixels = 0;
printf("Please specify the width of the new image: ");
width = strtoul(fgets(buf, 1023, stdin), NULL, 10);
printf("Please specify the height of the new image: ");
height = strtoul(fgets(buf, 1023, stdin), NULL, 10);
if (safe_mul(&pixels, width, height)) {
printf("The resulting image will have %u pixels.\n", pixels);
return 0;
} else {
printf("Image size specified exceeds maximum size!\n");
return 1;
}
}

0 comments on commit 4fd3728

Please sign in to comment.