From dbcc43ec3e2db0d01e8d80c55040bba3cf22cb4b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 10 Jan 2023 14:31:19 +0100 Subject: [PATCH] fix: correctly handle degenerate hamts while reading data Fixes https://github.com/ipfs/go-unixfs/security/advisories/GHSA-q264-w97q-q778 --- go.mod | 2 +- go.sum | 4 ++-- hamt/hamt.go | 22 ++++++++++++++++++---- hamt/hamt_test.go | 8 +++++--- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index c22a47157..3166c6017 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ipfs/go-unixfs require ( github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a github.com/gogo/protobuf v1.3.2 - github.com/ipfs/go-bitfield v1.0.0 + github.com/ipfs/go-bitfield v1.1.0 github.com/ipfs/go-block-format v0.0.3 github.com/ipfs/go-blockservice v0.2.1 github.com/ipfs/go-cid v0.3.2 diff --git a/go.sum b/go.sum index 86c29e9b1..073853364 100644 --- a/go.sum +++ b/go.sum @@ -244,8 +244,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-bitfield v1.0.0 h1:y/XHm2GEmD9wKngheWNNCNL0pzrWXZwCdQGv1ikXknQ= -github.com/ipfs/go-bitfield v1.0.0/go.mod h1:N/UiujQy+K+ceU1EF5EkVd1TNqevLrCQMIcAEPrdtus= +github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= +github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.5.1 h1:721YAEDBnLIrvcIMkCHCdqp34hA8jwL9yKMkyJpSpco= github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/hamt/hamt.go b/hamt/hamt.go index c6cae88ea..3dc7b8a6f 100644 --- a/hamt/hamt.go +++ b/hamt/hamt.go @@ -106,12 +106,16 @@ func makeShard(ds ipld.DAGService, size int, key string, val *ipld.Link) (*Shard if err != nil { return nil, err } + childer, err := newChilder(ds, size) + if err != nil { + return nil, err + } maxpadding := fmt.Sprintf("%X", size-1) s := &Shard{ tableSizeLg2: lg2s, prefixPadStr: fmt.Sprintf("%%0%dX", len(maxpadding)), maxpadlen: len(maxpadding), - childer: newChilder(ds, size), + childer: childer, tableSize: size, dserv: ds, @@ -765,11 +769,21 @@ type childer struct { children []*Shard } -func newChilder(ds ipld.DAGService, size int) *childer { +const maximumHamtWidth = 1 << 10 // FIXME: Spec this and decide of a correct value + +func newChilder(ds ipld.DAGService, size int) (*childer, error) { + if size > maximumHamtWidth { + return nil, fmt.Errorf("hamt witdh (%d) exceed maximum allowed (%d)", size, maximumHamtWidth) + } + bf, err := bitfield.NewBitfield(size) + if err != nil { + return nil, err + } + return &childer{ dserv: ds, - bitfield: bitfield.NewBitfield(size), - } + bitfield: bf, + }, nil } func (s *childer) makeChilder(data []byte, links []*ipld.Link) *childer { diff --git a/hamt/hamt_test.go b/hamt/hamt_test.go index 150b97b90..c68e05632 100644 --- a/hamt/hamt_test.go +++ b/hamt/hamt_test.go @@ -737,8 +737,10 @@ func BenchmarkHAMTSet(b *testing.B) { } func TestHamtBadSize(t *testing.T) { - _, err := NewShard(nil, 7) - if err == nil { - t.Fatal("should have failed to construct hamt with bad size") + for _, size := range [...]int{-8, 7, 2, 1337, 1024 + 8, -3} { + _, err := NewShard(nil, size) + if err == nil { + t.Error("should have failed to construct hamt with bad size: %d", size) + } } }