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

[mono][tests] Throw InvalidProgramException when ENDFILTER has invalid value type or invalid number of values #79394

Merged
merged 4 commits into from
Dec 9, 2022

Conversation

kotlarmilos
Copy link
Member

Fix for #54401

@ghost
Copy link

ghost commented Dec 8, 2022

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

Issue Details

Fix for #54401

Author: kotlarmilos
Assignees: -
Labels:

area-Codegen-Interpreter-mono

Milestone: -

@kotlarmilos kotlarmilos marked this pull request as ready for review December 8, 2022 11:45
@BrzVlad
Copy link
Member

BrzVlad commented Dec 8, 2022

The title is not really related to the code change

@@ -7576,6 +7576,12 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
case CEE_UNUSED57: ves_abort(); break;
#endif
case CEE_ENDFILTER:
td->sp--;
Copy link
Member

@BrzVlad BrzVlad Dec 8, 2022

Choose a reason for hiding this comment

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

Why are we decreasing the stack pointer once more ? You would need to update the code below.

Copy link
Member Author

Choose a reason for hiding this comment

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

I followed the same approach as in mono jit where the error is thrown:

--sp;
if ((sp != stack_start) || (sp [0]->type != STACK_I4))
UNVERIFIED;

I understood that on the top of stack is a result of filter and it should be the only value on the stack in new BB. So, if there is something else, just throw.

Copy link
Member

Choose a reason for hiding this comment

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

You are modifying the value of the stack pointer, which breaks following code, when you should only be checking what it is at that location.

Copy link
Member Author

Choose a reason for hiding this comment

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

Just to check if I got it right, sp - 1 should be equal to stack_start and sp->type should be int32?

@kotlarmilos kotlarmilos changed the title [mono][tests] Throw InvalidProgramException when a method with varargs is encountered [mono][tests] Throw InvalidProgramException when ENDFILTER has invalid value type or invalid number of values Dec 8, 2022
@@ -7576,6 +7576,11 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
case CEE_UNUSED57: ves_abort(); break;
#endif
case CEE_ENDFILTER:
if (td->sp - 1 != td->stack || td->sp->type != STACK_TYPE_I4) {
mono_error_set_generic_error (error, "System", "InvalidProgramException", "");
Copy link
Member

Choose a reason for hiding this comment

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

td->sp points to the location where a new entry is allocated, so you are accessing junk here. You either access it with td->sp [-1], or better decrement td->sp and also update accordingly the code below that adds the MINT_ENDFILTER instruction

Copy link
Member Author

Choose a reason for hiding this comment

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

If we decrement td->sp and update accordingly the code that adds the MINT_ENDFILTER instruction, how td-sp is then rebased to the top of the stack in the next instruction?

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably here?

if (new_bb->stack_height >= 0) {
if (new_bb->stack_height > 0)
memcpy (td->stack, new_bb->stack_state, new_bb->stack_height * sizeof(td->stack [0]));
td->sp = td->stack + new_bb->stack_height;
} else if (link_bblocks) {
/* This bblock is not branched to. Initialize its stack state */
init_bb_stack_state (td, new_bb);
}

Copy link
Member

Choose a reason for hiding this comment

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

Each instruction consumes some values from the top of the stack and pushes some result back. endfilter consumes one value from the top of the stack so td->sp is technically decreased by 1. In practice, it doesn't really matter since endifilter is the last instruction of the bblock, so the next bblock resets the pointer according to its stack height https://github.com/dotnet/runtime/blob/main/src/mono/mono/mini/interp/transform.c#L4603

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the explanation.

@kotlarmilos kotlarmilos merged commit 9333e46 into dotnet:main Dec 9, 2022
@kotlarmilos kotlarmilos deleted the varargs-exception branch December 9, 2022 09:29
@ghost ghost locked as resolved and limited conversation to collaborators Jan 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants