Re: [PATCH v38 04/39] LSM: Maintain a table of LSM attribute data

From: Tetsuo Handa
Date: Mon Oct 24 2022 - 17:57:47 EST


On 2022/10/24 2:13, Casey Schaufler wrote:
>> We won't be able to accept whatever LSM modules to upstream, and we won't
>> be able to enable whatever LSM modules in distributor kernels.
>
> A built in module loader security module would address this issue.
> Getting such a module accepted upstream is not going to be trivial,
> but the BPF people seem to have managed it.

How can we guarantee that a built-in module loader security module is
always built-in ? What I'm insisting is that "warrant the freedom to load
loadable LSM modules without recompiling the whole kernel".

Sure, we can load LSM modules which were not built into distributor kernels
if we can recompile the whole kernel". But give me a break, that's a stupid
opinion for non-kernel developers. People won't replace distributor kernels
with rebuilt kernels only for enabling LSM modules which were not built into
distributor kernels.

Quoting from https://lkml.kernel.org/r/7f9ffd77-a329-ab13-857b-f8e34b2bfc77@xxxxxxxxxxxxxxxx

> I'm waiting to see what happens if eBPF security modules
> become popular. I can easily see distributions turning the BPF LSM off.

Even if TOMOYO could be rewritten in eBPF (I don't think it is possible), how TOMOYO
can be loaded into distributor kernels if distributions turn the BPF LSM off ?

> Before I go any further, I think that the loadable module manager LSM would be
> very hard to get upstream.

Not only it will be very hard to get the loadable module manager LSM upstream,
it will be also very hard to keep the loadable module manager LSM enabled in
distributor kernels.

Again, how can we guarantee that a built-in module loader security module is
always built-in ?

What I'm insisting is that "warrant the freedom to load loadable LSM modules
without recompiling the whole kernel".

Adding EXPORT_SYMBOL_GPL(security_hook_heads) is the only way that can "allow
LSM modules which distributors cannot support to be legally loaded".

Any fixed-sized array like lsm_idlist[LSMID_ENTRIES] that defines max capacity
based on whether that LSM module is built-in will lock out loadable LSM modules.
Thus, I'm not happy with LSMID_ENTRIES.



On 2022/10/24 2:20, Casey Schaufler wrote:
> On 10/23/2022 3:10 AM, Tetsuo Handa wrote:
>> On 2022/10/23 16:27, Tetsuo Handa wrote:
>>> On 2022/10/21 8:42, Casey Schaufler wrote:
>>>> I will, on the other hand, listen to compelling arguments. It is not the
>>>> intention of this code to lock out loadable modules. If I thought it would
>>>> I would not have proposed it.
>>> This code is exactly for locking out loadable modules.
>>>
>> Imagine a situation where two individuals independently develop their own
>> web applications using the same identifier, and then their web applications
>> started working together with other web applications using that identifier.
>> When they published their web applications for public and wider use, a problem
>> that both web applications are already using the same identifier arises.
>> It is too late to reassign the identifier.
>>
>> The same trouble can happen with loadable LSM modules. Unless the upstream kernel
>> behaves as if a DNS registerer that assigns a unique domainname for whatever web
>> sites (regardless of whether a web site is for public or not), defining a permanent
>> constant for LSM module is a way towards locking out loadable LSM modules. And it
>> is well possible that a loadable LSM module wants to run on older kernels which
>> do not have LSM id defined yet.
>>
>> This "define LSM id as userspace visible constant" is more dangerous than just
>> reserving some space for future use. You are trying to control all IP addresses
>> for the sake of only in-tree LSM modules. No, no, no, please don't do that...
>
> It's really no more dangerous than using the LSM name. What if two developers
> implement modules and both name it "belllapadula"? User space won't be able to
> tell the difference if they base behavior on the module name. That's one thing
> that a loadable module mechanism is going to need to address that a built-in
> mechanism doesn't.

If the upstream kernel assigns an LSM id for all LSM modules including out-of-tree
and/or private LSM modules (that's why I described that the upstream kernel behaves
as if a DNS registerer), we can assign LSM id = 100 to "belllapadula" from A and
LSM id = 101 to "belllapadula" from B, and both "belllapadula" modules can work
without conflicts by using LSM id. Of course, this implies that we need to preserve
unused space in lsm_idlist[LSMID_ENTRIES] etc. for such LSM modules (if we use
fixed-sized array rather than a linked list).