-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Conversation
Tagging subscribers to this area: @BrzVlad Issue DetailsFix for #54401
|
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--; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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:
runtime/src/mono/mono/mini/method-to-ir.c
Lines 11786 to 11788 in a83c661
--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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
?
@@ -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", ""); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably here?
runtime/src/mono/mono/mini/interp/transform.c
Lines 4595 to 4602 in a83c661
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); | |
} |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation.
Fix for #54401