diff options
-rw-r--r-- | regress/lib/libc/Makefile | 4 | ||||
-rw-r--r-- | regress/lib/libc/mkstemp/Makefile | 19 | ||||
-rw-r--r-- | regress/lib/libc/mkstemp/mkstemp_test.c | 95 |
3 files changed, 116 insertions, 2 deletions
diff --git a/regress/lib/libc/Makefile b/regress/lib/libc/Makefile index 3c24e3f6341..ddbb9505fe6 100644 --- a/regress/lib/libc/Makefile +++ b/regress/lib/libc/Makefile @@ -1,10 +1,10 @@ -# $OpenBSD: Makefile,v 1.30 2009/11/21 09:56:10 guenther Exp $ +# $OpenBSD: Makefile,v 1.31 2010/02/11 07:35:38 guenther Exp $ SUBDIR+= _setjmp alloca atexit basename cxa-atexit db dirname fnmatch SUBDIR+= fpclassify getaddrinfo getcap getopt_long glob hsearch longjmp SUBDIR+= locale malloc netdb popen printf regex setjmp setjmp-signal SUBDIR+= sigreturn sigsetjmp sprintf strerror strtod strtonum telldir time vis -SUBDIR+= orientation stdio_threading +SUBDIR+= orientation stdio_threading mkstemp .if (${MACHINE_ARCH} != "vax") SUBDIR+= ieeefp diff --git a/regress/lib/libc/mkstemp/Makefile b/regress/lib/libc/mkstemp/Makefile new file mode 100644 index 00000000000..dc7eb281a9f --- /dev/null +++ b/regress/lib/libc/mkstemp/Makefile @@ -0,0 +1,19 @@ +# $OpenBSD: Makefile,v 1.1 2010/02/11 07:35:38 guenther Exp $ + +PROG=mkstemp_test +CLEANFILES+= ; rm -rf output + +O = output + +# The ktrace/kdump/perl combo verifies that all open() calls that +# were passed O_CREAT were also passed O_EXCL +run-regress-${PROG}: ${PROG} + mkdir -p $O && cd $O && ktrace ../${PROG} + cd $O && kdump | perl -mFcntl -nl \ + -e '/ open\([^,]*,([^,]+)/ or next;' \ + -e '$$f = oct($$1);' \ + -e 'if ($$f & O_CREAT && !($$f & O_EXCL)) {' \ + -e ' print "FAIL"; exit 1' \ + -e '}' + +.include <bsd.regress.mk> diff --git a/regress/lib/libc/mkstemp/mkstemp_test.c b/regress/lib/libc/mkstemp/mkstemp_test.c new file mode 100644 index 00000000000..d8311cbf351 --- /dev/null +++ b/regress/lib/libc/mkstemp/mkstemp_test.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010 Philip Guenther <guenther@openbsd.org> + * + * Public domain. + * + * Verify that mkstemp() doesn't overrun or underrun the template buffer + * and that it can generate names that don't contain any X's + */ + +#include <sys/param.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <unistd.h> + +#define MAX_TEMPLATE_LEN 10 +#define MAX_TRIES 100 + +long pg; + +void +try(char *p, const char *prefix, int len) +{ + struct stat sb, fsb; + char *q; + size_t plen = strlen(prefix); + int tries, fd; + + for (tries = 0; tries < MAX_TRIES; tries++) { + memcpy(p, prefix, plen); + memset(p + plen, 'X', len); + p[plen + len] = '\0'; + fd = mkstemp(p); + if (fd < 0) + err(1, "mkstemp"); + if (stat(p, &sb)) + err(1, "stat(%s)", p); + if (fstat(fd, &fsb)) + err(1, "fstat(%d==%s)", fd, p); + if (sb.st_dev != fsb.st_dev || sb.st_ino != fsb.st_ino) + errx(1, "stat mismatch"); + close(fd); + for (q = p + plen; *q != 'X'; q++) { + if (*q == '\0') { + if (q != p + plen + len) + errx(1, "unexpected truncation"); + return; + } + } + if (q >= p + plen + len) + errx(1, "overrun?"); + } + errx(1, "exceeded MAX_TRIES"); +} + +int +main(void) +{ + struct stat sb, fsb; + char cwd[MAXPATHLEN + 1]; + char *p; + size_t clen; + int i; + + pg = sysconf(_SC_PAGESIZE); + if (getcwd(cwd, sizeof cwd - 1) == NULL) + err(1, "getcwd"); + clen = strlen(cwd); + cwd[clen++] = '/'; + cwd[clen] = '\0'; + p = mmap(NULL, pg * 3, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + if (p == NULL) + err(1, "mmap"); + if (mprotect(p, pg, PROT_NONE) || mprotect(p + pg * 2, pg, PROT_NONE)) + err(1, "mprotect"); + p += pg; + + i = MAX_TEMPLATE_LEN + 1; + while (i-- > 1) { + /* try first at the start of a page, no prefix */ + try(p, "", i); + /* now at the end of the page, no prefix */ + try(p + pg - i - 1, "", i); + /* start of the page, prefixed with the cwd */ + try(p, cwd, i); + /* how about at the end of the page, prefixed with cwd? */ + try(p + pg - i - 1 - clen, cwd, i); + } + + return 0; +} |