From patchwork Thu Nov 24 00:47:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepa Dinamani X-Patchwork-Id: 9444593 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 28B4C600BA for ; Thu, 24 Nov 2016 00:50:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 25A4D279D1 for ; Thu, 24 Nov 2016 00:50:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1A68227DCD; Thu, 24 Nov 2016 00:50:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9F389279D1 for ; Thu, 24 Nov 2016 00:50:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936227AbcKXAtd (ORCPT ); Wed, 23 Nov 2016 19:49:33 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:33365 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935106AbcKXAsj (ORCPT ); Wed, 23 Nov 2016 19:48:39 -0500 Received: by mail-pg0-f66.google.com with SMTP id 3so2153244pgd.0; Wed, 23 Nov 2016 16:48:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=REufK+J8W18jUGZU2jVfIsxsc48RSQ5OMUT1/7p68Ng=; b=xmaYOI/q3mwBLJHx0q5+Q+Qkc5g11JxYQi2KZOCzQ7mOjcF8hpeZQUdyIbcAH3et5F bix+eM0IqbKhD6r47oBgxcRhEKyKiW2Qw4GW+597SxxzXNoJ1BXuB697qm+Kzd/gXUzz ceHxs1xpWYliRQsLH+mlVuqhLj7PHuTmlGAHsbZpKd4EU66Ub/Jb2QrTcXsgxkNUU+1L EiQmIfU47V63ihldABaYkQYBK9NHkWN+4eCjalhgWl+EBtU1dgIbX9MMVvJbrWNfYmG3 TwNpFsoPGkHfF9ns4xX3Dy9Q/tzecXeBFTvE4SqeiNaPZU4oiXbAMUHYZD84w/xDyQrE jqVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=REufK+J8W18jUGZU2jVfIsxsc48RSQ5OMUT1/7p68Ng=; b=D8t648d0BQl5GyrjURwQ3swOJN/Yj61+/+EtFkN0R36D7fCPaOj9eit5Xr3ETsYL5e 4vbzUf6d1Z/mjKb6euxq4etyBbvC1wn0IQcNK4M9Z19KeF6qhYoXt39BnVs8t5sESilb 5DHpy8Ga3haRGDUF3bcOjk5Jv8DVbBG8iSmGjDz0Wvy74C2nEhJ+3FDCggwS12TuLiPk b5kMF3KUM00IAWnk32e0iUO/AHvizLsNCDjht9oa4WVbDX94IhBKr3U0Zqdj1kvpbXrr ub6wb/YbQVtRwZSq4HIiGzloH5fjEjcztLnZ/fgSZ9SpkAjnSV289DN9Z3nexESLGEFj GU2Q== X-Gm-Message-State: AKaTC006aykRHfCMo6utjBQ13RhQXN0NVZnRVCSR8AVaLyHJWY33G4ZLwe1+fTFUlLPQ0Q== X-Received: by 10.98.79.193 with SMTP id f62mr5609954pfj.149.1479948489212; Wed, 23 Nov 2016 16:48:09 -0800 (PST) Received: from localhost.localdomain (c-24-6-102-171.hsd1.ca.comcast.net. [24.6.102.171]) by smtp.gmail.com with ESMTPSA id i11sm37364702pgn.17.2016.11.23.16.48.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 23 Nov 2016 16:48:08 -0800 (PST) From: Deepa Dinamani To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: arnd@arndb.de, tglx@linutronix.de, gregkh@linuxfoundation.org, akpm@linux-foundation.org, tytso@mit.edu, viro@zeniv.linux.org.uk, y2038@lists.linaro.org Subject: [RFC 2/6] vfs: Add checks for filesystem timestamp limits Date: Wed, 23 Nov 2016 16:47:46 -0800 Message-Id: <1479948470-2397-3-git-send-email-deepa.kernel@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1479948470-2397-1-git-send-email-deepa.kernel@gmail.com> References: <1479948470-2397-1-git-send-email-deepa.kernel@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Allow read only mounts for filesystems that do not have maximum timestamps beyond the y2038 expiry timestamp. Also, allow a sysctl override to all such filesystems to be mounted with write permissions. Alternatively, a mount option can be created to allow or disallow range check based clamps and the least max timestamp supported. If we take the sysctl approach, then the plan is to also add a boot param to support initial override of these checks without recompilation. Suggested-by: Arnd Bergmann Signed-off-by: Deepa Dinamani --- fs/inode.c | 5 +++++ fs/internal.h | 2 ++ fs/namespace.c | 12 ++++++++++++ fs/super.c | 7 +++++++ include/linux/fs.h | 1 + include/linux/time64.h | 4 ++++ include/uapi/linux/fs.h | 6 +++++- kernel/sysctl.c | 7 +++++++ 8 files changed, 43 insertions(+), 1 deletion(-) diff --git a/fs/inode.c b/fs/inode.c index 88110fd..7b2b78d 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -75,6 +75,11 @@ static DEFINE_PER_CPU(unsigned long, nr_unused); static struct kmem_cache *inode_cachep __read_mostly; +struct vfs_max_timestamp_check timestamp_check = { + .timestamp_supported = Y2038_EXPIRY_TIMESTAMP, + .check_on = 1, +}; + static long get_nr_inodes(void) { int i; diff --git a/fs/internal.h b/fs/internal.h index f4da334..5a144a8 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -67,6 +67,8 @@ extern int finish_automount(struct vfsmount *, struct path *); extern int sb_prepare_remount_readonly(struct super_block *); +extern bool sb_file_times_updatable(struct super_block *sb); + extern void __init mnt_init(void); extern int __mnt_want_write(struct vfsmount *); diff --git a/fs/namespace.c b/fs/namespace.c index 5ef9618..27eab32 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -543,6 +543,18 @@ static void __mnt_unmake_readonly(struct mount *mnt) unlock_mount_hash(); } +bool sb_file_times_updatable(struct super_block *sb) +{ + + if (!timestamp_check.check_on) + return true; + + if (sb->s_time_max > timestamp_check.timestamp_supported) + return true; + + return false; +} + int sb_prepare_remount_readonly(struct super_block *sb) { struct mount *mnt; diff --git a/fs/super.c b/fs/super.c index 27c973e..d21327f 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1199,6 +1199,13 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data) WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " "negative value (%lld)\n", type->name, sb->s_maxbytes); + if (!(sb->s_flags & MS_RDONLY) && !sb_file_times_updatable(sb)) { + WARN(1, "File times cannot be updated on the filesystem.\n"); + WARN(1, "Retry mounting the filesystem readonly.\n"); + error = -EROFS; + goto out_sb; + } + up_write(&sb->s_umount); free_secdata(secdata); return root; diff --git a/include/linux/fs.h b/include/linux/fs.h index 8eba822..b80d1e2 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -68,6 +68,7 @@ extern struct inodes_stat_t inodes_stat; extern int leases_enable, lease_break_time; extern int sysctl_protected_symlinks; extern int sysctl_protected_hardlinks; +extern struct vfs_max_timestamp_check timestamp_check; struct buffer_head; typedef int (get_block_t)(struct inode *inode, sector_t iblock, diff --git a/include/linux/time64.h b/include/linux/time64.h index 25433b18..906e0b3 100644 --- a/include/linux/time64.h +++ b/include/linux/time64.h @@ -43,6 +43,10 @@ struct itimerspec64 { #define KTIME_MAX ((s64)~((u64)1 << 63)) #define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) +/* Timestamps on boundary */ +#define Y2038_EXPIRY_TIMESTAMP S32_MAX /* 2147483647 */ +#define Y2106_EXPIRY_TIMESTAMP U32_MAX /* 4294967295 */ + #if __BITS_PER_LONG == 64 static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index c1d11df..07d225c 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -91,6 +91,11 @@ struct files_stat_struct { unsigned long max_files; /* tunable */ }; +struct vfs_max_timestamp_check { + time64_t timestamp_supported; + int check_on; +}; + struct inodes_stat_t { long nr_inodes; long nr_unused; @@ -100,7 +105,6 @@ struct inodes_stat_t { #define NR_FILE 8192 /* this can well be larger on a larger system */ - /* * These are the fs-independent mount-flags: up to 32 flags are supported */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 1475d25..b6030d5 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1667,6 +1667,13 @@ static struct ctl_table fs_table[] = { .proc_handler = proc_doulongvec_minmax, }, { + .procname = "fs-timestamp-check-on", + .data = ×tamp_check.check_on, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { .procname = "nr_open", .data = &sysctl_nr_open, .maxlen = sizeof(unsigned int),