[lxc-devel] [lxc/master] add funs to mmap() files to \0-terminated strings

brauner on Github lxc-bot at linuxcontainers.org
Sun Mar 27 16:40:11 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 958 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160327/5ab9395f/attachment.bin>
-------------- next part --------------
From 51abafeb63a831e21b4ab114e0a07285829a8214 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at mailbox.org>
Date: Sun, 27 Mar 2016 18:35:41 +0200
Subject: [PATCH] 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 <christian.brauner at mailbox.org>
---
 src/lxc/lxccontainer.c |  9 ++-------
 src/lxc/utils.c        | 30 +++++++++++++++++++++++++++++-
 src/lxc/utils.h        |  8 ++++++++
 3 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index ab48fb5..8e2f413 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -2163,13 +2163,8 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
 			}
 
 			if (fbuf.st_size != 0) {
-				/* write terminating \0-byte to file */
-				if (pwrite(fd, "", 1, fbuf.st_size) <= 0) {
-					close(fd);
-					goto out;
-				}
 
-				buf = mmap(NULL, fbuf.st_size + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+				buf = lxc_mmap(NULL, fbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 				if (buf == MAP_FAILED) {
 					SYSERROR("Failed to create mapping %s", path);
 					close(fd);
@@ -2182,7 +2177,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
 					bytes += len;
 				}
 
-				munmap(buf, fbuf.st_size + 1);
+				lxc_munmap(buf, fbuf.st_size);
 				if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
 					SYSERROR("Failed to truncate file %s", path);
 					close(fd);
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 5f15d94..98ea066 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 a8f0905..2c1b80f 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);
 


More information about the lxc-devel mailing list