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¶
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¶
- Linux kernel: Symbol Namespaces
- Related case:
case175_kabi_crc_changed
Source files¶
v1.symversv2.symvers
See also: Examples overview ยท All BREAKING cases ยท Category: Breaking.