Skip to content

Case 176: kABI Export Namespace Changed

Field Value
Verdict ๐Ÿ”ด BREAKING
Category Breaking
Platforms Linux
Flags ABI break
Detected ChangeKinds kabi_symbol_namespace_changed
Source files examples/case176_kabi_symbol_namespace_changed/

Category: Linux Kernel Module ABI (kABI) | Verdict: ๐Ÿ”ด BREAKING

Verdict and consumer impact

drm_mode_object_add keeps the same CRC โ€” its type signature never moved โ€” and the same symbol name and module. The only change: it moved from a plain EXPORT_SYMBOL() to EXPORT_SYMBOL_NS(..., DRM), gaining an export namespace. A module built against v1 that imports drm_mode_object_add normally, without a matching MODULE_IMPORT_NS(DRM) declaration, fails to load against a v2 kernel with drm_mode_object_add: exists, but namespace DRM does not match the module's imported namespaces: (empty) โ€” a load-time rejection even though nothing about the symbol's type changed at all. This is a distinct load gate from case175's CRC break, with a different fix: add the import declaration, not rebuild against new types.

Old/new diff

v1.symvers v2.symvers
0x4e2f9a10 drm_mode_object_add drivers/gpu/drm/drm EXPORT_SYMBOL 0x4e2f9a10 drm_mode_object_add drivers/gpu/drm/drm EXPORT_SYMBOL_NS DRM

(both files also carry an unrelated, unchanged drm_mode_object_find line โ€” abicheck correctly leaves it out of the finding.)

abicheck command

abicheck compare v1.symvers v2.symvers

Expected abicheck finding

Verdict: BREAKING (exit 4)

- kabi_symbol_namespace_changed: Kernel symbol namespace changed:
  drm_mode_object_add ((none) -> DRM)
  > A kernel-exported symbol gained or moved its export namespace
    (EXPORT_SYMBOL_NS*). A module that does not declare the matching
    MODULE_IMPORT_NS() fails to load, so a gained/changed namespace is a
    load-time break for existing modules.

Minimum evidence

min_evidence: L0 โ€” read directly from the two Module.symvers manifests' namespace column; no kernel build and no compiler are needed. Only a gained or changed namespace is flagged โ€” a namespace being removed only widens who can import the symbol, so that direction is not a break.

Why abicheck catches it

abicheck parses each Module.symvers line's five columns and diffs the namespace column by symbol name. drm_mode_object_add's CRC, module, and GPL class stay identical, isolating the namespace column as the only delta โ€” exactly kabi_symbol_namespace_changed, a finding that is deliberately independent from the CRC check in case175 because the mechanism (an access-control gate at load time, not a type mismatch) and the fix (MODULE_IMPORT_NS(), not a rebuild against new types) are both different.

Real-world deployment scenario

This is what a CI job diffing two kernel build trees' Module.symvers across a kernel update sees when a subsystem maintainer starts namespacing a previously plain-exported symbol โ€” e.g. the DRM subsystem gating GPU driver internals behind EXPORT_SYMBOL_NS(..., DRM). A CRC-only kABI check would report no change at all (the CRC never moved); a plain symbol-presence check would also miss it (the symbol never disappeared). Only reading the namespace column catches the load-time break before an out-of-tree module's insmod fails in the field.

Safe redesign

When introducing EXPORT_SYMBOL_NS() on a previously plain-exported symbol, document it in release notes for out-of-tree module maintainers โ€” MODULE_IMPORT_NS() is a source change even though no function signature moved. Prefer keeping a newly-namespaced export also available un-namespaced for one deprecation cycle if wide out-of-tree consumption is expected.

Cross-tool comparison

abidiff/abi-compliance-checker diff DWARF-carrying compiled binaries; neither reads Module.symvers or has a concept of kernel export namespaces, so there is no equivalent invocation of either tool for this fixture pair.

References


Source files

  • v1.symvers
  • v2.symvers

See also: Examples overview ยท All BREAKING cases ยท Category: Breaking.