CNA-BUG-090: GraphicsDeviceInformation accepts a null Adapter, and GraphicsDeviceManager then binds a reference through that null pointer

CNA snapshot c1c316b9  ·  Known Issues › Current bugs  ·  source links pinned to c1c316b9

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit c1c316b9; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

XNA's documentation says the GraphicsDeviceInformation.Adapter setter throws ArgumentNullException for a null value (the shipped IL only tests the stored adapter, so the first null slips through in real XNA). CNA's setter stores any pointer, and applyToExistingRenderer then dereferences its GraphicsDeviceInformation's getAdapterProperty() when it calls GraphicsDevice::Reset, which is undefined behaviour for a null adapter; in practice the device keeps its previous adapter.

Identifier
CNA-BUG-090
Category
Bug
Subsystem
Core & runtime
Status
Open
Verified against
CNA c1c316b9 (c1c316b9c7a846ce8002809c151fcd1af14942c9)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
Microsoft::Xna::Framework::GraphicsDeviceInformation::setAdapterProperty; PreparingDeviceSettings handlers

Expected behaviour

The XNA 4.0 documentation for GraphicsDeviceInformation.Adapter lists ArgumentNullException ("Adapter is null. Try using DefaultAdapter instead."), so a PreparingDeviceSettings handler is told not to produce a device information without an adapter. (The IL of set_Adapter tests the stored field rather than the incoming value, so real XNA 4.0 lets the first null through and fails later; the documented contract is the exception.) Independently of XNA, CNA's own code must not form a reference through a null pointer.

Actual behaviour at TARGET

GraphicsDeviceInformation.cpp stores any pointer in setAdapterProperty. ApplyChanges and CreateDevice in GraphicsDeviceManager.cpp already guard the adapter with a null check when they name the device, but applyToExistingRenderer then passes the dereferenced getAdapterProperty() of its GraphicsDeviceInformation argument to graphicsDevice_->Reset, forming a reference from a null pointer, which is undefined behaviour. With current compilers the address simply reaches the pointer overload of GraphicsDevice::Reset, which treats null as "keep the current adapter", so the handler's mistake is silently ignored rather than reported.

Source locations

Evidence

Checked by reading the named sources at c1c316b9; nothing was built or executed for this entry. The practical outcome depends on the compiler not exploiting the undefined behaviour.

Independent re-verification: Checked by reading the named sources at c1c316b9 and disassembling XNA 4.0's GraphicsDeviceInformation.set_Adapter, which loads the adapter field instead of the argument; the earlier statement that the IL rejects a null value is withdrawn, while the XNA documentation still lists the exception. Not executed; the practical outcome depends on the compiler not exploiting the undefined behaviour.

Focused reproduction

No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.

Current tests

GraphicsDeviceInformationTests.cpp does not set a null adapter.

Regression test

A test that sets Adapter = nullptr and expects ArgumentNullException from the setter.

Blast radius

Only PreparingDeviceSettings handlers that clear the adapter.

Workaround

Never assign a null adapter.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Known issues
Bug index