Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Memory-safety annotation for inline assembly. #12620

Merged
merged 6 commits into from
Mar 7, 2022
Merged

Conversation

ekpyron
Copy link
Member

@ekpyron ekpyron commented Feb 3, 2022

We can also properly make inline assembly StructurallyDocumented, etc, but then we need to double-check that existing natspec-style comments don't cause any errors to keep this fully non-breaking.

@ekpyron ekpyron force-pushed the assemblyAnnotation branch from 62de5d3 to 4539718 Compare February 3, 2022 11:13
@chriseth
Copy link
Contributor

chriseth commented Feb 3, 2022

Can you also define what exactly memory safety means?

@ekpyron
Copy link
Member Author

ekpyron commented Feb 3, 2022

Can you also define what exactly memory safety means?

Sure, this needs extensive documentation before I undraft it :-).
Mainly pushed it already to see if it works for the external test runs. For trident it does - but ENS still fails, I'm just trying to figure out whether that's because it pulls in dependencies with assembly that I didn't patch or because of something else.

@ekpyron
Copy link
Member Author

ekpyron commented Feb 3, 2022

Eventually we should also add better reports for all of this...
Ideally, I'd report an info message whenever any variables are moved to memory and if compilation fails due to stack too deep, but could not run stack-to-memory due to inline assembly, it should properly suggest adding those annotations... Ideally even with source locations :-).

But that's a bit of a hassle, since codegen so far is not meant to report stuff like that and we may need to store the source locations somewhere, etc., so I'd keep that separate for now...

@ekpyron ekpyron force-pushed the assemblyAnnotation branch from bfd815c to a3e16d7 Compare February 3, 2022 11:59
@ekpyron ekpyron force-pushed the assemblyAnnotation branch 4 times, most recently from d177ebf to e9c8803 Compare February 3, 2022 12:24
@ethereum ethereum deleted a comment from stackenbotten Feb 3, 2022
@ethereum ethereum deleted a comment from stackenbotten Feb 3, 2022
@ethereum ethereum deleted a comment from stackenbotten Feb 3, 2022
@ethereum ethereum deleted a comment from stackenbotten Feb 3, 2022
{
if (!_assembly.documentation())
return true;
StructuredDocumentation documentation{-1, _assembly.location(), _assembly.documentation()};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The -1 node id is a bit creepy...

@ekpyron ekpyron force-pushed the assemblyAnnotation branch 4 times, most recently from 77e0d2f to 2f37409 Compare February 3, 2022 15:14
@ekpyron
Copy link
Member Author

ekpyron commented Feb 3, 2022

I just added a first rough draft for documenting this.

I'm wondering how restrictive we should define this - technically it's valid for stack-to-memory to access any memory that is known to be past the initial value of the free memory pointer...
Also we need to decide whether we want to specifically add the requirement for memory accesses to be bounded, i.e. the assumption for the redundant store eliminator (either as only ever allocating bounded amounts of memory, if we stay with only accessing allocated memory, or more freely as not accessing memory from unbounded offsets).

@ekpyron ekpyron requested a review from chriseth February 3, 2022 15:24
@ekpyron ekpyron force-pushed the assemblyAnnotation branch from 2f37409 to 3d19b07 Compare February 3, 2022 15:26
@ekpyron
Copy link
Member Author

ekpyron commented Feb 3, 2022

Test failures are just pending #12624 I think

@cameel
Copy link
Member

cameel commented Feb 3, 2022

#12624 is ready.

@ekpyron ekpyron force-pushed the assemblyAnnotation branch from 3d19b07 to d38f89a Compare February 4, 2022 13:03
Comment on lines 305 to 308
All accessed memory (read or written) was properly allocated. This can either be memory allocated by yourself
using a mechanism like the ``allocate`` function described above, or memory allocated by Solidity,
e.g. memory within the bounds of a memory array you reference. The only exception to this is the scratch space
between memory offset 0 and 64 mentioned above.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this we still need to discuss what our actual requirements should really be, so I expect this to still change - for the rest of the docs, a review would be good already, though :-).

@ekpyron ekpyron marked this pull request as ready for review February 4, 2022 13:15
@@ -3,6 +3,7 @@
Language Features:
* General: Support ``ContractName.functionName`` for ``abi.encodeCall``, in addition to external function pointers.
* General: Add equality-comparison operators for external function types.
* General: Allow annotating inline assembly as memory-safe to allow optimizations and stack limit evasion that rely on respecting Solidity's memory model.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only applies to "via ir", does it?

Copy link
Member Author

@ekpyron ekpyron Feb 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In practice at least... in principle, we could use the information for old codegen as well, but we probably won't.

Comment on lines 290 to 291
While we recommend to always respect Solidity's memory model, it is possible to use memory
in an incompatible way from inline assembly. Therefore, moving stack variables to memory and additional
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
While we recommend to always respect Solidity's memory model, it is possible to use memory
in an incompatible way from inline assembly. Therefore, moving stack variables to memory and additional
While we recommend to always respect Solidity's memory model, inline assembly allows you to use memory
in an incompatible way. Therefore, moving stack variables to memory and additional


set<string> valuesSeen;
set<string> duplicates;
for (auto const& value: values | ranges::views::filter(not_fn(&string::empty)))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the boost::split I could also split on the fly using ranges...

constexpr auto splitString = [](auto _pred) {
		return ranges::views::split_when(move(_pred)) | ranges::views::transform([](auto&& _rng){
			return string_view(&*begin(_rng), static_cast<string_view::size_type>(ranges::distance(_rng)));
		});
};
for (auto value: tagValue.content | splitString(isWhiteSpace) | ranges::views::filter(not_fn(&string_view::empty)))

But maybe that's over the top...

@ekpyron ekpyron requested a review from chriseth March 2, 2022 09:15
chriseth
chriseth previously approved these changes Mar 2, 2022
@ekpyron
Copy link
Member Author

ekpyron commented Mar 2, 2022

Updated the warnings. We should probably be clear that we can also merge the other one, before merging this, though. Although it doesn't matter as long as we manage for the same release I guess.

@ekpyron ekpyron force-pushed the assemblyAnnotation branch from d924581 to 3730c58 Compare March 2, 2022 15:37
@ekpyron ekpyron force-pushed the assemblyAnnotation branch from 3730c58 to 6b6e163 Compare March 2, 2022 15:42
}
// ----
// Warning 6269: (177-188): Unexpected NatSpec tag "after" with value "bogus-value" in inline assembly.
// Warning 6269: (177-188): Unexpected NatSpec tag "before" with value "@solidity a memory-safe-assembly b c d" in inline assembly.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #12732
But if we report the full value here, I'd say it's still ok for this purpose and we can fix it with #12732...

@Cryptomooner111

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants