Thread (13 messages) 13 messages, 3 authors, 2023-03-27

Re: [PATCH 0/5] usermode_driver: Add management library and API

From: Roberto Sassu <hidden>
Date: 2023-03-27 11:28:07
Also in: bpf, linux-doc, linux-kselftest, lkml

On Fri, 2023-03-24 at 19:54 -0700, Alexei Starovoitov wrote:
On Thu, Mar 23, 2023 at 6:37 AM Roberto Sassu
[off-list ref] wrote:
quoted
On Wed, 2023-03-22 at 15:27 -0700, Alexei Starovoitov wrote:
quoted
On Wed, Mar 22, 2023 at 5:08 AM Roberto Sassu
[off-list ref] wrote:
quoted
On Tue, 2023-03-21 at 19:23 -0700, Alexei Starovoitov wrote:
quoted
On Fri, Mar 17, 2023 at 7:53 AM Roberto Sassu
[off-list ref] wrote:
quoted
From: Roberto Sassu <roberto.sassu@huawei.com>

A User Mode Driver (UMD) is a specialization of a User Mode Helper (UMH),
which runs a user space process from a binary blob, and creates a
bidirectional pipe, so that the kernel can make a request to that process,
and the latter provides its response. It is currently used by bpfilter,
although it does not seem to do any useful work.
FYI the new home for bpfilter is here:
https://github.com/facebook/bpfilter
Thanks. I just ensured that it worked, by doing:

getsockopt(fd, SOL_IP, IPT_SO_GET_INFO, &info, &optlen);

and accepting IPT_SO_GET_INFO in main.c.
quoted
quoted
The problem is, if other users would like to implement a UMD similar to
bpfilter, they would have to duplicate the code. Instead, make an UMD
management library and API from the existing bpfilter and sockopt code,
and move it to common kernel code.

Also, define the software architecture and the main components of the
library: the UMD Manager, running in the kernel, acting as the frontend
interface to any user or kernel-originated request; the UMD Loader, also
running in the kernel, responsible to load the UMD Handler; the UMD
Handler, running in user space, responsible to handle requests from the UMD
Manager and to send to it the response.
That doesn't look like a generic interface for UMD.
What would make it more generic? I made the API message format-
independent. It has the capability of starting the user space process
as required, when there is a communication.
quoted
It was a quick hack to get bpfilter off the ground, but certainly
not a generic one.
True, it is not generic in the sense that it can accomodate any
possible use case. The main goal is to move something that was running
in the kernel to user space, with the same isolation guarantees as if
the code was executed in the kernel.
They are not the same guarantees.
UMD is exactly equivalent to root process running in user space.
Meaning it can be killed, ptraced, priority inverted, etc
That is the starting point.

I suppose you can remove any privilege from the UMD process, it just
needs to read/write from/to a pipe (and in my case to use socket() with
AF_ALG to interact with the Crypto API).

Also, as I mentioned, you can enforce a very strict seccomp profile,
which forces the UMD process to use a very limited number of system
calls.

For the interactions of the rest of the system to the UMD process, you
could deny with an LSM all the operations that you mentioned. The rest
of the system would not be affected, only operations which have the UMD
process as target are denied.
quoted
quoted
quoted
quoted
I have two use cases, but for sake of brevity I will propose one.

I would like to add support for PGP keys and signatures in the kernel, so
that I can extend secure boot to applications, and allow/deny code
execution based on the signed file digests included in RPM headers.

While I proposed a patch set a while ago (based on a previous work of David
Howells), the main objection was that the PGP packet parser should not run
in the kernel.

That makes a perfect example for using a UMD. If the PGP parser is moved to
user space (UMD Handler), and the kernel (UMD Manager) just instantiates
the key and verifies the signature on already parsed data, this would
address the concern.
I don't think PGP parser belongs to UMD either.
Please do it as a normal user space process and define a proper
protocol for communication between kernel and user space.
UMD is better in the sense that it establishes a bidirectional pipe
between the kernel and the user space process. With that, there is no
need to further restrict the access to a sysfs file, for example.
If a simple pipe is good enough then you can have a kernel module
that creates it and interacts with the user space process.
Few points I forgot to mention.

With the UMD approach, the binary blob is embedded in the kernel
module, which means that no external dependencies are needed for
integrity verification. The binary is statically compiled, and the
kernel write-protects it at run-time.

Second, since DIGLIM would check the integrity of any executable,
including init, the PGP signature verification needs to occur before.
So, the PGP UMD should be already started by then. That is not going to
be a problem, since the binary is copied to a private tmpfs mount.
quoted
Out-of-tree bpftiler can do that, so can you.
As far as I can see, the out-of-tree bpfilter works exactly in the same
way as the in-tree counterpart. The binary blob is embedded in the
kernel module.
quoted
PGP is not suitable for kernel git repo either as kernel code or as UMD.
Well, the asymmetric key type can be extended with new parsers, so this
possibility was already taken into account. The objection that the PGP
parser should not run in kernel space is fair, but I think the UMD
approach fully addresses that.

Also, I agree with you that we should not just take any code and
pretend that it is part of the kernel. However, in this particular
case, the purpose of the PGP UMD would be simply to extract very few
information from the PGP packets. The asymmetric key type and the
signature verification infrastructure already take care of the rest.

PGP keys and signatures would act as an additional system trust anchor
for verifying critical system data (for DIGLIM, which executables are
allowed to run), similarly to how X.509 certificates are used for
verifying kernel modules. RPM headers, executables digests are taken
from, are signed with PGP, so there is no other way than adding this
functionality.

And unfortunately, especially for features impacting the entire system,
out-of-tree drivers are not really an option:
I think you have to start out of tree and prove that the PGP thing
is worth considering at all.
Only then we can talk about merits of UMD and generalization
of pipe interface if it's applicable.
Ok. This is my plan:

1) send the kernel part necessary to support PGP keys and signatures
2) evaluate/discuss if something else can be moved to user space
3) propose the implementation of the PGP UMD
4) assess the robustness of the solution, and compare to different
   designs

Thanks

Roberto
DIGLIM and everything else you mentioned above doesn't add weight
to the decision. PGP work should be acceptable on its own.
Out-of-tree is a method to prove that it works and later argue
for inclusion as in-tree either as kernel module or UMD.
Generalization of current bpfilter is out of scope here.
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help