]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
add funs to mmap() files to \0-terminated strings
authorChristian Brauner <christian.brauner@mailbox.org>
Sun, 27 Mar 2016 16:41:51 +0000 (18:41 +0200)
committerChristian Brauner <christian.brauner@mailbox.org>
Tue, 29 Mar 2016 06:48:27 +0000 (08:48 +0200)
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 <christian.brauner@mailbox.org>
src/lxc/utils.c
src/lxc/utils.h

index 5f15d9410e61679eb3f31e776f84d798fd728fc0..98ea0667dfece20e2ca1cdb391409a5dcfee5c9f 100644 (file)
@@ -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);
+}
index a8f09051e931e2cecc50813e450be6cbd965040d..2c1b80fba60c93055911f6e658cf750d199a6ae0 100644 (file)
@@ -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);