All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Adrian Ratiu" <adrian.ratiu@collabora.com>
To: "Kees Cook" <kees@kernel.org>
Cc: "Jeff Xu" <jeffxu@chromium.org>,
	linux-fsdevel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org,
	linux-doc@vger.kernel.org, kernel@collabora.com, gbiv@google.com,
	ryanbeltran@google.com, inglorion@google.com,
	ajordanr@google.com, jorgelo@chromium.org,
	"Guenter Roeck" <groeck@chromium.org>,
	"Doug Anderson" <dianders@chromium.org>,
	"Jann Horn" <jannh@google.com>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Randy Dunlap" <rdunlap@infradead.org>,
	"Christian Brauner" <brauner@kernel.org>,
	"Jeff Xu" <jeffxu@google.com>,
	"Mike Frysinger" <vapier@chromium.org>
Subject: Re: [PATCH v6 2/2] proc: restrict /proc/pid/mem
Date: Wed, 19 Jun 2024 22:31:49 +0100	[thread overview]
Message-ID: <3304e0-66734e80-1857-33d83680@76729138> (raw)
In-Reply-To: <202406191336.AC7F803123@keescook>

On Wednesday, June 19, 2024 23:41 EEST, Kees Cook <kees@kernel.org> wrote:

> On Tue, Jun 18, 2024 at 03:39:44PM -0700, Jeff Xu wrote:
> > Hi
> > 
> > Thanks for the patch !
> > 
> > On Thu, Jun 13, 2024 at 6:40 AM Adrian Ratiu <adrian.ratiu@collabora.com> wrote:
> > >
> > > Prior to v2.6.39 write access to /proc/<pid>/mem was restricted,
> > > after which it got allowed in commit 198214a7ee50 ("proc: enable
> > > writing to /proc/pid/mem"). Famous last words from that patch:
> > > "no longer a security hazard". :)
> > >
> > > Afterwards exploits started causing drama like [1]. The exploits
> > > using /proc/*/mem can be rather sophisticated like [2] which
> > > installed an arbitrary payload from noexec storage into a running
> > > process then exec'd it, which itself could include an ELF loader
> > > to run arbitrary code off noexec storage.
> > >
> > > One of the well-known problems with /proc/*/mem writes is they
> > > ignore page permissions via FOLL_FORCE, as opposed to writes via
> > > process_vm_writev which respect page permissions. These writes can
> > > also be used to bypass mode bits.
> > >
> > > To harden against these types of attacks, distrbutions might want
> > > to restrict /proc/pid/mem accesses, either entirely or partially,
> > > for eg. to restrict FOLL_FORCE usage.
> > >
> > > Known valid use-cases which still need these accesses are:
> > >
> > > * Debuggers which also have ptrace permissions, so they can access
> > > memory anyway via PTRACE_POKEDATA & co. Some debuggers like GDB
> > > are designed to write /proc/pid/mem for basic functionality.
> > >
> > > * Container supervisors using the seccomp notifier to intercept
> > > syscalls and rewrite memory of calling processes by passing
> > > around /proc/pid/mem file descriptors.
> > >
> > > There might be more, that's why these params default to disabled.
> > >
> > > Regarding other mechanisms which can block these accesses:
> > >
> > > * seccomp filters can be used to block mmap/mprotect calls with W|X
> > > perms, but they often can't block open calls as daemons want to
> > > read/write their runtime state and seccomp filters cannot check
> > > file paths, so plain write calls can't be easily blocked.
> > >
> > > * Since the mem file is part of the dynamic /proc/<pid>/ space, we
> > > can't run chmod once at boot to restrict it (and trying to react
> > > to every process and run chmod doesn't scale, and the kernel no
> > > longer allows chmod on any of these paths).
> > >
> > > * SELinux could be used with a rule to cover all /proc/*/mem files,
> > > but even then having multiple ways to deny an attack is useful in
> > > case one layer fails.
> > >
> > > Thus we introduce four kernel parameters to restrict /proc/*/mem
> > > access: open-read, open-write, write and foll_force. All these can
> > > be independently set to the following values:
> > >
> > > all     => restrict all access unconditionally.
> > > ptracer => restrict all access except for ptracer processes.
> > >
> > > If left unset, the existing behaviour is preserved, i.e. access
> > > is governed by basic file permissions.
> > >
> > > Examples which can be passed by bootloaders:
> > >
> > > proc_mem.restrict_foll_force=all
> > > proc_mem.restrict_open_write=ptracer
> > > proc_mem.restrict_open_read=ptracer
> > > proc_mem.restrict_write=all
> > >
> > > These knobs can also be enabled via Kconfig like for eg:
> > >
> > > CONFIG_PROC_MEM_RESTRICT_WRITE_PTRACE_DEFAULT=y
> > > CONFIG_PROC_MEM_RESTRICT_FOLL_FORCE_PTRACE_DEFAULT=y
> > >
> > > Each distribution needs to decide what restrictions to apply,
> > > depending on its use-cases. Embedded systems might want to do
> > > more, while general-purpouse distros might want a more relaxed
> > > policy, because for e.g. foll_force=all and write=all both break
> > > break GDB, so it might be a bit excessive.
> > >
> > > Based on an initial patch by Mike Frysinger <vapier@chromium.org>.
> > >
> > It is noteworthy that ChromeOS has benefited from blocking
> > /proc/pid/mem write since 2017 [1], owing to the patch implemented by
> > Mike Frysinger.
> > 
> > It is great that upstream can consider this patch, ChromeOS will use
> > the solution once it is accepted.
> > 
> > > Link: https://lwn.net/Articles/476947/ [1]
> > > Link: https://issues.chromium.org/issues/40089045 [2]
> > > Cc: Guenter Roeck <groeck@chromium.org>
> > > Cc: Doug Anderson <dianders@chromium.org>
> > > Cc: Kees Cook <keescook@chromium.org>
> > > Cc: Jann Horn <jannh@google.com>
> > > Cc: Andrew Morton <akpm@linux-foundation.org>
> > > Cc: Randy Dunlap <rdunlap@infradead.org>
> > > Cc: Christian Brauner <brauner@kernel.org>
> > > Cc: Jeff Xu <jeffxu@google.com>
> > > Co-developed-by: Mike Frysinger <vapier@chromium.org>
> > > Signed-off-by: Mike Frysinger <vapier@chromium.org>
> > > Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
> > 
> > Reviewed-by: Jeff Xu <jeffxu@chromium.org>
> > Tested-by: Jeff Xu <jeffxu@chromium.org>
> > [1] https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/764773
> 
> Thanks for the testing! What settings did you use? I think Chrome OS was
> effectively doing this?
> 
> PROC_MEM_RESTRICT_OPEN_READ_OFF=y
> CONFIG_PROC_MEM_RESTRICT_OPEN_WRITE_ALL=y
> CONFIG_PROC_MEM_RESTRICT_WRITE_ALL=y
> CONFIG_PROC_MEM_RESTRICT_FOLL_FORCE_ALL=y

