This repository has been archived by the owner on Nov 15, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Upstream
committed
Jan 12, 1970
0 parents
commit 4fd3728
Showing
5 changed files
with
2,076 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
Oops, something went wrong.