From patchwork Wed Apr 8 15:21:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 221350 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8C7F9C2BB1D for ; Wed, 8 Apr 2020 15:22:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6F38D20747 for ; Wed, 8 Apr 2020 15:22:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729495AbgDHPWq (ORCPT ); Wed, 8 Apr 2020 11:22:46 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:39112 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729508AbgDHPWo (ORCPT ); Wed, 8 Apr 2020 11:22:44 -0400 Received: from ip5f5bd698.dynamic.kabel-deutschland.de ([95.91.214.152] helo=wittgenstein.fritz.box) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jMCXF-0001BO-9W; Wed, 08 Apr 2020 15:22:37 +0000 From: Christian Brauner To: Jens Axboe , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, linux-block@vger.kernel.org, linux-api@vger.kernel.org Cc: Jonathan Corbet , Serge Hallyn , "Rafael J. Wysocki" , Tejun Heo , "David S. Miller" , Christian Brauner , Saravana Kannan , Jan Kara , David Howells , Seth Forshee , David Rheinsberg , Tom Gundersen , Christian Kellner , Dmitry Vyukov , =?utf-8?q?St=C3=A9phane_Gr?= =?utf-8?q?aber?= , linux-doc@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH 3/8] loop: use ns_capable for some loop operations Date: Wed, 8 Apr 2020 17:21:46 +0200 Message-Id: <20200408152151.5780-4-christian.brauner@ubuntu.com> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200408152151.5780-1-christian.brauner@ubuntu.com> References: <20200408152151.5780-1-christian.brauner@ubuntu.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The following LOOP_GET_STATUS, LOOP_SET_STATUS, and LOOP_SET_BLOCK_SIZE operations are now allowed in non-initial namespaces. Most other operations were already possible before. Cc: Jens Axboe Cc: Seth Forshee Cc: Tom Gundersen Cc: Tejun Heo Cc: Christian Kellner Cc: Greg Kroah-Hartman Cc: "David S. Miller" Cc: David Rheinsberg Cc: Dmitry Vyukov Cc: "Rafael J. Wysocki" Signed-off-by: Christian Brauner --- drivers/block/loop.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index a7eda14be639..b1c3436d6e38 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1294,6 +1294,25 @@ void loopfs_remove_locked(struct loop_device *lo) loop_remove(lo); mutex_unlock(&loop_ctl_mutex); } + +static bool loop_capable(const struct loop_device *lo, int cap) +{ + struct super_block *sb; + struct user_namespace *ns; + + sb = loopfs_i_sb(lo->lo_loopfs_i); + if (sb) + ns = sb->s_user_ns; + else + ns = &init_user_ns; + + return ns_capable(ns, cap); +} +#else /* !CONFIG_BLK_DEV_LOOPFS */ +static inline bool loop_capable(const struct loop_device *lo, int cap) +{ + return capable(cap); +} #endif /* CONFIG_BLK_DEV_LOOPFS */ static int @@ -1310,7 +1329,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) return err; if (lo->lo_encrypt_key_size && !uid_eq(lo->lo_key_owner, uid) && - !capable(CAP_SYS_ADMIN)) { + !loop_capable(lo, CAP_SYS_ADMIN)) { err = -EPERM; goto out_unlock; } @@ -1441,7 +1460,7 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE); info->lo_encrypt_type = lo->lo_encryption ? lo->lo_encryption->number : 0; - if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) { + if (lo->lo_encrypt_key_size && loop_capable(lo, CAP_SYS_ADMIN)) { info->lo_encrypt_key_size = lo->lo_encrypt_key_size; memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, lo->lo_encrypt_key_size); @@ -1665,7 +1684,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, return loop_clr_fd(lo); case LOOP_SET_STATUS: err = -EPERM; - if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { + if ((mode & FMODE_WRITE) || loop_capable(lo, CAP_SYS_ADMIN)) { err = loop_set_status_old(lo, (struct loop_info __user *)arg); } @@ -1674,7 +1693,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, return loop_get_status_old(lo, (struct loop_info __user *) arg); case LOOP_SET_STATUS64: err = -EPERM; - if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { + if ((mode & FMODE_WRITE) || loop_capable(lo, CAP_SYS_ADMIN)) { err = loop_set_status64(lo, (struct loop_info64 __user *) arg); } @@ -1684,7 +1703,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_SET_CAPACITY: case LOOP_SET_DIRECT_IO: case LOOP_SET_BLOCK_SIZE: - if (!(mode & FMODE_WRITE) && !capable(CAP_SYS_ADMIN)) + if (!(mode & FMODE_WRITE) && !loop_capable(lo, CAP_SYS_ADMIN)) return -EPERM; /* Fall through */ default: