diff options
author | Matthew Dempsky <matthew@cvs.openbsd.org> | 2014-06-13 07:17:55 +0000 |
---|---|---|
committer | Matthew Dempsky <matthew@cvs.openbsd.org> | 2014-06-13 07:17:55 +0000 |
commit | 51fc384bcf4757d13d5947ff3bdda531fc6d2c2b (patch) | |
tree | 1ec96c5bec7406661a0d93e28952a33b3d6ac52e /regress/sys/uvm/minherit_zero | |
parent | 85eeb1e3a9b977aa3728a40ff49136c90b39d210 (diff) |
Add regress test for MAP_INHERIT_ZERO.
Diffstat (limited to 'regress/sys/uvm/minherit_zero')
-rw-r--r-- | regress/sys/uvm/minherit_zero/Makefile | 5 | ||||
-rw-r--r-- | regress/sys/uvm/minherit_zero/minherit_zero.c | 130 |
2 files changed, 135 insertions, 0 deletions
diff --git a/regress/sys/uvm/minherit_zero/Makefile b/regress/sys/uvm/minherit_zero/Makefile new file mode 100644 index 00000000000..9e054db9f59 --- /dev/null +++ b/regress/sys/uvm/minherit_zero/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2014/06/13 07:17:54 matthew Exp $ + +PROG= minherit_zero + +.include <bsd.regress.mk> diff --git a/regress/sys/uvm/minherit_zero/minherit_zero.c b/regress/sys/uvm/minherit_zero/minherit_zero.c new file mode 100644 index 00000000000..e7bfa23f7c1 --- /dev/null +++ b/regress/sys/uvm/minherit_zero/minherit_zero.c @@ -0,0 +1,130 @@ +/* $OpenBSD: minherit_zero.c,v 1.1 2014/06/13 07:17:54 matthew Exp $ */ +/* + * Copyright (c) 2014 Google Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/mman.h> +#include <sys/wait.h> +#include <assert.h> +#include <fcntl.h> +#include <paths.h> +#include <string.h> +#include <unistd.h> + +#define CHECK(x) assert((x)) +#define CHECK_EQ(a, b) assert((a) == (b)) +#define CHECK_NE(a, b) assert((a) != (b)) +#define CHECK_GE(a, b) assert((a) >= (b)) + +static int +ismemset(const void *s, int c, size_t n) +{ + const unsigned char *p = s; + size_t i; + + for (i = 0; i < n; i++) + if (p[i] != c) + return (0); + return (1); +} + +static void +wait_for_clean_exit(pid_t pid) +{ + int status; + CHECK_EQ(pid, waitpid(pid, &status, 0)); + CHECK(WIFEXITED(status)); + CHECK_EQ(0, WEXITSTATUS(status)); +} + +enum { + NPAGES = 4, + + PARENT_BYTE = 42, + CHILD_BYTE = 53, + GRANDCHILD_BYTE = 65 +}; + +/* + * We map some memory, configure it's inheritance for MAP_INHERIT_ZERO, + * then check that when we fork child or grandchild processes, that they + * receive new zero'd out memory mappings. Additionally, we sanity check + * that after the child (or grandchild) process exits, that the parent's + * memory is still in tact. + */ +static void +dotest(int fd, size_t len, int flags) +{ + void *p; + pid_t pid; + + p = mmap(NULL, len, PROT_READ|PROT_WRITE, flags, fd, 0); + CHECK_NE(MAP_FAILED, p); + + CHECK_EQ(0, minherit(p, len, MAP_INHERIT_ZERO)); + + memset(p, PARENT_BYTE, len); + + pid = fork(); + CHECK_GE(pid, 0); + if (pid == 0) { + CHECK(ismemset(p, 0, len)); + memset(p, CHILD_BYTE, len); + + pid = fork(); + CHECK_GE(pid, 0); + if (pid == 0) { + CHECK(ismemset(p, 0, len)); + memset(p, GRANDCHILD_BYTE, len); + _exit(0); + } + + wait_for_clean_exit(pid); + CHECK(ismemset(p, CHILD_BYTE, len)); + memset(p, 0, len); + _exit(0); + } + + wait_for_clean_exit(pid); + CHECK(ismemset(p, PARENT_BYTE, len)); + memset(p, 0, len); + + CHECK_EQ(0, munmap(p, len)); +} + +int +main() +{ + long pagesize; + size_t len; + + pagesize = sysconf(_SC_PAGESIZE); + CHECK_GE(pagesize, 1); + len = NPAGES * pagesize; + + /* First run test with private anonymous memory. */ + dotest(-1, len, MAP_ANON|MAP_PRIVATE); + + /* Test again with shared anonymous memory. */ + dotest(-1, len, MAP_ANON|MAP_SHARED); + + /* Finally, test with private file mapping. */ + int fd = open(_PATH_BSHELL, O_RDONLY); + CHECK_GE(fd, 0); + dotest(fd, len, MAP_FILE|MAP_PRIVATE); + CHECK_EQ(0, close(fd)); + + return (0); +} |