Hello, I'm attaching a proposition of an overflow library, as a part of the NetBSD kernel and libc with dedicated header overflow.h. The library was inspired by libo by Xi Wang: https://github.com/xiw/libo Xi Wang was kind to license his work to BSD. I keep his license note as a credit even though in the final work there is little code share. The library was designed as a fast overflow checking utilities, however in the final work I put the emphasis on the safety rather then speed. A good compiler like GCC/Clang will likely optimize the code for efficiency on an architecture that is capable of it (like i386). The library is intended to be used as a layer in libc and kernel, everywhere an integer operation may overflow in the * / + - operations. Usage: if (overflow_mul(&c, a, b)) printf("overflow!\n"); The library is type agnostic, and for this there is need for a C11 or GCC-compatible compiler. At the moment PCC isn't supported. There is fall-back with a dummy implementation, which doesn't check for overflow, just does blindly a desired arithmetic operation. If the detection of overflows doesn't work and there is used the dummy implementation there is operations aren't supported then OVERFLOW_FUNCS_DUMMY is defined. A security important code should check for it (like calloc(3)), and implement fallback for manual overflow checks. I'm attaching test.c and test.sh (cc test.c -lutil) for developer tests. Known problems (at the moment I don't know how to fix): 1. '#include <overflow.h>' doesn't work, there is need for '#include <sys/overflow.h>' how to fix it? 2. Sanity preprocessor magic 3. Missing libkern support (problems with overflow.c not recognizing CHAR_MAX etc) Please review, After inclusion I will submit: - ATF tests, - strsuftoi/strsuftou replacement of strsuftoll(3) - switch to these functions in calloc(3), reallocarray(3), - everythin else. CC: Christos and Joerg as you were helping me with reallocarray(3). Regards,
Attachment:
patch-src-common
Description: Binary data
Attachment:
patch-src-lib
Description: Binary data
Attachment:
patch-src-sys
Description: Binary data
Attachment:
patch-src-tools
Description: Binary data
#include <string.h> #include <stdlib.h> #include <stdio.h> #include <stdbool.h> #include <err.h> #include <stdint.h> #include <inttypes.h> #include <limits.h> #include <util.h> #include "overflow.h" #define FUN(name,type,min,max, wrapped, print) \ void test_##name(char *a, char *b) \ { \ type v1 = wrapped(a, 0, min, max); \ type v2 = wrapped(b, 0, min, max); \ \ type res; \ bool o; \ \ o = overflow_add(&res, v1, v2); \ printf("[%s] %" #print " + %" #print " = %" #print " [status %s]\n", #name , v1, v2, res, o ? "overflow" : "ok"); \ o = overflow_sub(&res, v1, v2); \ printf("[%s] %" #print " - %" #print " = %" #print " [status %s]\n", #name , v1, v2, res, o ? "overflow" : "ok"); \ o = overflow_mul(&res, v1, v2); \ printf("[%s] %" #print " * %" #print " = %" #print " [status %s]\n", #name , v1, v2, res, o ? "overflow" : "ok"); \ o = overflow_div(&res, v1, v2); \ printf("[%s] %" #print " / %" #print " = %" #print " [status %s]\n", #name , v1, v2, res, o ? "overflow" : "ok"); \ } FUN(char,char,CHAR_MIN,CHAR_MAX,estrtoi, d) FUN(schar,signed char,SCHAR_MIN,SCHAR_MAX,estrtoi, hhd) FUN(uchar,unsigned char,0,UCHAR_MAX,estrtou, hhu) FUN(shrt,short,SHRT_MIN,SHRT_MAX,estrtoi, hd) FUN(ushrt,unsigned short,0,USHRT_MAX,estrtou, hu) FUN(int,int,INT_MIN,INT_MAX,estrtoi, d) FUN(uint,unsigned int,0,UINT_MAX,estrtou, u) FUN(long,long,LONG_MIN,LONG_MAX,estrtoi, ld) FUN(ulong,unsigned long,0,ULONG_MAX,estrtou, lu) FUN(llong,long long,LLONG_MIN,LLONG_MAX,estrtoi, lld) FUN(ullong,unsigned long long,0,ULLONG_MAX,estrtou, llu) #define IF_CHECK(name) \ if (strcmp(argv[1], #name ) == 0) { \ test_##name (argv[2], argv[3]); \ } void usage(void) { errx(EXIT_FAILURE, "usage: ./prog [char|schar|uchar|int|uint|long|ulong|llong|ullong] NUM1 NUM2"); } int main(int argc, char **argv) { if (argc < 4) usage(); IF_CHECK(char) else IF_CHECK(schar) else IF_CHECK(uchar) else IF_CHECK(shrt) else IF_CHECK(ushrt) else IF_CHECK(int) else IF_CHECK(uint) else IF_CHECK(long) else IF_CHECK(ulong) else IF_CHECK(llong) else IF_CHECK(ullong) else usage(); return 0; }
Attachment:
test.sh
Description: Unix shell archive