Skip to content

Commit e980c65

Browse files
vladimalatkin
authored andcommitted
added range check to readBlobHeapUncached
Obfuscated assemblies can have a bogus extra reference to mscorlib which has incorrect index in Blob heap for HashValue - index value was out of range of the heap.I guess the assumption was that compiler will not try to realize the whole set of information for this AssemblyRef entry but decompiler will try to do. The problem was that F# compiler is eagerly trying to populate information about referenced assemblies for the given assembly so it crashes during the attempt to read this malformed entry. fixes dotnet/fsharp#517 closes dotnet/fsharp#519 commit 326a7fc8fe346e1ee65fad9f60b3d7b84cf18a42 Author: Vladimir Matveev <[email protected]> Date: Wed Jul 1 00:27:11 2015 -0700 added tests commit 1d8dd07e7652fd20cce3300bf7099919a1d900a2 Author: Vladimir Matveev <[email protected]> Date: Mon Jun 29 00:14:27 2015 -0700 fix incorrect condition commit 0c0c69624da25ca3453b3fc84207a86e75cb015d Author: Vladimir Matveev <[email protected]> Date: Sun Jun 28 23:30:38 2015 -0700 added range check to readBlobHeapUncached
1 parent 49bdfb0 commit e980c65

File tree

6 files changed

+73
-1
lines changed

6 files changed

+73
-1
lines changed

src/absil/ilread.fs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,7 @@ type ILReaderContext =
10491049
userStringsStreamPhysicalLoc: int32;
10501050
stringsStreamPhysicalLoc: int32;
10511051
blobsStreamPhysicalLoc: int32;
1052+
blobsStreamSize: int32;
10521053
readUserStringHeap: (int32 -> string);
10531054
memoizeString: string -> string;
10541055
readStringHeap: (int32 -> string);
@@ -1534,9 +1535,13 @@ let readStringHeapUncached ctxtH idx =
15341535
let readStringHeap ctxt idx = ctxt.readStringHeap idx
15351536
let readStringHeapOption ctxt idx = if idx = 0 then None else Some (readStringHeap ctxt idx)
15361537

1538+
let emptyByteArray: byte[] = [||]
15371539
let readBlobHeapUncached ctxtH idx =
15381540
let ctxt = getHole ctxtH
1539-
seekReadBlob ctxt.is (ctxt.blobsStreamPhysicalLoc + idx)
1541+
// valid index lies in range [1..streamSize)
1542+
// NOTE: idx cannot be 0 - Blob\String heap has first empty element that is one byte 0
1543+
if idx <= 0 || idx >= ctxt.blobsStreamSize then emptyByteArray
1544+
else seekReadBlob ctxt.is (ctxt.blobsStreamPhysicalLoc + idx)
15401545
let readBlobHeap ctxt idx = ctxt.readBlobHeap idx
15411546
let readBlobHeapOption ctxt idx = if idx = 0 then None else Some (readBlobHeap ctxt idx)
15421547

@@ -3973,6 +3978,7 @@ let rec genOpenBinaryReader infile is opts =
39733978
userStringsStreamPhysicalLoc = userStringsStreamPhysicalLoc;
39743979
stringsStreamPhysicalLoc = stringsStreamPhysicalLoc;
39753980
blobsStreamPhysicalLoc = blobsStreamPhysicalLoc;
3981+
blobsStreamSize = blobsStreamSize;
39763982
memoizeString = Tables.memoize id;
39773983
readUserStringHeap = cacheUserStringHeap (readUserStringHeapUncached ctxtH);
39783984
readStringHeap = cacheStringHeap (readStringHeapUncached ctxtH);

tests/fsharp/core/ilread/Library.dll

4 KB
Binary file not shown.

tests/fsharp/core/ilread/build.bat

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@if "%_echo%"=="" echo off
2+
3+
setlocal
4+
REM Configure the sample, i.e. where to find the F# compiler and C# compiler.
5+
if EXIST build.ok DEL /f /q build.ok
6+
7+
call %~d0%~p0..\..\..\config.bat
8+
@if ERRORLEVEL 1 goto Error
9+
10+
if NOT "%FSC:NOTAVAIL=X%" == "%FSC%" (
11+
REM Skipping test for FSI.EXE
12+
goto Skip
13+
)
14+
15+
"%FSC%" %fsc_flags% /r:Library.dll /out:test.exe test.fs
16+
@if ERRORLEVEL 1 goto Error
17+
18+
"%PEVERIFY%" test.exe
19+
@if ERRORLEVEL 1 goto Error
20+
21+
:Ok
22+
echo Built fsharp %~f0 ok.
23+
echo. > build.ok
24+
endlocal
25+
exit /b 0
26+
27+
:Skip
28+
echo Skipped %~f0
29+
endlocal
30+
exit /b 0
31+
32+
33+
:Error
34+
endlocal
35+
exit /b %ERRORLEVEL%

tests/fsharp/core/ilread/run.bat

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@if "%_echo%"=="" echo off
2+
3+
setlocal
4+
dir build.ok > NUL ) || (
5+
@echo 'build.ok' not found.
6+
goto :ERROR
7+
)
8+
9+
call %~d0%~p0..\..\..\config.bat
10+
11+
%CLIX% .\test.exe
12+
if ERRORLEVEL 1 goto Error
13+
14+
:Ok
15+
echo Ran fsharp %~f0 ok.
16+
endlocal
17+
exit /b 0
18+
19+
:Error
20+
endlocal
21+
exit /b %ERRORLEVEL%
22+

tests/fsharp/core/ilread/test.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
open Library
2+
3+
[<EntryPoint>]
4+
let main _ =
5+
let cls = Class1()
6+
let len = cls.GetLength("123")
7+
printfn "%O" len
8+
if len = 3 then 0 else 1

tests/test.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Core03 fsharp\core\innerpoly
3535
Core03,Smoke fsharp\core\int32
3636
Core03 fsharp\core\internalsvisible
3737
Core03 fsharp\core\interop
38+
Core03 fsharp\core\ilread
3839
Core03 fsharp\core\lazy
3940
Core03 fsharp\core\letrec
4041
Core03,Smoke fsharp\core\libtest

0 commit comments

Comments
 (0)