diff --git a/changelog/unreleased/decomposedfs-treesize-overflow.md b/changelog/unreleased/decomposedfs-treesize-overflow.md new file mode 100644 index 0000000000..bff762551f --- /dev/null +++ b/changelog/unreleased/decomposedfs-treesize-overflow.md @@ -0,0 +1,7 @@ +Bugfix: treesize interger overflows + +Reading the treesize was parsing the string value as a signed integer while +setting the treesize used unsigned integers this could cause failures (out of +range errors) when reading very large treesizes. + +https://github.com/cs3org/reva/pull/3963 diff --git a/pkg/storage/utils/decomposedfs/node/node.go b/pkg/storage/utils/decomposedfs/node/node.go index a2332444a5..ea86aaee29 100644 --- a/pkg/storage/utils/decomposedfs/node/node.go +++ b/pkg/storage/utils/decomposedfs/node/node.go @@ -948,11 +948,11 @@ func (n *Node) IsDisabled() bool { // GetTreeSize reads the treesize from the extended attributes func (n *Node) GetTreeSize() (treesize uint64, err error) { - s, err := n.XattrInt64(prefixes.TreesizeAttr) + s, err := n.XattrUint64(prefixes.TreesizeAttr) if err != nil { return 0, err } - return uint64(s), nil + return s, nil } // SetTreeSize writes the treesize to the extended attributes diff --git a/pkg/storage/utils/decomposedfs/node/xattrs.go b/pkg/storage/utils/decomposedfs/node/xattrs.go index 3aa1eb3d13..d8b526ccd9 100644 --- a/pkg/storage/utils/decomposedfs/node/xattrs.go +++ b/pkg/storage/utils/decomposedfs/node/xattrs.go @@ -174,3 +174,12 @@ func (n *Node) XattrInt64(key string) (int64, error) { } return strconv.ParseInt(b, 10, 64) } + +// XattrUint64 returns the uint64 representation of an attribute +func (n *Node) XattrUint64(key string) (uint64, error) { + b, err := n.XattrString(key) + if err != nil { + return 0, err + } + return strconv.ParseUint(b, 10, 64) +} diff --git a/pkg/storage/utils/decomposedfs/tree/tree.go b/pkg/storage/utils/decomposedfs/tree/tree.go index d092f52d65..5ab6d69af5 100644 --- a/pkg/storage/utils/decomposedfs/tree/tree.go +++ b/pkg/storage/utils/decomposedfs/tree/tree.go @@ -794,12 +794,17 @@ func (t *Tree) Propagate(ctx context.Context, n *node.Node, sizeDiff int64) (err } case err != nil: return err + case sizeDiff > 0: + newSize = treeSize + uint64(sizeDiff) + case uint64(-sizeDiff) > treeSize: + // The sizeDiff is larger than the current treesize. Which would result in + // a negative new treesize. Something must have gone wrong with the accounting. + // Reset the current treesize to 0. + sublog.Error().Uint64("treeSize", treeSize).Int64("sizeDiff", sizeDiff). + Msg("Error when updating treesize of parent node. Updated treesize < 0. Reestting to 0") + newSize = 0 default: - if sizeDiff > 0 { - newSize = treeSize + uint64(sizeDiff) - } else { - newSize = treeSize - uint64(-sizeDiff) - } + newSize = treeSize - uint64(-sizeDiff) } // update the tree size of the node