fusefs: fix some uninitialized memory references

This bug was long present, but was exacerbated by r345876.

The problem is that fiov_refresh was bzero()ing a buffer _before_ it
reallocated that buffer.  That's obviously the wrong order.  I fixed the
order in r345876, which exposed the main problem.  Previously, the first 160
bytes of the buffer were getting bzero()ed when it was first allocated in
fiov_init.  Subsequently, as that buffer got recycled between callers, the
portion used by the _previous_ caller was getting bzero()ed by the current
caller in fiov_refresh.  The problem was never visible simply because no
caller was trying to use more than 160 bytes.

Now the buffer gets properly bzero()ed both at initialization time and any
time it gets enlarged or reallocated.

Sponsored by:	The FreeBSD Foundation
This commit is contained in:
asomers 2019-04-04 20:24:58 +00:00
parent 5feef0e492
commit d78a539252

View File

@ -182,6 +182,11 @@ fiov_adjust(struct fuse_iov *fiov, size_t size)
}
fiov->allocated_size = FU_AT_LEAST(size);
fiov->credit = fuse_iov_credit;
/* Clear data buffer after reallocation */
bzero(fiov->base, size);
} else if (size > fiov->len) {
/* Clear newly extended portion of data buffer */
bzero((char*)fiov->base + fiov->len, size - fiov->len);
}
fiov->len = size;
}
@ -198,7 +203,6 @@ void
fiov_refresh(struct fuse_iov *fiov)
{
fiov_adjust(fiov, 0);
bzero(fiov->base, fiov->len);
}
static int
@ -744,6 +748,8 @@ fdisp_refresh_pid(struct fuse_dispatcher *fdip, enum fuse_opcode op,
struct mount *mp, uint64_t nid, pid_t pid, struct ucred *cred)
{
MPASS(fdip->tick);
MPASS2(sizeof(fdip->finh) + fdip->iosize <= fdip->tick->tk_ms_fiov.len,
"Must use fdisp_make_pid to increase the size of the fiov");
fticket_reset(fdip->tick);
FUSE_DIMALLOC(&fdip->tick->tk_ms_fiov, fdip->finh,
@ -766,6 +772,7 @@ fdisp_make_pid(struct fuse_dispatcher *fdip, enum fuse_opcode op,
fdip->tick = fuse_ticket_fetch(data);
}
/* FUSE_DIMALLOC will bzero the fiovs when it enlarges them */
FUSE_DIMALLOC(&fdip->tick->tk_ms_fiov, fdip->finh,
fdip->indata, fdip->iosize);