[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