Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp524817ybh; Wed, 15 Jul 2020 08:14:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxNWwma2wmpnES2raq9cSdnlGA/pjvoo5IfOZMVX9I8cmg0Vkbx/E6ER+d+hBprKn7b0SlU X-Received: by 2002:a50:fe18:: with SMTP id f24mr123051edt.14.1594826069184; Wed, 15 Jul 2020 08:14:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594826069; cv=none; d=google.com; s=arc-20160816; b=SqnPxHkQMojqIhOu3ZNYO9Ip9LJjR32xUUYi3WeZcJV1n+ZkSxyrgj4pSacmHY7+Hp o6KSEBi2a/AL4lgEZsc/LhRbYOEOhV5BCMBcTWdIDB9ONweXRXpDsbRNu3oqZaFFNhcV /lfnJfjGRnS5NsDC4gBA5Xfvzkj+KrLrvWPHsmEFt1nTFGzjLVykjzgOWjZmb/e8y9ts kFkmy5r9kmS9T47ht8/9XB1fKUHo5dUTW1m6grfoOJayHgdq8HF9QJNK9uuLjFB5wGbP gHxhC8AVDkRoxoUo0CtYBS3NXkXUqbAvxogR+q0gfk09wp6ZKh7MAv5rI9iRTK2zCwar O7ng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=/wNp3G+nHH0QcY14zrlNUtYwFoWlT7WFH4FwGdELhFU=; b=pVC+SjePuv48Ah6b96Dt1jfGpNULrIaZFkmtUwMKQLhTZ7uBAkyuoYFUTFG55gHb/O lgKi/HXqL6zlV5mfjdtpaw6J1IPUMXo/IGQXLhsN+kRYWaEHUxMdIWspVBHmbQXiTEG4 0jB30s817efEQAgopZ2EEIVwogjtR78MXcfGfVafpnaZbxfGd/3DIpmjHEG4KjfuMUR7 HK9eeIsYmy9LzpR7Yh07lyGcJNLhrXEk8VFQauq/qtJt5D/5qWKYP3zCAI9gcuc/6L6N sXWIy3xt7MC6PPKw935DE5BNc1NT6N9R7ndGSMEYAqfhenRIcI1UkQMd3enyK8KixTaf hSrQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f13si1455643edy.576.2020.07.15.08.14.06; Wed, 15 Jul 2020 08:14:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728189AbgGOPHW (ORCPT + 99 others); Wed, 15 Jul 2020 11:07:22 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:50263 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728146AbgGOPHT (ORCPT ); Wed, 15 Jul 2020 11:07:19 -0400 Received: from ip5f5af08c.dynamic.kabel-deutschland.de ([95.90.240.140] helo=wittgenstein) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jvizh-0003h4-21; Wed, 15 Jul 2020 15:06:49 +0000 Date: Wed, 15 Jul 2020 17:06:47 +0200 From: Christian Brauner To: Adrian Reber Cc: Eric Biederman , Pavel Emelyanov , Oleg Nesterov , Dmitry Safonov <0x7f454c46@gmail.com>, Andrei Vagin , Nicolas Viennot , =?utf-8?B?TWljaGHFgiBDxYJhcGnFhHNraQ==?= , Kamil Yurtsever , Dirk Petersen , Christine Flood , Casey Schaufler , Mike Rapoport , Radostin Stoyanov , Cyrill Gorcunov , Serge Hallyn , Stephen Smalley , Sargun Dhillon , Arnd Bergmann , linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, selinux@vger.kernel.org, Eric Paris , Jann Horn , linux-fsdevel@vger.kernel.org Subject: Re: [PATCH v5 1/6] capabilities: Introduce CAP_CHECKPOINT_RESTORE Message-ID: <20200715150647.a24nz2iqrel62sfg@wittgenstein> References: <20200715144954.1387760-1-areber@redhat.com> <20200715144954.1387760-2-areber@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20200715144954.1387760-2-areber@redhat.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Jul 15, 2020 at 04:49:49PM +0200, Adrian Reber wrote: > This patch introduces CAP_CHECKPOINT_RESTORE, a new capability facilitating > checkpoint/restore for non-root users. > > Over the last years, The CRIU (Checkpoint/Restore In Userspace) team has been > asked numerous times if it is possible to checkpoint/restore a process as > non-root. The answer usually was: 'almost'. > > The main blocker to restore a process as non-root was to control the PID of the > restored process. This feature available via the clone3 system call, or via > /proc/sys/kernel/ns_last_pid is unfortunately guarded by CAP_SYS_ADMIN. > > In the past two years, requests for non-root checkpoint/restore have increased > due to the following use cases: > * Checkpoint/Restore in an HPC environment in combination with a resource > manager distributing jobs where users are always running as non-root. > There is a desire to provide a way to checkpoint and restore long running > jobs. > * Container migration as non-root > * We have been in contact with JVM developers who are integrating > CRIU into a Java VM to decrease the startup time. These checkpoint/restore > applications are not meant to be running with CAP_SYS_ADMIN. > > We have seen the following workarounds: > * Use a setuid wrapper around CRIU: > See https://github.com/FredHutch/slurm-examples/blob/master/checkpointer/lib/checkpointer/checkpointer-suid.c > * Use a setuid helper that writes to ns_last_pid. > Unfortunately, this helper delegation technique is impossible to use with > clone3, and is thus prone to races. > See https://github.com/twosigma/set_ns_last_pid > * Cycle through PIDs with fork() until the desired PID is reached: > This has been demonstrated to work with cycling rates of 100,000 PIDs/s > See https://github.com/twosigma/set_ns_last_pid > * Patch out the CAP_SYS_ADMIN check from the kernel > * Run the desired application in a new user and PID namespace to provide > a local CAP_SYS_ADMIN for controlling PIDs. This technique has limited use in > typical container environments (e.g., Kubernetes) as /proc is > typically protected with read-only layers (e.g., /proc/sys) for hardening > purposes. Read-only layers prevent additional /proc mounts (due to proc's > SB_I_USERNS_VISIBLE property), making the use of new PID namespaces limited as > certain applications need access to /proc matching their PID namespace. > > The introduced capability allows to: > * Control PIDs when the current user is CAP_CHECKPOINT_RESTORE capable > for the corresponding PID namespace via ns_last_pid/clone3. > * Open files in /proc/pid/map_files when the current user is > CAP_CHECKPOINT_RESTORE capable in the root namespace, useful for recovering > files that are unreachable via the file system such as deleted files, or memfd > files. > > See corresponding selftest for an example with clone3(). > > Signed-off-by: Adrian Reber > Signed-off-by: Nicolas Viennot > --- Thanks! This looks good now. Acked-by: Christian Brauner > include/linux/capability.h | 6 ++++++ > include/uapi/linux/capability.h | 9 ++++++++- > security/selinux/include/classmap.h | 5 +++-- > 3 files changed, 17 insertions(+), 3 deletions(-) > > diff --git a/include/linux/capability.h b/include/linux/capability.h > index b4345b38a6be..1e7fe311cabe 100644 > --- a/include/linux/capability.h > +++ b/include/linux/capability.h > @@ -261,6 +261,12 @@ static inline bool bpf_capable(void) > return capable(CAP_BPF) || capable(CAP_SYS_ADMIN); > } > > +static inline bool checkpoint_restore_ns_capable(struct user_namespace *ns) > +{ > + return ns_capable(ns, CAP_CHECKPOINT_RESTORE) || > + ns_capable(ns, CAP_SYS_ADMIN); > +} > + > /* audit system wants to get cap info from files as well */ > extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); > > diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h > index 48ff0757ae5e..395dd0df8d08 100644 > --- a/include/uapi/linux/capability.h > +++ b/include/uapi/linux/capability.h > @@ -408,7 +408,14 @@ struct vfs_ns_cap_data { > */ > #define CAP_BPF 39 > > -#define CAP_LAST_CAP CAP_BPF > + > +/* Allow checkpoint/restore related operations */ > +/* Allow PID selection during clone3() */ > +/* Allow writing to ns_last_pid */ > + > +#define CAP_CHECKPOINT_RESTORE 40 > + > +#define CAP_LAST_CAP CAP_CHECKPOINT_RESTORE > > #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) > > diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h > index e54d62d529f1..ba2e01a6955c 100644 > --- a/security/selinux/include/classmap.h > +++ b/security/selinux/include/classmap.h > @@ -27,9 +27,10 @@ > "audit_control", "setfcap" > > #define COMMON_CAP2_PERMS "mac_override", "mac_admin", "syslog", \ > - "wake_alarm", "block_suspend", "audit_read", "perfmon", "bpf" > + "wake_alarm", "block_suspend", "audit_read", "perfmon", "bpf", \ > + "checkpoint_restore" > > -#if CAP_LAST_CAP > CAP_BPF > +#if CAP_LAST_CAP > CAP_CHECKPOINT_RESTORE > #error New capability defined, please update COMMON_CAP2_PERMS. > #endif > > -- > 2.26.2 >