From patchwork Wed May 8 12:13:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 1097014 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=brauner.io Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=brauner.io header.i=@brauner.io header.b="V1wGfFLi"; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44zb3Y2Cz1z9s9T; Wed, 8 May 2019 22:13:29 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1hOLRr-00015r-Re; Wed, 08 May 2019 12:13:23 +0000 Received: from mail-wr1-f68.google.com ([209.85.221.68]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1hOLRp-00015e-Dv for kernel-team@lists.ubuntu.com; Wed, 08 May 2019 12:13:21 +0000 Received: by mail-wr1-f68.google.com with SMTP id v11so6771616wru.5 for ; Wed, 08 May 2019 05:13:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brauner.io; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=yFOt01YtKqd33gXo6IIDsLTErgAm22l2bHXOABRBVrA=; b=V1wGfFLiRNgXGAP7gTcTj6z9jYIx3pBe84/tqpIgPF/lyx4AEujP3AAJtHfE8vGI9o 3ZXONU/k/keEVVXQdEVrWCTA4BgpW8W00shD/52scAT+wNrRpam4pyiAJGUZXyruQ4Kk kMVFxDX4csLo1Qphc1rhRUpQanaDEyG89/xxmHi3zXjwR7eRVevtPB97Kc01fHf80TkL wbQMEwhY9swkdeGoo7ih594IuAKo5bV6ooSniiqhW7VrEou3oCnVxfUfYl4A7h4q7g7F A+WjCLzmH5hDy3qV9kmXkwLL+5V15Z3jiEzHeSTXJVc4VGhwZY/boaauV8/RQS/EP5Z2 WSHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=yFOt01YtKqd33gXo6IIDsLTErgAm22l2bHXOABRBVrA=; b=GvPtZNuIAkxf3/raJWxnsCemMICHrVzzw+H/4CsOsyWJoOSBmXackogwOTpohuFSSs oD2IM+J51bbURqc0+k73x2eLLmTbjPKzFnBw4lD1BVAWJDrOMuIuw5aBjoy1xgwqRl1m BlA1p6Xm3Ov4BHKQNtdyj8dVraopKY1aeUMs44mCT4225ZCockgfCePz3ODtbJhvg7hw +Ngf1cCuvkoqvko447uCULa9mZ32eXo8xfcfEOz7DwUAo5yLwp+bynYwRp4xC1hlwBGz 1ZErRAgBEH4SdjoFnpTNKabCiYn8YOWVDCtuvepi0wM4rdv11SU1DptO/CLf05Mp8pQS HqdA== X-Gm-Message-State: APjAAAX3VbKg5JJ5aLU3SNTTXqfL7tpiUer87vD63G8Kvb1rPzvLSCPz y8X0aTlASUSmoJD6I6GE7RpXYA== X-Google-Smtp-Source: APXvYqwxmyhTMk8XSS/Lue/EhqBkrTrAIkJUk+z8eyAhHLaExSdV//p0M9ESr2//48ExUww5PW/CvA== X-Received: by 2002:a5d:6304:: with SMTP id i4mr10747392wru.251.1557317600539; Wed, 08 May 2019 05:13:20 -0700 (PDT) Received: from localhost.localdomain (v22018046084765073.goodsrv.de. [185.183.158.195]) by smtp.gmail.com with ESMTPSA id c18sm14685913wrm.96.2019.05.08.05.13.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 May 2019 05:13:19 -0700 (PDT) From: Christian Brauner X-Google-Original-From: Christian Brauner To: seth.forshee@canonical.com, kernel-team@lists.ubuntu.com Subject: [PATCH v1][SRU][Disco] UBUNTU: SAUCE: shiftfs: lock down certain superblock flags Date: Wed, 8 May 2019 14:13:14 +0200 Message-Id: <20190508121314.23664-1-christian.brauner@ubuntu.com> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: stgraber@ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Christian Brauner BugLink: https://bugs.launchpad.net/bugs/1827122 This locks down various superblock flags to prevent userns-root from remounting a superblock with less restrictive options than the original mark or underlay mount. Signed-off-by: Christian Brauner Acked-by: Seth Forshee Acked-by: Kleber Sacilotto de Souza --- fs/shiftfs.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/fs/shiftfs.c b/fs/shiftfs.c index 9771165d1ce0..a1dae7ea593b 100644 --- a/fs/shiftfs.c +++ b/fs/shiftfs.c @@ -1808,6 +1808,33 @@ static inline bool passthrough_is_subset(int old_flags, int new_flags) return true; } +static int shiftfs_super_check_flags(unsigned long old_flags, + unsigned long new_flags) +{ + if ((old_flags & SB_RDONLY) && !(new_flags & SB_RDONLY)) + return -EPERM; + + if ((old_flags & SB_NOSUID) && !(new_flags & SB_NOSUID)) + return -EPERM; + + if ((old_flags & SB_NODEV) && !(new_flags & SB_NODEV)) + return -EPERM; + + if ((old_flags & SB_NOEXEC) && !(new_flags & SB_NOEXEC)) + return -EPERM; + + if ((old_flags & SB_NOATIME) && !(new_flags & SB_NOATIME)) + return -EPERM; + + if ((old_flags & SB_NODIRATIME) && !(new_flags & SB_NODIRATIME)) + return -EPERM; + + if (!(old_flags & SB_POSIXACL) && (new_flags & SB_POSIXACL)) + return -EPERM; + + return 0; +} + static int shiftfs_remount(struct super_block *sb, int *flags, char *data) { int err; @@ -1818,6 +1845,10 @@ static int shiftfs_remount(struct super_block *sb, int *flags, char *data) if (err) return err; + err = shiftfs_super_check_flags(sb->s_flags, *flags); + if (err) + return err; + /* Mark mount option cannot be changed. */ if (info->mark || (info->mark != new.mark)) return -EPERM; @@ -1847,6 +1878,16 @@ struct shiftfs_data { const char *path; }; +static void shiftfs_super_force_flags(struct super_block *sb, + unsigned long lower_flags) +{ + sb->s_flags |= lower_flags & (SB_RDONLY | SB_NOSUID | SB_NODEV | + SB_NOEXEC | SB_NOATIME | SB_NODIRATIME); + + if (!(lower_flags & SB_POSIXACL)) + sb->s_flags &= ~SB_POSIXACL; +} + static int shiftfs_fill_super(struct super_block *sb, void *raw_data, int silent) { @@ -1888,6 +1929,8 @@ static int shiftfs_fill_super(struct super_block *sb, void *raw_data, goto out_put_path; } + sb->s_flags |= SB_POSIXACL; + if (sbinfo->mark) { struct super_block *lower_sb = path.mnt->mnt_sb; @@ -1904,6 +1947,8 @@ static int shiftfs_fill_super(struct super_block *sb, void *raw_data, */ sb->s_iflags = SB_I_NOEXEC; + shiftfs_super_force_flags(sb, lower_sb->s_flags); + /* * Handle nesting of shiftfs mounts by referring this mark * mount back to the original mark mount. This is more @@ -1972,6 +2017,7 @@ static int shiftfs_fill_super(struct super_block *sb, void *raw_data, * passthrough settings. */ sbinfo->passthrough_mark = sbinfo_mp->passthrough; + shiftfs_super_force_flags(sb, path.mnt->mnt_sb->s_flags); } sb->s_stack_depth = dentry->d_sb->s_stack_depth + 1; @@ -1995,7 +2041,6 @@ static int shiftfs_fill_super(struct super_block *sb, void *raw_data, sb->s_op = &shiftfs_super_ops; sb->s_xattr = shiftfs_xattr_handlers; sb->s_d_op = &shiftfs_dentry_ops; - sb->s_flags |= SB_POSIXACL; sb->s_root = d_make_root(inode); if (!sb->s_root) { err = -ENOMEM;