Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

stack size can exceed MaxStackSize #3300

Closed
dusmart opened this issue Jun 7, 2024 · 3 comments · Fixed by #3301
Closed

stack size can exceed MaxStackSize #3300

dusmart opened this issue Jun 7, 2024 · 3 comments · Fixed by #3301
Labels
Bug Used to tag confirmed bugs Critical Issues (bugs) that need to be fixed ASAP

Comments

@dusmart
Copy link

dusmart commented Jun 7, 2024

Describe the bug

You can make a large object larger than the limit MaxStackSize.

To Reproduce

invoke 0x179ab5d297fd34ecd48643894242fc3527f42853 bingo [{"type":"Integer","value":2000}]

AdAHEcAfDAViaW5nbwwUUyj0JzX8QkKJQ4bU7DT9l9K1mhdBYn1bUg==

Expected behavior

FAULT

Screenshots

Screenshot 2024-06-07 at 13 06 17

Platform:

  • Version 3.7.4

(Optional) Additional context

I believe that Runtime.Notify should be blamed.

@dusmart
Copy link
Author

dusmart commented Jun 7, 2024

It's very dangerous if someone can combine this with some O(n2) DoS attacks like what have been shown by @vang1ong7ang in the past.

@vang1ong7ang
Copy link
Contributor

it breaks a fundamental assumption of neovm and it should be fixed soon and published

@Jim8y Jim8y linked a pull request Jun 7, 2024 that will close this issue
14 tasks
@shargon shargon added Bug Used to tag confirmed bugs Critical Issues (bugs) that need to be fixed ASAP labels Jun 7, 2024
@dusmart
Copy link
Author

dusmart commented Jun 7, 2024

With careful construction, it can theoretically generate an array containing at least 10 million data which may cost ~10 hours. Within 20 GAS.

invoke 0x179ab5d297fd34ecd48643894242fc3527f42853 maxSize  [{"type":"Integer","value":100000}]

// notice that each iteration will generate 100 new items to the result array

AnnaShaleva added a commit to nspcc-dev/neo-go that referenced this issue Jun 11, 2024
This test ensures that NeoGo node doesn't have the DeepCopy problem
described in neo-project/neo#3300 and fixed in
neo-project/neo#3301. This problem leads to the
fact that Notifications items are not being properly refcounted by C#
node which leads to possibility to build an enormously large object on
stack. Go node doesn't have this problem.

The reason (at least, as I understand it) is in the fact that C# node
performs objects refcounting inside the DeepCopy even if the object
itself is not yet on stack. I.e. System.Runtime.Notify handler
immediately adds references to the notification argumetns inside
DeepCopy:
https://github.com/neo-project/neo/blob/b1d27f0189861167b8005a7e40e6d8500fb48cc4/src/Neo.VM/Types/Array.cs#L108
https://github.com/neo-project/neo/blob/b1d27f0189861167b8005a7e40e6d8500fb48cc4/src/Neo.VM/Types/Array.cs#L75

Whereas Go node just performs the honest DeepCopy without references counting:
https://github.com/nspcc-dev/neo-go/blob/b66cea5cccbcc8446312b012e29aaf2d1837430a/pkg/vm/stackitem/item.go#L1223

Going further, C# node clears refs for notification arguments (for array
and underlying array items). System.Runtime.GetNotifications pushes the
notificaiton args array back on stack and increments counter only for
the external array, not for its arguments. Which results in negative
refcounter once notificaiton is removed from the stack. The fix itself
(https://github.com/Jim8y/neo/blob/f471c0542ddd8f527478fbdcda76a3ab9194b958/src/Neo/SmartContract/NotifyEventArgs.cs#L84)
doesn't need to be ported to NeoGo because Go node adds object to the
refcounter only at the moment when it's being pushed to stack by
System.Runtime.GetNotifications handler. This object is treated as new
object since it was deepcopied earlier by System.Runtime.Notify handler:
https://github.com/nspcc-dev/neo-go/blob/b66cea5cccbcc8446312b012e29aaf2d1837430a/pkg/vm/stack.go#L178.

Thus, no functoinal changes from the NeoGo side. And we won't
intentionally break our node to follow C# pre-Domovoi invalid behaviour.

Close #3484, close #3482.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Bug Used to tag confirmed bugs Critical Issues (bugs) that need to be fixed ASAP
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants