On 11/30/2023 3:43 PM, Roberto Sassu wrote: > On 12/1/2023 12:31 AM, Casey Schaufler wrote: >> On 11/30/2023 1:34 PM, Roberto Sassu wrote: >>> On 11/30/2023 5:15 PM, Casey Schaufler wrote: >>>> On 11/30/2023 12:30 AM, Petr Tesarik wrote: >>>>> Hi all, >>>>> >>>>> On 11/30/2023 1:41 AM, Casey Schaufler wrote: >>>>>> ... >>>>>> It would be nice if the solution directly addresses the problem. >>>>>> EVM needs to be after the LSMs that use xattrs, not after all LSMs. >>>>>> I suggested LSM_ORDER_REALLY_LAST in part to identify the notion as >>>>>> unattractive. >>>>> Excuse me to chime in, but do we really need the ordering in code? >>>> >>>> tl;dr - Yes. >>>> >>>>> FWIW >>>>> the linker guarantees that objects appear in the order they are seen >>>>> during the link (unless --sort-section overrides that default, but >>>>> this >>>>> option is not used in the kernel). Since *.a archive files are >>>>> used in >>>>> kbuild, I have also verified that their use does not break the >>>>> assumption; they are always created from scratch. >>>>> >>>>> In short, to enforce an ordering, you can simply list the >>>>> corresponding >>>>> object files in that order in the Makefile. Of course, add a big fat >>>>> warning comment, so people understand the order is not arbitrary. >>>> >>>> Not everyone builds custom kernels. >>> >>> Sorry, I didn't understand your comment. >> >> Most people run a disto supplied kernel. If the LSM ordering were >> determined >> only at compile time you could never run a kernel that omitted an LSM. > > Ah, ok. We are talking about the LSMs with order LSM_ORDER_LAST which > are always enabled and the last. > > This is the code in security.c to handle them: > > /* LSM_ORDER_LAST is always last. */ > for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { > if (lsm->order == LSM_ORDER_LAST) > append_ordered_lsm(lsm, " last"); > } > > Those LSMs are not affected by lsm= in the kernel command line, or the > order in the kernel configuration (those are the mutable LSMs). > > In this case, clearly, what matters is how LSMs are stored in the > .lsm_info.init section. See the DEFINE_LSM() macro: > > #define DEFINE_LSM(lsm) \ > static struct lsm_info __lsm_##lsm \ > __used __section(".lsm_info.init") \ > __aligned(sizeof(unsigned long)) > > With Petr, we started to wonder if somehow the order in which LSMs are > placed in this section is deterministic. I empirically tried to swap > the order in which IMA and EVM are compiled in the Makefile, and that > led to 'evm' being placed in the LSM list before 'ima'. > > The question is if this behavior is deterministic, or there is a case > where 'evm' is before 'ima', despite they are in the inverse order in > the Makefile. > > Petr looked at the kernel linking process, which is relevant for the > order of LSMs in the .lsm_info.init section, and he found that the > order in the section always corresponds to the order in the Makefile. OK, that's staring to make sense. My recollection is that there wasn't an expectation for multiple LSM_ORDER_FIRST or LSM_ORDER_LAST entries in the beginning. They were supposed to be special cases, not general features. > > Thanks > > Roberto >>> Everyone builds the kernel, also Linux distros. What Petr was >>> suggesting was that it does not matter how you build the kernel, the >>> linker will place the LSMs in the order they appear in the Makefile. >>> And for this particular case, we have: >>> >>> obj-$(CONFIG_IMA) += ima/ >>> obj-$(CONFIG_EVM) += evm/ >>> >>> In the past, I also verified that swapping these two resulted in the >>> swapped order of LSMs. Petr confirmed that it would always happen. >> >> LSM execution order is not based on compilation order. It is specified >> by CONFIG_LSM, and may be modified by the LSM_ORDER value. I don't >> understand why the linker is even being brought into the discussion. >> >>> >>> Thanks >>> >>> Roberto >