RE: F36 Change: DIGLIM (System-Wide Change proposal)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> From: Zbigniew Jędrzejewski-Szmek [mailto:zbyszek@xxxxxxxxx]
> Sent: Thursday, December 30, 2021 1:02 PM
> The gist of the proposal is described thus:
> > The new feature behaves as follows. A modified kernel with the DIGLIM
> > patches will expose to user space an interface to add/remove file
> > digests from the kernel hash table. A user space parser, executed by
> > the kernel during early boot, parses RPM headers found in /etc/diglim
> > in the initial ram disk (included with a custom dracut script) and
> > uploads them to the kernel. When a file is accessed, IMA calculates
> > the file digest and queries it with DIGLIM. If the digest is found,
> > measurement is skipped and appraisal is successful. If the digest is
> > not found, a measurement of the file is performed and appraisal fails.
> > When packages are installed or removed, the kernel hash table is kept
> > synchronized with a new rpm plugin.
> 
> This description is … short.

I saw you asked more questions below. I will answer there.

> > A user space parser, executed by the kernel during early boot
> 
> Is it really executed by the kernel? This description makes it sound
> like a special old-hotplug-helper-style program that is spawned directly
> by the kernel.

Yes, it must be executed before init, otherwise the kernel
would refuse to execute it. And probably, it must be executed
earlier than now, as I'm seeing that the kmod binary is being
executed (with the same mechanism, user-mode helper) before
the digest lists are uploaded to the kernel.

The reason for the kernel denying any operation enforced
by the IMA policy would be that there are no file signatures
for appraisal. The digests loaded by the helper are used
instead. For the same reason, the digest of the helper itself
must be in the native format understood by the kernel
(the process of generation and signing is done in kernel.spec),
and the kernel must scan /etc/diglim to load the native
digest list before the helper is executed.

> > parses RPM headers found in /etc/diglim in the initial ram disk
> 
> In general we try not to stuff more things in /etc, especially when
> there is no reason to. Why doesn't the helper just read files from
> /var/lib/rpm (or whatever %_dbpath du jour)?

The RPM DB cannot be loaded as it is. The kernel accepts a
file format similar to kernel modules, with appended signatures
(I added support for PGP appended signatures in IMA). Each RPM
header, together with its signature, must be written individually
in a file.

Also files in other formats can be added to the same directory
(for example the user-generated digest lists).

If there is a better place than /etc, it would be fine for me to
move the directory to a new location. 

> This opens a bigger design question: the implementation seems to be
> closely tied to a very specific boot sequence implementation:
> grub2 + dracut. Unfortunately this is made even more opaque by the
> text description which uses generic terms like "boot loader configuration"
> when talking about a script which is intimately tied to some obsolete
> imperative grub2 installation mechanism.

Ok, sorry for the confusion. We just need to add few parameters
to the kernel command line, and include the digest lists in the
initial ram disk. For now, I'm excluding the implementation of a
custom script to select only the digest lists required for accessing
files in the initial ram disk.

> It would be much better if instead the helper to upload the hashes
> to the kernel would be a generic tool that can be called whenever and
> from whatever environment. _Then_ you can add a dracut module to call
> it in the initrd, but that part should be a trivial wrapper, with all
> the "business logic" contained in the generic helper.

Too late.

Also it cannot be a generic tool. First it is statically linked, to
avoid depending on shared libraries for which a native digest
list must be generated. At least with a static binary, only one
file should be considered.

Second, I had to develop an ad-hoc LSM to protect the helper
against the other root processes. The problem is that an attacker
might be able to tamper with the memory of the helper containing
the digests extracted from RPMs, before the digests are uploaded
to the kernel. Anything that the helper accesses must be inspected
by IMA to provide the guarantee that the helper was not tampered.

> This will make testing easier, and not preclude systems without an
> initrd.
> 
> > When a file is accessed, IMA calculates the file digest and queries it with
> DIGLIM
> 
> All files? What does "accessed" mean exactly in this context?

IMA selects the files to analyze depending on a policy. That policy
allows the usage of different criteria: inode UID/GID, process UID/EUID,
LSM label, etc. IMA does this selection at the time a file is executed,
mmapped, opened, or read from the kernel.

DIGLIM is invoked only whenever IMA selected a file, and IMA
decides what to do with the file depending on the result of the
query (other than the action specified in the policy).

> > When packages are installed or removed, the kernel hash table is kept
> > synchronized with a new rpm plugin.
> 
> Does this mean that old hashes are removed from the kernel after a
> package has been upgraded?

Yes, the old digests are removed. However, files in use could
be still used, as the result of the last integrity evaluation is
stored in the IMA cache. For cached results, DIGLIM is not
invoked again.

> Are there any race conditions: e.g. when a new version of a package is
> installed, at what point in time are the new hashes uploaded? Something
> may be executed concurrently with the package upgrade, which would mean
> that the new hashes would need to be uploaded before any files land on
> disk.

Yes, we encountered this problem when we implemented
the solution in openEuler. One of the problems was that we
loaded the digests too late, and that prevented the RPM
installation scripts to work. After some iterations, we seem
to have found the right solution (will try to complete the
rpm plugin soon).

> And vice versa, if a file is opened, and later executed with fexecve(2),
> and concurrently the package is upgraded between those two steps,
> will the execution fail?

We are handling concurrency with RCU. It depends if
IMA, calling the DIGLIM lookup function, sees the old
or the new version of the pointers in the hash table.

Roberto

HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Li Peng, Zhong Ronghua
_______________________________________________
devel mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxx
Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/devel@xxxxxxxxxxxxxxxxxxxxxxx
Do not reply to spam on the list, report it: https://pagure.io/fedora-infrastructure




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Fedora Announce]     [Fedora Users]     [Fedora Kernel]     [Fedora Testing]     [Fedora Formulas]     [Fedora PHP Devel]     [Kernel Development]     [Fedora Legacy]     [Fedora Maintainers]     [Fedora Desktop]     [PAM]     [Red Hat Development]     [Gimp]     [Yosemite News]

  Powered by Linux