From 8650614c32c4dc5e8754b7bf4c84278551cff419 Mon Sep 17 00:00:00 2001 From: Rahat Mahmood Date: Fri, 12 Nov 2021 17:31:23 -0800 Subject: [PATCH] Shift buffer correctly when unmarshalling FUSE dirents. PiperOrigin-RevId: 409547679 --- pkg/abi/linux/fuse.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/pkg/abi/linux/fuse.go b/pkg/abi/linux/fuse.go index 1112dadd6..0147077a3 100644 --- a/pkg/abi/linux/fuse.go +++ b/pkg/abi/linux/fuse.go @@ -782,21 +782,31 @@ func (r *FUSEDirent) SizeBytes() int { return (dataSize + (FUSE_DIRENT_ALIGN - 1)) & ^(FUSE_DIRENT_ALIGN - 1) } +// shiftNextDirent advances buf to the start of the next dirent, per +// FUSE ABI. buf should begin at the start of a dirent. +func (r *FUSEDirent) shiftNextDirent(buf []byte) []byte { + nextOff := r.SizeBytes() + if nextOff > len(buf) { // Handle overflow. + return buf[len(buf):] + } + return buf[nextOff:] +} + // UnmarshalBytes deserializes FUSEDirent from the src buffer. func (r *FUSEDirent) UnmarshalBytes(src []byte) []byte { - src = r.Meta.UnmarshalBytes(src) + srcP := r.Meta.UnmarshalBytes(src) if r.Meta.NameLen > FUSE_NAME_MAX { // The name is too long and therefore invalid. We don't // need to unmarshal the name since it'll be thrown away. - return src + return r.shiftNextDirent(src) } buf := make([]byte, r.Meta.NameLen) name := primitive.ByteSlice(buf) - name.UnmarshalBytes(src[:r.Meta.NameLen]) + name.UnmarshalBytes(srcP[:r.Meta.NameLen]) r.Name = string(name) - return src[r.Meta.NameLen:] + return r.shiftNextDirent(src) } // FATTR_* consts are the attribute flags defined in include/uapi/linux/fuse.h.