Correct except for CONFIG_PROC_MEM_RESTRICT_OPEN_WRITE_ALL=y
which will make ChromeOS boot loop because upstart/systemd-tmpfiles
will fail and trigger a recovery + reboot, then the kernel will again block
opening the file and so on. :)

ChromeOS effectively only blocks all writes which also blocks all foll_force.

> 
> Though I don't see the FOLL_FORCE changes in the linked Chrome OS patch,
> but I suspect it's unreachable with
> CONFIG_PROC_MEM_RESTRICT_OPEN_WRITE_ALL=y.
 
That is correct, CONFIG_PROC_MEM_RESTRICT_OPEN_WRITE_ALL=y also
blocks FOLL_FORCE.

The idea there is to restrict writes entirely in production images via
Kconfig and then relax the restriction in dev/test images via boot params
proc_mem.restrict_write=ptracer proc_mem.restrict_foll_force=ptracer

See this CL:
https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/5631026


  reply	other threads:[~2024-06-19 21:31 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-13 13:39 [PATCH v6 1/2] proc: pass file instead of inode to proc_mem_open Adrian Ratiu
2024-06-13 13:39 ` [PATCH v6 2/2] proc: restrict /proc/pid/mem Adrian Ratiu
2024-06-17 18:00   ` Kees Cook
2024-06-18 22:39   ` Jeff Xu
2024-06-19 20:41     ` Kees Cook
2024-06-19 21:31       ` Adrian Ratiu [this message]
2024-06-20 16:24       ` Jeff Xu
2024-06-17  8:48 ` [PATCH v6 1/2] proc: pass file instead of inode to proc_mem_open Christian Brauner
2024-06-17 10:47   ` Adrian Ratiu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3304e0-66734e80-1857-33d83680@76729138 \
    --to=adrian.ratiu@collabora.com \
    --cc=ajordanr@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=brauner@kernel.org \
    --cc=dianders@chromium.org \
    --cc=gbiv@google.com \
    --cc=groeck@chromium.org \
    --cc=inglorion@google.com \
    --cc=jannh@google.com \
    --cc=jeffxu@chromium.org \
    --cc=jeffxu@google.com \
    --cc=jorgelo@chromium.org \
    --cc=kees@kernel.org \
    --cc=kernel@collabora.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=ryanbeltran@google.com \
    --cc=vapier@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.