Skip to content

MdeModulePkg/NvmExpressDxe: Add NVMe namespace filtering PCD#1754

Open
eeshanl wants to merge 3 commits intomicrosoft:release/202511from
eeshanl:nvme_namespace_filtering
Open

MdeModulePkg/NvmExpressDxe: Add NVMe namespace filtering PCD#1754
eeshanl wants to merge 3 commits intomicrosoft:release/202511from
eeshanl:nvme_namespace_filtering

Conversation

@eeshanl
Copy link
Copy Markdown
Contributor

@eeshanl eeshanl commented Apr 8, 2026

Description

Add PcdNvmeNamespaceFilter to control NVMe namespace enumeration.
When TRUE, only the first namespace (NSID 1) is discovered and enumerated. When FALSE (default), all namespaces are enumerated as before.

This improves security on NVMe devices with multiple namespaces.
Without filtering, UEFI enumerates all namespaces and an attacker could place malicious boot media in a secondary namespace. By restricting enumeration to only the first namespace, we ensure the system boots exclusively from the intended namespace and prevents exploitation of additional namespaces as an attack vector.

Changes:

  • NvmExpress.h: Add NVME_FIRST_NSID define
  • NvmExpress.c: Add FilteringEnabled parameter to DiscoverAllNamespaces, EnumerateNvmeDevNamespace with namespace ID check when filtering
  • NvmExpressDxe.inf: Add PcdNvmeNamespaceFilter to [Pcd] section
  • MdeModulePkg.dec: Define PcdNvmeNamespaceFilter (default FALSE)

Ref: microsoft/mu_msvm@9337285

For details on how to complete these options and their meaning refer to CONTRIBUTING.md.

  • Impacts functionality?
  • Impacts security?
  • Breaking change?
  • Includes tests?
  • Includes documentation?

How This Was Tested

Tested on:

  • OpenVMM platform where namespace filtering is required and successfully booted to OS via DDA NVMe with Namespace filtering on & off.

  • Physical platform and booted to OS with physical NVMe with Namespace filtering on & off.

  • Qemu Q35 by booting to OS via NVMe with Namespace filtering on & off:

    Modified QemuCommandBuilder.py with the following:

    elif device == "ssd" and self._architecture == QemuArchitecture.Q35:
        # Create NVMe controller with 2 namespaces for testing namespace filtering
        # NS1: boot media, NS2: empty 1GB drive
        self._args.extend([
            "-drive",
            f"file={path},format={format},if=none,id=nvme_ns1",
            "-drive",
            "if=none,id=nvme_ns2,format=raw,file.driver=null-co,file.size=1G",
            "-device",
            "nvme,id=nvme0,serial=nvme-1",
            "-device",
            "nvme-ns,drive=nvme_ns1,bus=nvme0,nsid=1",
            "-device",
            "nvme-ns,drive=nvme_ns2,bus=nvme0,nsid=2",
        ])
    

With this change, we have added 2 NVMe namespaces nsid 1 & 2, and we have added 2 boot media, 1 with the real OS and 2 with an empty drive.

With PcdNvmeNamespaceFilter == TRUE we only enumerate the NSID 1 and successfully boot to OS.

With PcdNvmeNamespaceFilter == FALSE we enumerate both the namespaces as defined above and also successfully boot to OS.

Integration Instructions

Set PcdNvmeNamespaceFilter to TRUE when required at the platform dsc.

@eeshanl eeshanl self-assigned this Apr 8, 2026
@eeshanl eeshanl force-pushed the nvme_namespace_filtering branch 2 times, most recently from 4f534ff to 7ef1da1 Compare April 8, 2026 18:54
@eeshanl eeshanl marked this pull request as ready for review April 8, 2026 18:54
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 8, 2026

Codecov Report

❌ Patch coverage is 0% with 18 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (release/202511@872dc15). Learn more about missing BASE report.

Files with missing lines Patch % Lines
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c 0.00% 18 Missing ⚠️
Additional details and impacted files
@@                Coverage Diff                @@
##             release/202511    #1754   +/-   ##
=================================================
  Coverage                  ?    1.84%           
=================================================
  Files                     ?     1150           
  Lines                     ?   376097           
  Branches                  ?     3196           
=================================================
  Hits                      ?     6936           
  Misses                    ?   369105           
  Partials                  ?       56           
