Browse Source

SECURITY: check for integer overflow in stralloc_ready

master
Felix von Leitner 8 years ago
parent
commit
765d88a76d
  1. 1
      CHANGES
  2. 1
      stralloc/stralloc_free.c
  3. 2
      stralloc/stralloc_ready.c
  4. 53
      test/marshal.c

1
CHANGES

@ -10,6 +10,7 @@
added fmt_escapechar* to fmt.h (implement various escaping mechanisms also found in textcode but for a single char not a whole string, and they always escape, not just when they think it's needed)
scan_ushort was supposed to abort early and return 5 when attempting to parse "65536", because the result does not fit. It did not. Now it does.
scan_*long, scan_*int, scan_*short now properly abort if the number would not fit
SECURITY: check for integer overflow in stralloc_ready
0.29:
save 8 bytes in taia.h for 64-bit systems

1
stralloc/stralloc_free.c

@ -4,4 +4,5 @@
void stralloc_free(stralloc *sa) {
if (sa->s) free(sa->s);
sa->s=0;
sa->a=sa->len=0;
}

2
stralloc/stralloc_ready.c

@ -9,7 +9,7 @@
* old space, and returns 1. Note that this changes sa.s. */
int stralloc_ready(stralloc *sa,size_t len) {
register size_t wanted=len+(len>>3)+30; /* heuristic from djb */
if (!sa->s || sa->a<len) {
if (wanted<len || !sa->s || sa->a<len) {
register char* tmp;
if (!(tmp=realloc(sa->s,wanted)))
return 0;

53
test/marshal.c

@ -1,14 +1,20 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <fmt.h>
#include <scan.h>
#include <textcode.h>
#include <byte.h>
#include <assert.h>
#include <uint16.h>
#include <uint32.h>
#include <uint64.h>
#include <openreadclose.h>
#include <mmap.h>
char buf[100];
stralloc sa;
void zap() { size_t i; for (i=0; i<sizeof(buf); ++i) buf[i]='_'; }
@ -26,6 +32,13 @@ int main() {
signed int i;
signed short s;
long flen;
char* stdiocopy;
#ifdef NDEBUG
#error This is a unit test that uses assert() or all checks, compile without -DNDEBUG!
#endif
// check utf8 encoding
zap(); assert(fmt_utf8(NULL,12345) == 3);
zap(); assert(fmt_utf8(buf,12345) == 3 && byte_equal(buf,4,"\xe3\x80\xb9_"));
@ -306,5 +319,41 @@ int main() {
}
}
{
char* mmapcopy;
FILE* f;
size_t mlen;
assert(f=fopen("test/marshal.c","rb"));
assert(fseek(f,0,SEEK_END)==0);
flen=ftell(f);
assert(flen>4096);
fseek(f,0,SEEK_SET);
assert(stdiocopy=malloc(flen));
assert(fread(stdiocopy,1,flen,f)==flen);
fclose(f);
assert(openreadclose("test/marshal.c",&sa,4096)==1);
assert(sa.len == flen);
assert(byte_equal(sa.s,flen,stdiocopy));
assert((mmapcopy=mmap_read("test/marshal.c",&mlen)) && mlen==flen);
assert(byte_equal(sa.s,flen,mmapcopy));
mmap_unmap(mmapcopy,mlen);
}
stralloc_free(&sa);
assert(stralloc_ready(&sa,0x1000));
assert(sa.a >= 0x1000);
assert(stralloc_copyb(&sa,stdiocopy,0x900));
assert(sa.len == 0x900);
assert(stralloc_catb(&sa,stdiocopy+0x900,0x700));
assert(sa.len == 0x1000);
assert(byte_equal(sa.s,0x1000,stdiocopy));
assert(stralloc_readyplus(&sa,0x1000));
assert(sa.a >= 0x2000);
assert(stralloc_readyplus(&sa,(size_t)-1)==0);
assert(stralloc_ready(&sa,(size_t)-1)==0);
return 0;
}

Loading…
Cancel
Save