diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2022-07-10 23:49:07 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2022-07-11 00:44:30 -0600 |
commit | ad9ac6d07ce1819260c2b7f090fd4fe742c80d9f (patch) | |
tree | ab6a607ea8575382c978f07de943ccf6c077de7c /lib/btrfs/btrfsitem/item_dir.go | |
parent | 41ef03aabf8d6db4f926480fc5ddfec014e342d3 (diff) |
Fuzz btrfsitem, and by consequence improve binstruct errors
Diffstat (limited to 'lib/btrfs/btrfsitem/item_dir.go')
-rw-r--r-- | lib/btrfs/btrfsitem/item_dir.go | 50 |
1 files changed, 17 insertions, 33 deletions
diff --git a/lib/btrfs/btrfsitem/item_dir.go b/lib/btrfs/btrfsitem/item_dir.go index 859cd14..2fb2d41 100644 --- a/lib/btrfs/btrfsitem/item_dir.go +++ b/lib/btrfs/btrfsitem/item_dir.go @@ -9,47 +9,21 @@ import ( "hash/crc32" "git.lukeshu.com/btrfs-progs-ng/lib/binstruct" + "git.lukeshu.com/btrfs-progs-ng/lib/binstruct/binutil" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/internal" ) -// key.objectid = inode of directory containing this entry -// key.offset = -// for DIR_ITEM and XATTR_ITEM = NameHash(name) -// for DIR_INDEX = index id in the directory (starting at 2, because "." and "..") -type DirEntries []DirEntry // DIR_ITEM=84 DIR_INDEX=96 XATTR_ITEM=24 +const MaxNameLen = 255 func NameHash(dat []byte) uint64 { return uint64(^crc32.Update(1, crc32.MakeTable(crc32.Castagnoli), dat)) } -func (o *DirEntries) UnmarshalBinary(dat []byte) (int, error) { - *o = nil - n := 0 - for n < len(dat) { - var ref DirEntry - _n, err := binstruct.Unmarshal(dat, &ref) - n += _n - if err != nil { - return n, err - } - *o = append(*o, ref) - } - return n, nil -} - -func (o DirEntries) MarshalBinary() ([]byte, error) { - var ret []byte - for _, ref := range o { - bs, err := binstruct.Marshal(ref) - ret = append(ret, bs...) - if err != nil { - return ret, err - } - } - return ret, nil -} - -type DirEntry struct { +// key.objectid = inode of directory containing this entry +// key.offset = +// for DIR_ITEM and XATTR_ITEM = NameHash(name) +// for DIR_INDEX = index id in the directory (starting at 2, because "." and "..") +type DirEntry struct { // DIR_ITEM=84 DIR_INDEX=96 XATTR_ITEM=24 Location internal.Key `bin:"off=0x0, siz=0x11"` TransID int64 `bin:"off=0x11, siz=8"` DataLen uint16 `bin:"off=0x19, siz=2"` // [ignored-when-writing] @@ -61,10 +35,20 @@ type DirEntry struct { } func (o *DirEntry) UnmarshalBinary(dat []byte) (int, error) { + if err := binutil.NeedNBytes(dat, 0x1e); err != nil { + return 0, err + } n, err := binstruct.UnmarshalWithoutInterface(dat, o) if err != nil { return n, err } + if o.NameLen > MaxNameLen { + return 0, fmt.Errorf("maximum name len is %v, but .NameLen=%v", + MaxNameLen, o.NameLen) + } + if err := binutil.NeedNBytes(dat, 0x1e+int(o.DataLen)+int(o.NameLen)); err != nil { + return 0, err + } o.Data = dat[n : n+int(o.DataLen)] n += int(o.DataLen) o.Name = dat[n : n+int(o.NameLen)] |