[vbox-dev] Question about PE loader validation

Konstantin Vlasov flint at flint-inc.ru
Wed Aug 30 00:03:58 GMT 2023


  Hi,

I'm trying to build VBox 7.0.10 from sources. While I managed to get a
successful build, it refused to start VMs due to failed validation for VMMR0.r0:

> VMMR0.r0: Grown load config (304 to 320 bytes) includes non-zero bytes:
> a8 a5 17 80 01 00 00 00 00 00 00 00 00 00 00 00


I tried to dig the sources, and found the trigger point in the file 
  src\VBox\Runtime\common\ldr\ldrPE.cpp
  (function rtldrPEValidateDirectoriesAndRememberStuff)

As far as I could understand the code, the PE loader is trying to make sure that
it "knows" the internal structures of the loaded file. In my case, the "Load
configuration directory" section was too big, and its extra bytes are non-zero,
which means they are not just padding or anything but contain some useful data.
And it means, in turn, that the known versions of the structure cannot reflect
the section contents properly. The loader considers it too risky to continue,
and returns failure. (Please, correct me if I'm wrong in this conjecture.)

I started analyzing the file, and indeed, this section in my version of VMMR0.r0
has the size of 320 bytes (I'm using VS 16.11.28), while the expected maximum
was 304 bytes; and yes, some of the extra 16 bytes are non-zeroes, as clearly
shown in the error message above. But here lies the mystery. The variable
containing the maximum supported structure size is defined as:

>         const size_t cbMaxKnown = cbExpectV12;

But why version 12? In the code, there are already definitions for the version
13 of this structure (the comment says, it was found in VS 16.11.9), and even
more, this version 13 is already being used in the validation code, only not in
cbMaxKnown.

In my case, version 13 would fit nicely. While it's still technically not big
enough (312 bytes versus my 320), if I use it, I will only have extra 8 bytes,
and all of them are zeroes. Therefore, the validation test would pass. So I
replaced cbMaxKnown value to cbExpectV13 instead of V12, compiled it, and tried.
And sure enough, VMMR0.r0 loaded successfully, the VM launched, and booted the
guest OS without issues. (I have not tested it rigorously, of course, but
still.)


So my question is, why is cbMaxKnown set to cbExpectV12 instead of cbExpectV13?

Is it simply because the Oracle build system uses old enough compiler, and is
not affected by this issue, so it was left untouched? Or are there any more
substantial reasons?


-- 
Bye.                                    With best regards,
                                        Konstantin Vlasov.



More information about the vbox-dev mailing list