diff options
author | Stefan Metzmacher <metze@samba.org> | 2010-10-26 22:45:19 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2011-01-20 05:31:45 +0100 |
commit | cc59f347ee6ca5d48ba2790a8f5d843b76c470a7 (patch) | |
tree | 580ec3f252132980c48d6864b893021b436187fb /lib/util | |
parent | 34ea9096366fe475891a0aee7b3bbc74bfe07032 (diff) | |
download | samba-cc59f347ee6ca5d48ba2790a8f5d843b76c470a7.tar.gz samba-cc59f347ee6ca5d48ba2790a8f5d843b76c470a7.tar.bz2 samba-cc59f347ee6ca5d48ba2790a8f5d843b76c470a7.zip |
lib/util: add anonymous_shared_free()
metze
Diffstat (limited to 'lib/util')
-rw-r--r-- | lib/util/util.c | 41 | ||||
-rw-r--r-- | lib/util/util.h | 1 |
2 files changed, 40 insertions, 2 deletions
diff --git a/lib/util/util.c b/lib/util/util.c index db71def4c4..35ad49b532 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -936,12 +936,24 @@ bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); } +struct anonymous_shared_header { + union { + size_t length; + uint8_t pad[16]; + } u; +}; + /* Map a shared memory buffer of at least nelem counters. */ -void *anonymous_shared_allocate(size_t bufsz) +void *anonymous_shared_allocate(size_t orig_bufsz) { + void *ptr; void *buf; size_t pagesz = getpagesize(); size_t pagecnt; + size_t bufsz = orig_bufsz; + struct anonymous_shared_header *hdr; + + bufsz += sizeof(*hdr); /* round up to full pages */ pagecnt = bufsz / pagesz; @@ -950,6 +962,12 @@ void *anonymous_shared_allocate(size_t bufsz) } bufsz = pagesz * pagecnt; + if (orig_bufsz >= bufsz) { + /* integer wrap */ + errno = ENOMEM; + return NULL; + } + #ifdef MAP_ANON /* BSD */ buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, @@ -963,8 +981,27 @@ void *anonymous_shared_allocate(size_t bufsz) return NULL; } - return buf; + hdr = (struct anonymous_shared_header *)buf; + hdr->u.length = bufsz; + + ptr = (void *)(&hdr[1]); + + return ptr; +} + +void anonymous_shared_free(void *ptr) +{ + struct anonymous_shared_header *hdr; + + if (ptr == NULL) { + return; + } + + hdr = (struct anonymous_shared_header *)ptr; + + hdr--; + munmap(hdr, hdr->u.length); } #ifdef DEVELOPER diff --git a/lib/util/util.h b/lib/util/util.h index 04ea20d07d..8f4fd8f70b 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -859,6 +859,7 @@ bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, * Allocate anonymous shared memory of the given size */ void *anonymous_shared_allocate(size_t bufsz); +void anonymous_shared_free(void *ptr); /* run a command as a child process, with a timeout. |