From: Christian Brauner Date: Sun, 27 Mar 2016 16:41:51 +0000 (+0200) Subject: add funs to mmap() files to \0-terminated strings X-Git-Tag: lxc-2.0.0.rc14~1^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1adbd02064e10645cdd05a813e23cce2ccb1a4de;p=thirdparty%2Flxc.git add funs to mmap() files to \0-terminated strings In order to do this we make use of the MAP_FIXED flag of mmap(). MAP_FIXED should be safe to use when it replaces an already existing mapping. To this end, we establish an anonymous mapping that is one byte larger than the underlying file. The pages handed to us are zero filled. Now we establish a fixed-address mapping starting at the address we received from our anonymous mapping and replace all bytes excluding the additional \0-byte with the file. This allows us to use normal string-handling function. The idea implemented here is similar to how shared libraries are mapped. Signed-off-by: Christian Brauner --- diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 5f15d9410..98ea0667d 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -69,7 +69,7 @@ struct prctl_mm_map { uint64_t *auxv; uint32_t auxv_size; uint32_t exe_fd; -}; +}; #endif #ifndef O_PATH @@ -1811,3 +1811,31 @@ int lxc_count_file_lines(const char *fn) fclose(f); return n; } + +void *lxc_mmap(void *addr, size_t length, int prot, int flags, int fd, + off_t offset) +{ + void *tmp = NULL, *overlap = NULL; + + /* We establish an anonymous mapping that is one byte larger than the + * underlying file. The pages handed to us are zero filled. */ + tmp = mmap(addr, length + 1, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (tmp == MAP_FAILED) + goto out; + + /* Now we establish a fixed-address mapping starting at the address we + * received from our anonymous mapping and replace all bytes excluding + * the additional \0-byte with the file. This allows us to use normal + * string-handling function. */ + overlap = mmap(tmp, length, prot, MAP_FIXED | flags, fd, offset); + if (overlap == MAP_FAILED) + goto out; + +out: + return overlap; +} + +int lxc_munmap(void *addr, size_t length) +{ + return munmap(addr, length + 1); +} diff --git a/src/lxc/utils.h b/src/lxc/utils.h index a8f09051e..2c1b80fba 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -252,6 +252,14 @@ extern void lxc_free_array(void **array, lxc_free_fn element_free_fn); extern size_t lxc_array_len(void **array); extern void **lxc_append_null_to_array(void **array, size_t count); + +/* mmap() wrapper. lxc_mmap() will take care to \0-terminate files so that + * normal string-handling functions can be used on the buffer. */ +extern void *lxc_mmap(void *addr, size_t length, int prot, int flags, int fd, + off_t offset); +/* munmap() wrapper. Use it to free memory mmap()ed with lxc_mmap(). */ +extern int lxc_munmap(void *addr, size_t length); + //initialize rand with urandom extern int randseed(bool);