[lxc-devel] [PATCH] Ensure that mmap()ed memory is \0-terminated lseek() to end of file and write() terminating \0-byte

Christian Brauner christianvanbrauner at gmail.com
Wed Sep 9 19:22:32 UTC 2015


This allows us to use standard string handling functions and we can avoid using
the GNU-extension memmem(). This simplifies removing the container from the
lxc_snapshots file. Wrap strstr() in a while loop to remove duplicate entries.

Signed-off-by: Christian Brauner <christianvanbrauner at gmail.com>
---
 src/lxc/lxccontainer.c | 88 +++++++++++++++++++++++++++-----------------------
 1 file changed, 48 insertions(+), 40 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index fb99892..5f4d3ab 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1983,13 +1983,13 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
 {
 	FILE *f1;
 	struct stat fbuf;
-	char *buf = NULL;
-	char *del;
+	void *buf = NULL;
+	char *del = NULL;
 	char path[MAXPATHLEN];
 	char newpath[MAXPATHLEN];
-	int fd, ret, n = 0, v = 0;
+	int fd, ret, n = 0, v = 0, ind = 0;
 	bool bret = false;
-	size_t len, difflen;
+	size_t len = 0, bytes = 0;
 
 	if (container_disk_lock(c0))
 		return false;
@@ -2049,55 +2049,63 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
 				goto out;
 			}
 		} else if (!inc) {
-			fd = open(path, O_RDWR | O_CLOEXEC);
-			if (fd < 0)
-				goto out;
+                        if ((fd = open(path, O_RDWR | O_CLOEXEC)) < 0)
+                                goto out;
 
-			ret = fstat(fd, &fbuf);
-			if (ret < 0) {
-				close(fd);
-				goto out;
-			}
+                        if (fstat(fd, &fbuf) < 0) {
+                                close(fd);
+                                goto out;
+                        }
 
-			if (fbuf.st_size != 0) {
-				buf = 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);
-					goto out;
-				}
-			}
-
-			len = strlen(newpath);
-
-			/* mmap()ed memory is only \0-terminated when it is not
-			 * a multiple of a pagesize. Hence, we'll use memmem(). */
-                        if ((del = memmem(buf, fbuf.st_size, newpath, len))) {
-                                /* remove container entry */
-                                if (del != buf + fbuf.st_size - len) {
-                                        difflen = fbuf.st_size - (del-buf);
-                                        memmove(del, del + len, strnlen(del, difflen) - len);
+                        if (fbuf.st_size != 0) {
+                                if (lseek(fd, 0, SEEK_END) < 0) {
+                                        close(fd);
+                                        goto out;
                                 }
 
-                                munmap(buf, fbuf.st_size);
+                                /* write terminating \0-byte to file */
+                                if (write(fd, "", 1) <= 0) {
+                                        close(fd);
+                                        goto out;
+                                }
 
-                                if (ftruncate(fd, fbuf.st_size - len) < 0) {
-                                        SYSERROR("Failed to truncate file %s", path);
+                                buf = mmap(NULL, fbuf.st_size + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+                                if (buf == MAP_FAILED) {
+                                        SYSERROR("Failed to create mapping %s", path);
                                         close(fd);
                                         goto out;
                                 }
-                        } else {
-                                munmap(buf, fbuf.st_size);
-			}
 
-			close(fd);
-		}
+                                len = strlen(newpath);
+                                while ((del = strstr((char *)buf, newpath))) {
+                                        memmove(del, del + len, strlen(del) - len + 1);
+                                        bytes += len;
+                                        ind++;
+                                }
+
+                                munmap(buf, fbuf.st_size + 1);
+                                if (ind > 0) {
+                                        if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
+                                                SYSERROR("Failed to truncate file %s", path);
+                                                close(fd);
+                                                goto out;
+                                        }
+                                } else {
+                                        if (ftruncate(fd, fbuf.st_size) < 0) {
+                                                SYSERROR("Failed to truncate file %s", path);
+                                                close(fd);
+                                                goto out;
+                                        }
+                                }
+                        }
+                        close(fd);
+                }
 
 		/* If the lxc-snapshot file is empty, remove it. */
 		if (stat(path, &fbuf) < 0)
 			goto out;
-		if (!fbuf.st_size) {
-			remove(path);
+                if (!fbuf.st_size) {
+                        remove(path);
 		}
 	}
 
-- 
2.5.1



More information about the lxc-devel mailing list