[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAJHvVcigVqAibm0JODkiR=Pcd3E14xp0NB6acw2q2enwnrnLSA@mail.gmail.com>
Date: Tue, 19 Jul 2022 15:45:37 -0700
From: Axel Rasmussen <axelrasmussen@...gle.com>
To: Nadav Amit <namit@...are.com>
Cc: Alexander Viro <viro@...iv.linux.org.uk>,
Andrew Morton <akpm@...ux-foundation.org>,
Dave Hansen <dave.hansen@...ux.intel.com>,
"Dmitry V . Levin" <ldv@...linux.org>,
Gleb Fotengauer-Malinovskiy <glebfm@...linux.org>,
Hugh Dickins <hughd@...gle.com>, Jan Kara <jack@...e.cz>,
Jonathan Corbet <corbet@....net>,
Mel Gorman <mgorman@...hsingularity.net>,
Mike Kravetz <mike.kravetz@...cle.com>,
Mike Rapoport <rppt@...nel.org>, Peter Xu <peterx@...hat.com>,
Shuah Khan <shuah@...nel.org>,
Suren Baghdasaryan <surenb@...gle.com>,
Vlastimil Babka <vbabka@...e.cz>,
zhangyi <yi.zhang@...wei.com>,
"linux-doc@...r.kernel.org" <linux-doc@...r.kernel.org>,
linux-fsdevel <linux-fsdevel@...r.kernel.org>,
LKML <linux-kernel@...r.kernel.org>,
Linux MM <linux-mm@...ck.org>,
"linux-kselftest@...r.kernel.org" <linux-kselftest@...r.kernel.org>
Subject: Re: [PATCH v4 2/5] userfaultfd: add /dev/userfaultfd for fine grained
access control
On Tue, Jul 19, 2022 at 3:32 PM Nadav Amit <namit@...are.com> wrote:
>
> On Jul 19, 2022, at 12:56 PM, Axel Rasmussen <axelrasmussen@...gle.com> wrote:
>
> > Historically, it has been shown that intercepting kernel faults with
> > userfaultfd (thereby forcing the kernel to wait for an arbitrary amount
> > of time) can be exploited, or at least can make some kinds of exploits
> > easier. So, in 37cd0575b8 "userfaultfd: add UFFD_USER_MODE_ONLY" we
> > changed things so, in order for kernel faults to be handled by
> > userfaultfd, either the process needs CAP_SYS_PTRACE, or this sysctl
> > must be configured so that any unprivileged user can do it.
> >
> > In a typical implementation of a hypervisor with live migration (take
> > QEMU/KVM as one such example), we do indeed need to be able to handle
> > kernel faults. But, both options above are less than ideal:
> >
> > - Toggling the sysctl increases attack surface by allowing any
> > unprivileged user to do it.
> >
> > - Granting the live migration process CAP_SYS_PTRACE gives it this
> > ability, but *also* the ability to "observe and control the
> > execution of another process [...], and examine and change [its]
> > memory and registers" (from ptrace(2)). This isn't something we need
> > or want to be able to do, so granting this permission violates the
> > "principle of least privilege".
> >
> > This is all a long winded way to say: we want a more fine-grained way to
> > grant access to userfaultfd, without granting other additional
> > permissions at the same time.
> >
> > To achieve this, add a /dev/userfaultfd misc device. This device
> > provides an alternative to the userfaultfd(2) syscall for the creation
> > of new userfaultfds. The idea is, any userfaultfds created this way will
> > be able to handle kernel faults, without the caller having any special
> > capabilities. Access to this mechanism is instead restricted using e.g.
> > standard filesystem permissions.
>
> Are there any other “devices" that when opened by different processes
> provide such isolated interfaces in each process? I.e., devices that if you
> read from them in different processes you get completely unrelated data?
> (putting aside namespaces).
>
> It all sounds so wrong to me, that I am going to try again to pushback
> (sorry).
No need to be sorry. :)
>
> From a semantic point of view - userfaultfd is process specific. It is
> therefore similar to /proc/[pid]/mem (or /proc/[pid]/pagemap and so on).
>
> So why can’t we put it there? I saw that you argued against it in your
> cover-letter, and I think that your argument is you would need
> CAP_SYS_PTRACE if you want to access userfaultfd of other processes. But
> this is EXACTLY the way opening /proc/[pid]/mem is performed - see
> proc_mem_open().
>
> So instead of having some strange device that behaves differently in the
> context of each process, you can just have /proc/[pid]/userfaultfd and then
> use mm_access() to check if you have permissions to access userfaultfd (just
> like proc_mem_open() does). This would be more intuitive for users as it is
> similar to other /proc/[pid]/X, and would cover both local and remote
> use-cases.
Ah, so actually I find this argument much more compelling.
I don't find it persuasive that we should put it in /proc for the
purpose of supporting cross-process memory manipulation, because I
think the syscall works better for that, and in that case we don't
mind depending on CAP_SYS_PTRACE.
But, what you've argued here I do find persuasive. :) You are right, I
can't think of any other example of a device node in /dev that works
like this, where it is completely independent on a per-process basis.
The closest I could come up with was /dev/zero or /dev/null or
similar. You won't affect any other process by touching these, but I
don't think these are good examples.
I'll send a v5 which does this. I do worry that cross-process support
is probably complex to get right, so I might leave that out and only
allow a process to open its own device for now.
>
Powered by blists - more mailing lists