11195Srgrimes/* $OpenBSD: malloc0test.c,v 1.5 2008/04/13 00:22:17 djm Exp $ */ 250472Speter/* 337Srgrimes * Public domain. 2001, Theo de Raadt 438103Speter */ 538103Speter#include <sys/types.h> 664618Sgshapiro#include <sys/signal.h> 755230Speter#include <stdio.h> 855230Speter#include <unistd.h> 955230Speter#include <stdlib.h> 1055230Speter#include <setjmp.h> 1155230Speter#include <limits.h> 1259257Siwasaki#include <errno.h> 1357954Sshin 1455230Spetervolatile sig_atomic_t got; 1557407Sshinjmp_buf jmp; 1655230Speter 1755230Speterstatic void 1855230Spetercatch(int signo) 1955230Speter{ 201734Sjkh got++; 2117639Swosch longjmp(jmp, 1); 2217639Swosch} 2337Srgrimes 2457479Speterstatic int 2557488Spetertest(char *p, int size) 2657459Smarkm{ 2757459Smarkm signal(SIGSEGV, catch); 2857459Smarkm got = 0; 2960677Skris if (setjmp(jmp) == 0) 3060677Skris *p = 0; 3160677Skris if (setjmp(jmp) == 0) 3260677Skris *(p+size-1) = 0; 331773Sjkh return (got); 3448734Siwasaki} 35147Srgrimes 3627487Sasamichar *prot_table[] = { 3765168Sasami "unprotected", 3835832Sache "fuckup", 3943901Sbrian "protected" 4049110Sbrian}; 4164598Sgshapiro 4264598Sgshapiro#define SIZE 10 4337Srgrimes 4417639Swosch/* 45263Srgrimes * Do random memory allocations. 462779Srgrimes * 478857Srgrimes * For each one, ensure that it is at least 16 bytes in size (that 48993Srgrimes * being what our current malloc returns for the minsize of an 49263Srgrimes * object, alignment wise); 5038103Speter * 5137Srgrimes * For zero-byte allocations, check that they are still aligned. 524487Sphk * 536717Sphk * For each object, ensure that they are correctly protected or not 5439590Sjkh * protected. 5539636Sdima * 5639590Sjkh * Does not regress test malloc + free combinations ... it should. 5739590Sjkh */ 585948Sjkhint 594487Sphkmain(int argc, char *argv[]) 601759Sjkh{ 619970Sbde caddr_t blob; 6236902Sguido int size, tsize; 6343832Sjkh int prot; 6452609Sdillon int rval = 0, fuckup = 0; 6558979Siwasaki long limit = 200000, count; 6661981Sbrian int ch, silent = 0; 679970Sbde char *ep; 6851033Sn_hibma extern char *__progname; 699970Sbde 701759Sjkh while ((ch = getopt(argc, argv, "sn:")) != -1) { 7157488Speter switch (ch) { 7257488Speter case 's': 7317639Swosch silent = 1; 7417639Swosch break; 7517645Swosch case 'n': 7638160Sjb errno = 0; 7757488Speter limit = strtol(optarg, &ep, 10); 781759Sjkh if (optarg[0] == '\0' || *ep != '\0' || 799970Sbde (errno == ERANGE && 8053327Speter (limit == LONG_MAX || limit == LONG_MIN))) 8157488Speter goto usage; 8257488Speter break; 8357488Speter default: 8457488Speterusage: 8560677Skris fprintf(stderr, "Usage: %s [-s][-n <count>]\n", 8660677Skris __progname); 8760677Skris exit(1); 8860677Skris } 8957071Srwatson } 9057488Speter 9157071Srwatson if (limit == 0) 921731Sjkh limit = LONG_MAX; 939970Sbde 9437Srgrimes for (count = 0; count < limit; count++) { 959970Sbde size = arc4random_uniform(SIZE); 9637Srgrimes blob = malloc(size); 979970Sbde if (blob == NULL) { 9837Srgrimes fprintf(stderr, "success: out of memory\n"); 999970Sbde exit(rval); 10037Srgrimes } 10137Srgrimes 10237Srgrimes tsize = size == 0 ? 16 : size; 10337Srgrimes fuckup = 0; 1049970Sbde prot = test(blob, tsize); 1051731Sjkh 1069970Sbde if (size == 0 && prot < 2) 1071731Sjkh fuckup = 1; 1089970Sbde 1096177Samurai if (fuckup) { 11049110Sbrian printf("%8p %6d %20s %10s\n", blob, size, 11149110Sbrian prot_table[prot], fuckup ? "fuckup" : ""); 11230589Sjmb rval = 1; 11364598Sgshapiro } 11464629Sgshapiro 11564629Sgshapiro if (!silent && count % 100000 == 0 && count != 0) 11664629Sgshapiro fprintf(stderr, "count = %ld\n", count); 11764629Sgshapiro } 11864629Sgshapiro 1199970Sbde return rval; 12037Srgrimes} 12163097Speter