[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CA+OvW8ZY1D3ECy2vw_Nojm1Kc8NzJHCpqNJUF0n8z3MhLAQd8A@mail.gmail.com>
Date: Thu, 4 Sep 2025 00:28:22 +0100
From: Sid Nayyar <sidnayyar@...gle.com>
To: Petr Pavlu <petr.pavlu@...e.com>
Cc: Nathan Chancellor <nathan@...nel.org>, Luis Chamberlain <mcgrof@...nel.org>,
Sami Tolvanen <samitolvanen@...gle.com>, Nicolas Schier <nicolas.schier@...ux.dev>,
Arnd Bergmann <arnd@...db.de>, linux-kbuild@...r.kernel.org, linux-arch@...r.kernel.org,
linux-modules@...r.kernel.org, linux-kernel@...r.kernel.org,
Giuliano Procida <gprocida@...gle.com>, Matthias Männich <maennich@...gle.com>
Subject: Re: [RFC PATCH 00/10] scalable symbol flags with __kflagstab
On Mon, Sep 1, 2025 at 1:27 PM Petr Pavlu <petr.pavlu@...e.com> wrote:
> 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.
Thanks for looking into the history of the _gpl split. We also noted
that there were up to five separate arrays at one point.
We explored three approaches to this problem: using the existing
__ksymtab, packing flags as bit-vectors, and the proposed
__kflagstab. We ruled out the bit-vector approach due to its
complexity, which would only save a few bits per symbol. The
__ksymtab approach, while the simplest, was too wasteful of space.
The __kflagstab seems like a good compromise, offering a slight
increase in complexity over the __ksymtab method but requiring only
one extra byte 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?
The Android Common Kernel source is compiled into what we call
GKI (Generic Kernel Image), which consists of a kernel and a
number of modules. We maintain a stable interface (based on CRCs and
types) between the GKI components and vendor-specific modules
(compiled by device manufacturers, e.g., for hardware-specific
drivers) for the lifetime of a given GKI version.
This interface is intentionally restricted to the minimal set of
symbols required by the union of all vendor modules; our partners
declare their requirements in symbol lists. Any additions to these
lists are reviewed to ensure kernel internals are not overly exposed.
For example, we restrict drivers from having the ability to open and
read arbitrary files. This ABI boundary also allows us to evolve
internal kernel types that are not exposed to vendor modules, for
example, when a security fix requires a type to change.
The mechanism we use for this is CONFIG_TRIM_UNUSED_KSYMS and
CONFIG_UNUSED_KSYMS_WHITELIST. This results in a ksymtab
containing two kinds of exported symbols: those explicitly required
by vendors ("vendor-listed") and those only required by GKI modules
("GKI use only").
On top of this, we have implemented symbol import protection
(covered in patches 9/10 and 10/10). This feature prevents vendor
modules from using symbols that are not on the vendor-listed
whitelist. It is built on top of CONFIG_MODULE_SIG. GKI modules are
signed with a specific key, while vendor modules are unsigned and thus
treated as untrusted. This distinction allows signed GKI modules to
use any symbol in the ksymtab, while unsigned vendor modules can only
access the declared subset. This provides a significant layer of
defense and security against potentially exploitable vendor module
code.
Finally, we have implemented symbol export protection, which prevents
a vendor module from impersonating a GKI module by exporting any of
the same symbols. Note that this protection is currently specific to
the Android kernel and is not included in this patch series.
We have several years of experience with older implementations of
these protection mechanisms. The code in this series is a
considerably cleaner and simpler version compared to what has been
shipping in Android kernels since Android 14 (6.1 kernel).
I hope this clarifies the goals of the patch set. Let me know if you
have further questions.
--
Thanks,
Siddharth Nayyar
Powered by blists - more mailing lists