fuse dirent bug???

Konstantin Belousov kostikbel at gmail.com
Wed Dec 10 09:24:35 UTC 2014


On Tue, Dec 09, 2014 at 10:41:30PM -0500, Rick Macklem wrote:
> Hi,
> 
> While looking at the fuse code to change it to use a new
> "struct dirent", I spotted this line, which doesn't look
> correct.
> 
> Line 358 of sys/fs/fuse/fuse_internal.c:
>         ((char *)cookediov->base)[bytesavail] = '\0';
> - I think this is intended to null terminate the name,
>   since it comes right after the memcpy() of the file name.
> However, bytesavail is the value returned by GENERIC_DIRSIZ(),
> which means [bytesavail] after "cookediov->base" would be the
> first byte after the "struct dirent" (including the space for
> null termination and padding.
> 
> If I'm correct, I think this line can be replaced by:
>         de->d_name[fudge->namelen] = '\0';
> which would be the byte after the name in the structure.
> 
> Also, although I think the first argument to the memcpy() call
> just above this is correct, it is complex/convoluted.
> Wouldn't just writing "memcpy(de->d_name, ..." make it
> more readable?
> 
> Anyone out there familiar with fuse able to look at/test this?

No, I am not familiar with fuse.  Still, I think you are right.
OTOH, it is probably very rare to result in the actual override
of the last byte after the buffer, since dirents have to fill the
buffer to the last byte.

One additional note. The getdirentries(2) specifies that the name must
be null-terminated. But sys/dirent.h comment claims that the whole
padding must be zeroed. I did not tracked the source of the buffer in
fuse_internal_readdir(), so my question is whether the buffer is zeroed
before filled. If not, padding must be cleared.


More information about the freebsd-fs mailing list