From: "Roman Kagan" <rkagan@virtuozzo.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>
Subject: static data in dxe_runtime modules
Date: Thu, 1 Aug 2019 19:16:24 +0000 [thread overview]
Message-ID: <20190801191621.GB14235@rkaganb.sw.ru> (raw)
I'm trying to come up with a solution to the problem that OpenSSL
internally uses static variables ("per-thread" in no-threads config) to
store pointers, which remain unadjusted upon SetVirtualAddressMap and
cause the guest OS crash.
More specifically, trying to set a signed variable leads to the
following call chain:
VariableServiceSetVariable
ProcessVarWithPk
VerifyTimeBasedPayloadAndUpdate
Pkcs7GetSigners
ASN1_item_d2i
asn1_item_embed_d2i
asn1_template_ex_d2i
asn1_template_noexp_d2i
asn1_item_embed_d2i
asn1_template_ex_d2i
asn1_template_noexp_d2i
asn1_item_embed_d2i
asn1_template_ex_d2i
asn1_template_noexp_d2i
asn1_item_embed_d2i
pubkey_cb
ERR_set_mark
ERR_get_state
The latter performs one-time initialization if needed, and then returns
a pointer maintained in a static array using CRYPTO_THREAD_get_local().
If a signed variable is set before SetVirtualAddressMap and (another
one) after it, the pointer is initialized while in the old mapping and
dereferenced while in the new one, crashing the OS.
The real-world reproducer: install Windows Server 2016 in a VM with
OVMF, shut it down, replace the varstore with a fresh template copy,
boot Windows, try to update, say, "dbx" from within Windows => BSOD.
The reason is that the Windows bootloader stores a secure variable
"CurrentPolicy" if it isn't there, triggering the above callchain while
still in identity mapping.
(This problem isn't widely noticed because during the installation the
bootloader stores CurrentPolicy, but the OS is soon rebooted, before it
attempts to update dbx; upon that CurrentPolicy remains in the varstore
and on further boots the bootloader skips setting it.)
What would be the best way to fix it?
One option is to audit OpenSSL and make sure it either doesn't put
pointers into static storage or properly cleans them up (and call the
cleanup function in RuntimeCryptLibAddressChangeEvent); then assume the
rest of EDKII code is safe in this regard.
Another is to assume that no static data in dxe_runtime modules should
survive SetVirtualAddressMap, and thus make
PeCoffLoaderRelocateImageForRuntime reinitialize the modules from
scratch instead of re-applying the relocations only.
I must admit I don't yet quite understand the full consequences of
either option. Perhaps there are better ones.
Any suggestion is appreciated.
Thanks,
Roman.
next reply other threads:[~2019-08-01 19:16 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-01 19:16 Roman Kagan [this message]
2019-08-02 23:54 ` [edk2-devel] static data in dxe_runtime modules Andrew Fish
2019-08-03 2:03 ` Laszlo Ersek
2019-08-05 10:18 ` Roman Kagan
2019-08-07 17:29 ` Laszlo Ersek
2019-08-07 17:41 ` Andrew Fish
2019-08-08 17:39 ` Laszlo Ersek
2019-08-09 16:07 ` Roman Kagan
[not found] ` <15B94CD6CF07DEE2.13696@groups.io>
2019-08-12 18:43 ` Roman Kagan
2019-08-13 9:10 ` Laszlo Ersek
2019-08-13 11:23 ` Roman Kagan
2019-08-14 15:16 ` Laszlo Ersek
2019-08-14 16:26 ` Andrew Fish
2019-08-16 15:22 ` Laszlo Ersek
2019-08-16 17:00 ` Roman Kagan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190801191621.GB14235@rkaganb.sw.ru \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox