Commit aef087f "[LibOS] Move trusted and allowed files logic to LibOS" moved all handling of allowed/trusted files into the LibOS layer. This led to a subtle bug: if sys.enable_extra_runtime_domain_names_conf is set to true, Gramine will generate /etc/resolv.conf from scratch, ignoring whether the file was marked as allowed or trusted. At the same time, Gramine still needs to look up this file, and as part of this look up Gramine will check whether it was marked as allowed or trusted.
The bug is benign if the file was not marked as allowed or trusted at all: Gramine's lookup logic will return a perfectly valid ENOENT code. The bug is also benign if the file was marked as allowed: the file will be found on the host but ignored and immediately replaced with a generated version. The bug manifests itself, however, if the file was marked as trusted and its hash does not correspond to the one specified in the manifest. In such case, Gramine's lookup logic detects that the file is trusted and that its hashes do not match, and Gramine fails on startup.
This bug is subtle because it needs three things to happen: (1) /etc/resolv.conf ends up in sgx.trusted_files, (2) the hashes in the host environment and in the manifest do not match, (3) the manifest contains sys.enable_extra_runtime_domain_names_conf = true. The first prerequisite may happen if the user puts a blanket /etc/ dir in the manifest. The second prerequisite may happen e.g. in Docker containers where /etc/resolv.conf is re-generated by Docker every time.
This commit adds the corner case of excluding /etc/resolv.conf from allowed/trusted file checks, if the manifest contains sys.enable_extra_runtime_domain_names_conf = true. This silent exclusion is in line with the current behavior of this manifest option.
Description of the changes
Commit aef087f "[LibOS] Move trusted and allowed files logic to LibOS" moved all handling of allowed/trusted files into the LibOS layer. This led to a subtle bug: if
sys.enable_extra_runtime_domain_names_conf
is set to true, Gramine will generate/etc/resolv.conf
from scratch, ignoring whether the file was marked as allowed or trusted. At the same time, Gramine still needs to look up this file, and as part of this look up Gramine will check whether it was marked as allowed or trusted.The bug is benign if the file was not marked as allowed or trusted at all: Gramine's lookup logic will return a perfectly valid ENOENT code. The bug is also benign if the file was marked as allowed: the file will be found on the host but ignored and immediately replaced with a generated version. The bug manifests itself, however, if the file was marked as trusted and its hash does not correspond to the one specified in the manifest. In such case, Gramine's lookup logic detects that the file is trusted and that its hashes do not match, and Gramine fails on startup.
This bug is subtle because it needs three things to happen: (1)
/etc/resolv.conf
ends up insgx.trusted_files
, (2) the hashes in the host environment and in the manifest do not match, (3) the manifest containssys.enable_extra_runtime_domain_names_conf = true
. The first prerequisite may happen if the user puts a blanket/etc/
dir in the manifest. The second prerequisite may happen e.g. in Docker containers where/etc/resolv.conf
is re-generated by Docker every time.This commit adds the corner case of excluding
/etc/resolv.conf
from allowed/trusted file checks, if the manifest containssys.enable_extra_runtime_domain_names_conf = true
. This silent exclusion is in line with the current behavior of this manifest option.Code references:
Reported by @anjalirai-intel and @jinengandhi-intel on Curated Apps/GSC. Kudos to them.
Fixes #2014
How to test this PR?
Not trivial to reproduce.Updated one LibOS regression test to check this corner case (without this PR, the test fails on startup).This change is