DRAFT: migtd: harden EnableLogArea handling (reserved validation + gated set_max_level)#886
Draft
sgrams wants to merge 1 commit into
Draft
DRAFT: migtd: harden EnableLogArea handling (reserved validation + gated set_max_level)#886sgrams wants to merge 1 commit into
sgrams wants to merge 1 commit into
Conversation
…_max_level) GHCI 1.5 v6 Table 3-50 specifies the EnableLogArea request as a 16-byte payload: mig_request_id (u64) | log_max_level (u8) | reserved[7] (MUST be 0). Several issues existed in the handler: 1. log::set_max_level was called unconditionally in both transport handlers (main.rs and cvmemu.rs), even when enable_logarea() had rejected the request with InvalidParameter. A malformed VMM request (e.g. log_max_level = 0xFF) would leave LOGGING_INFORMATION .maxloglevel at 0 (Off) but still flip the crate-global log gate to Trace via the 5 | _ arm of u8_to_levelfilter, so the two filters disagreed. 2. EnableLogAreaInfo.reserved[7] was never validated. PR intel#882 added reserved-must-be-zero checks for Prepare Migration / Prepare Rebinding payloads; the same hardening was missing for op 4. 3. The error-path log message in enable_logarea() incorrectly reused the success message text ("Logging has been enabled with MaxLevel") even when rejecting an invalid level. Fixes: - Replace impl_read_from_bytes!(EnableLogAreaInfo) with a custom read_from_bytes that rejects non-zero reserved bytes with InvalidParameter (matching the PR intel#882 pattern). The now-unused impl_read_from_bytes! macro is removed. - Move the log::set_max_level call inside enable_logarea() so it only runs on the validated success path, after the u8_to_loglevel check. The crate-global gate now always matches the per-MigTD gate. - Drop the duplicated log::set_max_level + 'Setting log level to' info! from main.rs and cvmemu.rs handlers, and drop the now-unused u8_to_levelfilter import from cvmemu.rs. - Correct the error-path log message in enable_logarea() to say 'rejected request with invalid MaxLogLevel'. Signed-off-by: Stanislaw Grams <stanislaw.grams@intel.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hardens the GHCI 1.5 v6
EnableLogArea(operation4) request path. Three correctness issues are addressed in a single PR.Closes #664
Spec reference
GHCI 1.5 v6 Table 3-50 defines the
EnableLogArearequest payload as a 16-byte struct:mig_request_idlog_max_levellog_max_levelmust be one of1=Error,2=Warn,3=Info,4=Debug,5=Trace. The VMM is the producer; MigTD must validate and propagate.Issues fixed
log::set_max_levelwas called unconditionally in both transport handlers (src/migtd/src/bin/migtd/main.rsandsrc/migtd/src/bin/migtd/cvmemu.rs), even whenenable_logarea()had rejected the request withInvalidParameter. A malformed VMM request (e.g.log_max_level = 0xFF) would leaveLOGGING_INFORMATION.maxloglevelat0(Off) — the structured-log gate — but still flip the crate-globallog::max_level()toTracevia the5 | _arm ofu8_to_levelfilter. The two filters disagreed.EnableLogAreaInfo.reserved[7]was never validated. PR fix(rebinding): validate all reserved bytes 10..15 #882 added "reserved must be zero" checks for the Prepare Migration / Prepare Rebinding payloads; the same hardening was missing for op 4 (EnableLogArea).The error-path log message in
enable_logarea()incorrectly reused the success message text ("Logging has been enabled with MaxLevel: …") even when rejecting an invalid level.Fixes
src/migtd/src/migration/mod.rs— Replaceimpl_read_from_bytes!(EnableLogAreaInfo)with a customread_from_bytesthat rejects non-zero reserved bytes withMigrationResult::InvalidParameter(matching the PR fix(rebinding): validate all reserved bytes 10..15 #882 pattern). The now-unusedimpl_read_from_bytes!macro is removed.src/migtd/src/migration/logging.rs— Move thelog::set_max_level(u8_to_levelfilter(log_max_level))call insideenable_logarea()so it only runs on the validated success path, after theu8_to_loglevelcheck. The crate-global gate now always matches the per-MigTDLOGGING_INFORMATION.maxloglevel. Correct the error-path log message to say"rejected request with invalid MaxLogLevel".src/migtd/src/bin/migtd/main.rsandsrc/migtd/src/bin/migtd/cvmemu.rs— Drop the duplicatedlog::set_max_leveland the preceding"Setting log level to …"info!from both handlers (now handled insideenable_logarea). Drop the now-unusedu8_to_levelfilterimport fromcvmemu.rs.Tests
All 11 pre-existing
migration::logging::test::*cases pass, includingtest_enable_logareawhich exercises both the failure-before-create_logarea path and the success path.