Skip to content

Commit 7f76bea

Browse files
authored
Add some IL validity checks to interpreter (#120682)
This change adds validity checks that calls BADCODE around some EH stuff and varargs calls and also replaces assert(0) in the primitive type conversion operations with BADCODE calls for the cases when invalid type conversions are requested.
1 parent 8aad2ab commit 7f76bea

File tree

1 file changed

+78
-33
lines changed

1 file changed

+78
-33
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 78 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,31 @@ int32_t *InterpCompiler::EmitBBCode(int32_t *ip, InterpBasicBlock *bb, TArray<Re
954954
return ip;
955955
}
956956

957+
void ValidateEmittedSequenceTermination(InterpInst *lastIns)
958+
{
959+
if (lastIns == NULL)
960+
return;
961+
962+
if (InterpOpIsUncondBranch(lastIns->opcode) ||
963+
(lastIns->opcode == INTOP_RET) ||
964+
(lastIns->opcode == INTOP_RET_VOID) ||
965+
(lastIns->opcode == INTOP_RET_VT) ||
966+
(lastIns->opcode == INTOP_THROW) ||
967+
(lastIns->opcode == INTOP_THROW_PNSE) ||
968+
(lastIns->opcode == INTOP_CALL_TAIL) ||
969+
(lastIns->opcode == INTOP_CALLI_TAIL) ||
970+
(lastIns->opcode == INTOP_CALLVIRT_TAIL) ||
971+
(lastIns->opcode == INTOP_RETHROW) ||
972+
(lastIns->opcode == INTOP_LEAVE_FILTER) ||
973+
(lastIns->opcode == INTOP_LEAVE_CATCH))
974+
{
975+
// Valid terminating instruction
976+
return;
977+
}
978+
979+
BADCODE("Emitted code sequence does not end with a terminating instruction");
980+
}
981+
957982
void InterpCompiler::EmitCode()
958983
{
959984
TArray<Reloc*, MemPoolAllocator> relocs(GetMemPoolAllocator());
@@ -999,14 +1024,19 @@ void InterpCompiler::EmitCode()
9991024
do
10001025
{
10011026
emittedBlock = false;
1027+
InterpInst *lastEmittedIns = NULL;
10021028
for (InterpBasicBlock *bb = m_pEntryBB; bb != NULL; bb = bb->pNextBB)
10031029
{
10041030
if (bb->overlappingEHClauseCount == clauseDepth)
10051031
{
10061032
ip = EmitBBCode(ip, bb, &relocs);
1033+
lastEmittedIns = bb->pLastIns;
10071034
emittedBlock = true;
10081035
}
10091036
}
1037+
1038+
ValidateEmittedSequenceTermination(lastEmittedIns);
1039+
10101040
clauseDepth++;
10111041
}
10121042
while (emittedBlock);
@@ -3843,6 +3873,10 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
38433873
resolvedCallToken.tokenScope = m_methodInfo->scope;
38443874

38453875
m_compHnd->findSig(m_methodInfo->scope, token, METHOD_BEING_COMPILED_CONTEXT(), &callInfo.sig);
3876+
if (callInfo.sig.isVarArg())
3877+
{
3878+
BADCODE("Vararg methods are not supported in interpreted code");
3879+
}
38463880

38473881
callIFunctionPointerVar = m_pStackPointer[-1].var;
38483882
m_pStackPointer--;
@@ -3858,6 +3892,11 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
38583892

38593893
m_compHnd->getCallInfo(&resolvedCallToken, pConstrainedToken, m_methodInfo->ftn, flags, &callInfo);
38603894

3895+
if (callInfo.sig.isVarArg())
3896+
{
3897+
BADCODE("Vararg methods are not supported in interpreted code");
3898+
}
3899+
38613900
// Inject call to callsite callout helper
38623901
EmitCallsiteCallout(callInfo.accessAllowed, &callInfo.callsiteCalloutHelper);
38633902

@@ -5321,7 +5360,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
53215360
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_U1_I8);
53225361
break;
53235362
default:
5324-
assert(0);
5363+
BADCODE("conv.u1 operand must be R4, R8, I4 or I8");
53255364
}
53265365
m_ip++;
53275366
break;
@@ -5342,7 +5381,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
53425381
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_I1_I8);
53435382
break;
53445383
default:
5345-
assert(0);
5384+
BADCODE("conv.i1 operand must be R4, R8, I4 or I8");
53465385
}
53475386
m_ip++;
53485387
break;
@@ -5363,7 +5402,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
53635402
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_U2_I8);
53645403
break;
53655404
default:
5366-
assert(0);
5405+
BADCODE("conv.u2 operand must be R4, R8, I4 or I8");
53675406
}
53685407
m_ip++;
53695408
break;
@@ -5384,7 +5423,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
53845423
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_I2_I8);
53855424
break;
53865425
default:
5387-
assert(0);
5426+
BADCODE("conv.i2 operand must be R4, R8, I4 or I8");
53885427
}
53895428
m_ip++;
53905429
break;
@@ -5421,7 +5460,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
54215460
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_MOV_8);
54225461
break;
54235462
default:
5424-
assert(0);
5463+
BADCODE("conv.u operand must be R4, R8, I4, I8, O or ByRef");
54255464
}
54265465
m_ip++;
54275466
break;
@@ -5458,7 +5497,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
54585497
#endif
54595498
break;
54605499
default:
5461-
assert(0);
5500+
BADCODE("conv.i operand must be R4, R8, I4, I8, O or ByRef");
54625501
}
54635502
m_ip++;
54645503
break;
@@ -5481,7 +5520,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
54815520
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_MOV_P);
54825521
break;
54835522
default:
5484-
assert(0);
5523+
BADCODE("conv.u4 operand must be R4, R8, I4, I8, O or ByRef");
54855524
}
54865525
m_ip++;
54875526
break;
@@ -5504,7 +5543,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
55045543
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_MOV_P);
55055544
break;
55065545
default:
5507-
assert(0);
5546+
BADCODE("conv.i4 operand must be R4, R8, I4, I8, O or ByRef");
55085547
}
55095548
m_ip++;
55105549
break;
@@ -5532,7 +5571,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
55325571
#endif
55335572
break;
55345573
default:
5535-
assert(0);
5574+
BADCODE("conv.i8 operand must be R4, R8, I4, I8, O or ByRef");
55365575
}
55375576
m_ip++;
55385577
break;
@@ -5552,7 +5591,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
55525591
case StackTypeR4:
55535592
break;
55545593
default:
5555-
assert(0);
5594+
BADCODE("conv.r4 operand must be R4, R8, I4 or I8");
55565595
}
55575596
m_ip++;
55585597
break;
@@ -5572,7 +5611,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
55725611
case StackTypeR8:
55735612
break;
55745613
default:
5575-
assert(0);
5614+
BADCODE("conv.r8 operand must be R4, R8, I4 or I8");
55765615
}
55775616
m_ip++;
55785617
break;
@@ -5599,7 +5638,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
55995638
#endif
56005639
break;
56015640
default:
5602-
assert(0);
5641+
BADCODE("conv.u8 operand must be R4, R8, I4, I8, O or ByRef");
56035642
}
56045643
m_ip++;
56055644
break;
@@ -5618,7 +5657,8 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
56185657
EmitConv(m_pStackPointer - 1, StackTypeR8, INTOP_CONV_R_UN_I4);
56195658
break;
56205659
default:
5621-
assert(0);
5660+
BADCODE("conv.r8 operand must be R4, R8, I4 or I8");
5661+
break;
56225662
}
56235663
m_ip++;
56245664
break;
@@ -5639,7 +5679,8 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
56395679
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I1_I8);
56405680
break;
56415681
default:
5642-
assert(0);
5682+
BADCODE("conv.ovf.i1 operand must be R4, R8, I4 or I8");
5683+
break;
56435684
}
56445685
m_ip++;
56455686
break;
@@ -5660,7 +5701,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
56605701
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U1_I8);
56615702
break;
56625703
default:
5663-
assert(0);
5704+
BADCODE("conv.ovf.u1 operand must be R4, R8, I4 or I8");
56645705
}
56655706
m_ip++;
56665707
break;
@@ -5681,7 +5722,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
56815722
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I2_I8);
56825723
break;
56835724
default:
5684-
assert(0);
5725+
BADCODE("conv.ovf.i2 operand must be R4, R8, I4 or I8");
56855726
}
56865727
m_ip++;
56875728
break;
@@ -5702,7 +5743,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
57025743
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U2_I8);
57035744
break;
57045745
default:
5705-
assert(0);
5746+
BADCODE("conv.ovf.u2 operand must be R4, R8, I4 or I8");
57065747
}
57075748
m_ip++;
57085749
break;
@@ -5722,7 +5763,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
57225763
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I4_I8);
57235764
break;
57245765
default:
5725-
assert(0);
5766+
BADCODE("conv.ovf.i4 operand must be R4, R8, I4 or I8");
57265767
}
57275768
m_ip++;
57285769
break;
@@ -5743,7 +5784,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
57435784
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U4_I8);
57445785
break;
57455786
default:
5746-
assert(0);
5787+
BADCODE("conv.ovf.u4 operand must be R4, R8, I4 or I8");
57475788
}
57485789
m_ip++;
57495790
break;
@@ -5763,7 +5804,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
57635804
case StackTypeI8:
57645805
break;
57655806
default:
5766-
assert(0);
5807+
BADCODE("conv.ovf.i8 operand must be R4, R8, I4 or I8");
57675808
}
57685809
m_ip++;
57695810
break;
@@ -5784,7 +5825,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
57845825
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_U8_I8);
57855826
break;
57865827
default:
5787-
assert(0);
5828+
BADCODE("conv.ovf.u8 operand must be R4, R8, I4 or I8");
57885829
}
57895830
m_ip++;
57905831
break;
@@ -5821,7 +5862,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
58215862
#endif
58225863
break;
58235864
default:
5824-
assert(0);
5865+
BADCODE("conv.ovf.i operand must be R4, R8, I4, I8, O or ByRef");
58255866
}
58265867
m_ip++;
58275868
break;
@@ -5858,7 +5899,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
58585899
#endif
58595900
break;
58605901
default:
5861-
assert(0);
5902+
BADCODE("conv.ovf.u operand must be R4, R8, I4, I8, O or ByRef");
58625903
}
58635904
m_ip++;
58645905
break;
@@ -5882,7 +5923,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
58825923
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I1_U8);
58835924
break;
58845925
default:
5885-
assert(0);
5926+
BADCODE("conv.ovf.i1 operand must be R4, R8, I4 or I8");
58865927
}
58875928
m_ip++;
58885929
break;
@@ -5903,7 +5944,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
59035944
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U1_U8);
59045945
break;
59055946
default:
5906-
assert(0);
5947+
BADCODE("conv.ovf.u1 operand must be R4, R8, I4 or I8");
59075948
}
59085949
m_ip++;
59095950
break;
@@ -5924,7 +5965,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
59245965
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I2_U8);
59255966
break;
59265967
default:
5927-
assert(0);
5968+
BADCODE("conv.ovf.i2 operand must be R4, R8, I4 or I8");
59285969
}
59295970
m_ip++;
59305971
break;
@@ -5945,7 +5986,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
59455986
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U2_U8);
59465987
break;
59475988
default:
5948-
assert(0);
5989+
BADCODE("conv.ovf.u2 operand must be R4, R8, I4 or I8");
59495990
}
59505991
m_ip++;
59515992
break;
@@ -5966,7 +6007,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
59666007
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I4_U8);
59676008
break;
59686009
default:
5969-
assert(0);
6010+
BADCODE("conv.ovf.i4 operand must be R4, R8, I4 or I8");
59706011
}
59716012
m_ip++;
59726013
break;
@@ -5986,7 +6027,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
59866027
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U4_U8);
59876028
break;
59886029
default:
5989-
assert(0);
6030+
BADCODE("conv.ovf.u4 operand must be R4, R8, I4 or I8");
59906031
}
59916032
m_ip++;
59926033
break;
@@ -6007,7 +6048,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
60076048
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_I8_U8);
60086049
break;
60096050
default:
6010-
assert(0);
6051+
BADCODE("conv.ovf.i8 operand must be R4, R8, I4 or I8");
60116052
}
60126053
m_ip++;
60136054
break;
@@ -6027,7 +6068,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
60276068
case StackTypeI8:
60286069
break;
60296070
default:
6030-
assert(0);
6071+
BADCODE("conv.ovf.u8 operand must be R4, R8, I4 or I8");
60316072
}
60326073
m_ip++;
60336074
break;
@@ -6064,7 +6105,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
60646105
#endif
60656106
break;
60666107
default:
6067-
assert(0);
6108+
BADCODE("conv.ovf.i operand must be R4, R8, I4, I8, O or ByRef");
60686109
}
60696110
m_ip++;
60706111
break;
@@ -6099,7 +6140,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
60996140
#endif
61006141
break;
61016142
default:
6102-
assert(0);
6143+
BADCODE("conv.ovf.u operand must be R4, R8, I4, I8, O or ByRef");
61036144
}
61046145
m_ip++;
61056146
break;
@@ -7058,6 +7099,10 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
70587099

70597100
case CEE_ENDFINALLY:
70607101
{
7102+
if (m_pCBB->clauseType != BBClauseFinally)
7103+
{
7104+
BADCODE("endfinally not in a finally block");
7105+
}
70617106
AddIns(INTOP_RET_VOID);
70627107
m_ip++;
70637108
linkBBlocks = false;

0 commit comments

Comments
 (0)