Flag Coverage Δ
FmpDevicePkg 9.53% <ø> (?)
MdeModulePkg 1.58% <0.00%> (?)
NetworkPkg 0.55% <ø> (?)
PolicyServicePkg 30.42% <ø> (?)
SecurityPkg 1.61% <ø> (?)
UefiCpuPkg 4.78% <ø> (?)
UnitTestFrameworkPkg 11.70% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mu-automation
Copy link
Copy Markdown
Contributor

mu-automation bot commented Apr 8, 2026

✅ QEMU Validation Passed

Source Dependencies

Repository Commit
mu_basecore ede9f77
mu_tiano_platforms e7f5cec

Results

Platform Target Build Boot Overall Boot Time Build Logs Boot Logs
Q35 DEBUG ✅ success ✅ success 0m 16s Build Logs Boot Logs
SBSA DEBUG ✅ success ✅ success 0m 31s Build Logs Boot Logs

Workflow run: https://github.com/microsoft/mu_basecore/actions/runs/24270302709

This comment was automatically generated by the Mu QEMU PR Validation workflow.

@eeshanl eeshanl force-pushed the nvme_namespace_filtering branch 2 times, most recently from ca5e37c to e846018 Compare April 8, 2026 20:12
@makubacki makubacki force-pushed the nvme_namespace_filtering branch from e846018 to e929851 Compare April 8, 2026 21:22
@eeshanl eeshanl requested a review from spbrogan April 9, 2026 00:03
@eeshanl eeshanl force-pushed the nvme_namespace_filtering branch 4 times, most recently from 31a43a4 to ba5c53f Compare April 10, 2026 20:37
@eeshanl eeshanl requested review from apop5, kuqin12, makubacki and os-d April 10, 2026 23:36
@eeshanl
Copy link
Copy Markdown
Contributor Author

eeshanl commented Apr 10, 2026

Disclaimer: Readme.md is AI generated

@eeshanl eeshanl force-pushed the nvme_namespace_filtering branch 3 times, most recently from 03419de to 37e056c Compare April 11, 2026 00:18
eeshanl added 3 commits April 10, 2026 17:18
Add PcdNvmeNamespaceFilter to control NVMe namespace enumeration.
When TRUE, only the first namespace (NSID 1) is discovered and
enumerated. When FALSE (default), all namespaces are enumerated
as before.

This improves security on NVMe devices with multiple namespaces.
Without filtering, UEFI enumerates all namespaces and an attacker
could place malicious boot media in a secondary namespace. By
restricting enumeration to only the first namespace, we ensure the
system boots exclusively from the intended namespace and prevents
exploitation of additional namespaces as an attack vector.

Changes:
- NvmExpress.h: Add NVME_FIRST_NSID define
- NvmExpress.c: Add FilteringEnabled parameter to DiscoverAllNamespaces,
  EnumerateNvmeDevNamespace with namespace ID check when filtering
- NvmExpressDxe.inf: Add PcdNvmeNamespaceFilter to [Pcd] section
- MdeModulePkg.dec: Define PcdNvmeNamespaceFilter (default FALSE)

Ref: microsoft/mu_msvm@9337285
@eeshanl eeshanl force-pushed the nvme_namespace_filtering branch from 37e056c to ede9f77 Compare April 11, 2026 00:19
Copy link
Copy Markdown
Contributor

@os-d os-d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you take this directly to edk2 or do we have a platform need to get this into Mu now? If so, please take it to edk2 in parallel. Obviously dropping the MU_CHANGEs part of the readme.

# MU_CHANGE [BEGIN] - NVMe namespace filtering
## When TRUE, only the first NVMe namespace is enumerated. When FALSE, all namespaces are discovered.
# @Prompt Enable NVMe namespace filtering to only use NSID 1.
gEfiMdeModulePkgTokenSpaceGuid.PcdNvmeNamespaceFilter|FALSE|BOOLEAN|0x40000153
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is from existing platform code, but there is nothing special about the first namespace, right? Should this PCD specify which namespace ID to exclusively use?

Copy link
Copy Markdown
Collaborator

@apop5 apop5 Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would second Olver's comment.

NSID 0 is an invalid name space. Name spaces start at 1 and go up from there.
I think the PcdNvmeNamespaceFilter could be used to specify the name space being filtered, with 0 being no filtering.

And this would eliminate that #define as well

discover, initialize, and provide block-level access to NVMe storage devices during the UEFI
boot phase.

## Module Details
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop

The driver registers with `EFI_RESET_NOTIFICATION_PROTOCOL` to issue NVMe shutdown notifications
(CC.SHN) to all managed controllers before a platform reset, ensuring data integrity.

## Source Files
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop (not much info beyond the filename, will go out of date)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants