Commit 42342bed by Christian Brauner Committed by Stéphane Graber

Ensure that mmap()ed memory is \0-terminated (v3)

Use pwrite() to write terminating \0-byte 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: 's avatarChristian Brauner <christianvanbrauner@gmail.com> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent af651aa9
...@@ -1983,13 +1983,13 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc ...@@ -1983,13 +1983,13 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
{ {
FILE *f1; FILE *f1;
struct stat fbuf; struct stat fbuf;
char *buf = NULL; void *buf = NULL;
char *del; char *del = NULL;
char path[MAXPATHLEN]; char path[MAXPATHLEN];
char newpath[MAXPATHLEN]; char newpath[MAXPATHLEN];
int fd, ret, n = 0, v = 0; int fd, ret, n = 0, v = 0;
bool bret = false; bool bret = false;
size_t len, difflen; size_t len = 0, bytes = 0;
if (container_disk_lock(c0)) if (container_disk_lock(c0))
return false; return false;
...@@ -2049,55 +2049,49 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc ...@@ -2049,55 +2049,49 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
goto out; goto out;
} }
} else if (!inc) { } else if (!inc) {
fd = open(path, O_RDWR | O_CLOEXEC); if ((fd = open(path, O_RDWR | O_CLOEXEC)) < 0)
if (fd < 0) goto out;
goto out;
ret = fstat(fd, &fbuf); if (fstat(fd, &fbuf) < 0) {
if (ret < 0) { close(fd);
close(fd); goto out;
goto out; }
}
if (fbuf.st_size != 0) { if (fbuf.st_size != 0) {
buf = mmap(NULL, fbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); /* write terminating \0-byte to file */
if (buf == MAP_FAILED) { if (pwrite(fd, "", 1, fbuf.st_size) <= 0) {
SYSERROR("Failed to create mapping %s", path); close(fd);
close(fd); goto out;
goto out; }
}
}
len = strlen(newpath);
/* mmap()ed memory is only \0-terminated when it is not buf = mmap(NULL, fbuf.st_size + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
* a multiple of a pagesize. Hence, we'll use memmem(). */ if (buf == MAP_FAILED) {
if ((del = memmem(buf, fbuf.st_size, newpath, len))) { SYSERROR("Failed to create mapping %s", path);
/* remove container entry */ close(fd);
if (del != buf + fbuf.st_size - len) { goto out;
difflen = fbuf.st_size - (del-buf);
memmove(del, del + len, strnlen(del, difflen) - len);
} }
munmap(buf, fbuf.st_size); len = strlen(newpath);
while ((del = strstr((char *)buf, newpath))) {
memmove(del, del + len, strlen(del) - len + 1);
bytes += len;
}
if (ftruncate(fd, fbuf.st_size - len) < 0) { munmap(buf, fbuf.st_size + 1);
if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
SYSERROR("Failed to truncate file %s", path); SYSERROR("Failed to truncate file %s", path);
close(fd); close(fd);
goto out; goto out;
} }
} else { }
munmap(buf, fbuf.st_size); close(fd);
} }
close(fd);
}
/* If the lxc-snapshot file is empty, remove it. */ /* If the lxc-snapshot file is empty, remove it. */
if (stat(path, &fbuf) < 0) if (stat(path, &fbuf) < 0)
goto out; goto out;
if (!fbuf.st_size) { if (!fbuf.st_size) {
remove(path); remove(path);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment