[lxc-devel] [PATCH] Ensure that mmap()ed memory is \0-terminated (v2) Use pwrite() to write terminating \0-byte

Christian Brauner christianvanbrauner at gmail.com
Fri Sep 11 06:03:18 UTC 2015


Updated patch to follow.

On Thu, Sep 10, 2015 at 11:20:44PM +0000, Serge Hallyn wrote:
> Quoting Christian Brauner (christianvanbrauner at gmail.com):
> > 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>
> 
> looks good, one comment below.
> 
> > ---
> >  src/lxc/lxccontainer.c | 85 ++++++++++++++++++++++++++------------------------
> >  1 file changed, 44 insertions(+), 41 deletions(-)
> > 
> > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> > index fb99892..7026719 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,58 @@ 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;
> > -
> > -			ret = fstat(fd, &fbuf);
> > -			if (ret < 0) {
> > -				close(fd);
> > -				goto out;
> > -			}
> > +                        if ((fd = open(path, O_RDWR | O_CLOEXEC)) < 0)
> > +                                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;
> > -				}
> > -			}
> > +                        if (fstat(fd, &fbuf) < 0) {
> > +                                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) {
> > +                                /* write terminating \0-byte to file */
> > +                                if (pwrite(fd, "", 1, fbuf.st_size) <= 0) {
> > +                                        close(fd);
> > +                                        goto out;
> >                                  }
> >  
> > -                                munmap(buf, fbuf.st_size);
> > -
> > -                                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);
> 
> since bytes is 0 if ind is 0, you can just do the 
> 
>                                 if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
>                                         SYSERROR("Failed to truncate file %s", path);
>                                         close(fd);
>                                         goto out;
>                                 }
> 
> below, rather than special-casing (ind <= 0)

Thanks!

> 
> > +                                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
> > 
> > _______________________________________________
> > lxc-devel mailing list
> > lxc-devel at lists.linuxcontainers.org
> > http://lists.linuxcontainers.org/listinfo/lxc-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20150911/c4f7cd17/attachment.sig>


More information about the lxc-devel mailing list