On 8/29/25 12:54 PM, Siddharth Nayyar wrote:
> Hi everyone,
> 
> This patch series proposes a new, scalable mechanism to represent
> boolean flags for exported kernel symbols.
> 
> Problem Statement:
> 
> The core architectural issue with kernel symbol flags is our reliance on
> splitting the main symbol table, ksymtab. To handle a single boolean
> property, such as GPL-only, all exported symbols are split across two
> separate tables: __ksymtab and __ksymtab_gpl.
> 
> This design forces the module loader to perform a separate search on
> each of these tables for every symbol it needs, for vmlinux and for all
> previously loaded modules.
> 
> This approach is fundamentally not scalable. If we were to introduce a
> second flag, we would need four distinct symbol tables. For n boolean
> flags, this model requires an exponential growth to 2^n tables,
> dramatically increasing complexity.
> 
> Another consequence of this fragmentation is degraded performance. For
> example, a binary search on the symbol table of vmlinux, that would take
> only 14 comparison steps (assuming ~2^14 or 16K symbols) in a unified
> table, can require up to 26 steps when spread across two tables
> (assuming both tables have ~2^13 symbols). This performance penalty
> worsens as more flags are added.
> 
> Proposed Solution:
> 
> This series introduces a __kflagstab section to store symbol flags in a
> dedicated data structure, similar to how CRCs are handled in the
> __kcrctab.
> 
> The flags for a given symbol in __kflagstab will be located at the same
> index as the symbol's entry in __ksymtab and its CRC in __kcrctab. This
> design decouples the flags from the symbol table itself, allowing us to
> maintain a single, sorted __ksymtab. As a result, the symbol search
> remains an efficient, single lookup, regardless of the number of flags
> we add in the future.

Merging __ksymtab and __ksymtab_gpl into a single section looks ok to
me, and similarly for __kcrctab and __kcrtab_gpl. The __ksymtab_gpl
support originally comes from commit 3344ea3ad4 ("[PATCH] MODULE_LICENSE
and EXPORT_SYMBOL_GPL support") [1], where it was named __gpl_ksymtab.
The commit doesn't mention why the implementation opts for using
a separate section, but I suspect it was designed this way to reduce
memory/disk usage.

A question is whether the symbol flags should be stored in a new
__kflagstab section, instead of adding a flag member to the existing
__ksymtab. As far as I'm aware, no userspace tool (particularly kmod)
uses the __ksymtab data, so we are free to update its format.

Note that I believe that __kcrctab/__kcrtab_gpl is a separate section
because the CRC data is available only if CONFIG_MODVERSIONS=y.

Including the flags as part of __ksymtab would be obviously a simpler
schema. On the other hand, an entry in __ksymtab has in the worst case
a size of 24 bytes with an 8-byte alignment requirement. This means that
adding a flag to it would require additional 8 bytes per symbol.

> 
> The motivation for this change comes from the Android kernel, which uses
> an additional symbol flag to restrict the use of certain exported
> symbols by unsigned modules, thereby enhancing kernel security. This
> __kflagstab can be implemented as a bitmap to efficiently manage which
> symbols are available for general use versus those restricted to signed
> modules only.

I think it would be useful to explain in more detail how this protected
schema is used in practice and what problem it solves. Who is allowed to
provide these limited unsigned modules and if the concern is kernel
security, can't you enforce the use of only signed modules?

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=3344ea3ad4b7c302c846a680dbaeedf96ed45c02

-- 
Thanks,
Petr

Reply via email to