Allocate buffer when splicing from the fuse device
authorMiklos Szeredi <mszeredi@suse.cz>
Thu, 27 Feb 2014 14:02:12 +0000 (15:02 +0100)
committerMiklos Szeredi <mszeredi@suse.cz>
Thu, 27 Feb 2014 14:02:12 +0000 (15:02 +0100)
Was broken by commit 561d7054d856 "libfuse: remove fuse_chan_bufsize()".

lib/fuse_lowlevel.c

index 19feb14cdfd7faa72ef83b172ced2805fa635794..4284535654491a0c0884789a080fd7d5b063a894 100755 (executable)
@@ -2721,7 +2721,7 @@ int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
                             struct fuse_chan *ch)
 {
        struct fuse_ll *f = se->f;
-       size_t bufsize = buf->size = f->bufsize;
+       size_t bufsize = f->bufsize;
        struct fuse_ll_pipe *llp;
        struct fuse_buf tmpbuf;
        int err;
@@ -2782,7 +2782,19 @@ int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
        if (res < sizeof(struct fuse_in_header) +
            sizeof(struct fuse_write_in) + pagesize) {
                struct fuse_bufvec src = { .buf[0] = tmpbuf, .count = 1 };
-               struct fuse_bufvec dst = { .buf[0] = *buf, .count = 1 };
+               struct fuse_bufvec dst = { .count = 1 };
+
+               if (!buf->mem) {
+                       buf->mem = malloc(f->bufsize);
+                       if (!buf->mem) {
+                               fprintf(stderr,
+                                       "fuse: failed to allocate read buffer\n");
+                               return -ENOMEM;
+                       }
+               }
+               buf->size = f->bufsize;
+               buf->flags = 0;
+               dst.buf[0] = *buf;
 
                res = fuse_buf_copy(&dst, &src, 0);
                if (res < 0) {
@@ -2796,11 +2808,14 @@ int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
                        fuse_ll_clear_pipe(f);
                        return -EIO;
                }
-               buf->size = tmpbuf.size;
-               return buf->size;
-       }
+               assert(res == tmpbuf.size);
 
-       *buf = tmpbuf;
+       } else {
+               /* Don't overwrite buf->mem, as that would cause a leak */
+               buf->fd = tmpbuf.fd;
+               buf->flags = tmpbuf.flags;
+       }
+       buf->size = tmpbuf.size;
 
        return res;