lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190429045359.8923-9-ira.weiny@intel.com>
Date:   Sun, 28 Apr 2019 21:53:57 -0700
From:   ira.weiny@...el.com
To:     lsf-pc@...ts.linux-foundation.org
Cc:     linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
        linux-mm@...ck.org, Dan Williams <dan.j.williams@...el.com>,
        Jan Kara <jack@...e.cz>,
        Jérôme Glisse <jglisse@...hat.com>,
        John Hubbard <jhubbard@...dia.com>,
        Michal Hocko <mhocko@...e.com>, Ira Weiny <ira.weiny@...el.com>
Subject: [RFC PATCH 08/10] mm/gup: fs: Send SIGBUS on truncate of active file

From: Ira Weiny <ira.weiny@...el.com>

Now that the taking of LONGTERM leases is in place we can now facilitate
sending a SIGBUS to process if a file truncate or hole punch is
performed and they do not respond by releasing the lease.

The standard file lease_break_time is used to time out the LONGTERM
lease which is in place on the inode.
---
 fs/ext4/inode.c    |  4 ++++
 fs/locks.c         | 13 +++++++++++--
 fs/xfs/xfs_file.c  |  4 ++++
 include/linux/fs.h | 13 +++++++++++++
 4 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index b32a57bc5d5d..bee456c8c805 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4237,6 +4237,10 @@ int ext4_break_layouts(struct inode *inode)
 	if (WARN_ON_ONCE(!rwsem_is_locked(&ei->i_mmap_sem)))
 		return -EINVAL;
 
+	/* Break longterm leases */
+	if (dax_mapping_is_dax(inode->i_mapping))
+		break_longterm(inode);
+
 	do {
 		page = dax_layout_busy_page(inode->i_mapping);
 		if (!page)
diff --git a/fs/locks.c b/fs/locks.c
index 58c6d7a411b6..c77eee081d11 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1580,6 +1580,7 @@ static void time_out_leases(struct inode *inode, struct list_head *dispose)
 {
 	struct file_lock_context *ctx = inode->i_flctx;
 	struct file_lock *fl, *tmp;
+	struct task_struct *tsk;
 
 	lockdep_assert_held(&ctx->flc_lock);
 
@@ -1587,8 +1588,16 @@ static void time_out_leases(struct inode *inode, struct list_head *dispose)
 		trace_time_out_leases(inode, fl);
 		if (past_time(fl->fl_downgrade_time))
 			lease_modify(fl, F_RDLCK, dispose);
-		if (past_time(fl->fl_break_time))
-			lease_modify(fl, F_UNLCK, dispose);
+		if (past_time(fl->fl_break_time)) {
+			if (fl->fl_flags & FL_LONGTERM) {
+				tsk = find_task_by_vpid(fl->fl_pid);
+				fl->fl_break_time = 1 + jiffies + lease_break_time * HZ;
+				lease_modify_longterm(fl, F_UNLCK, dispose);
+				kill_pid(tsk->thread_pid, SIGBUS, 0);
+			} else {
+				lease_modify(fl, F_UNLCK, dispose);
+			}
+		}
 	}
 }
 
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 1f2e2845eb76..ebd310f3ae65 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -739,6 +739,10 @@ xfs_break_dax_layouts(
 
 	ASSERT(xfs_isilocked(XFS_I(inode), XFS_MMAPLOCK_EXCL));
 
+	/* Break longterm leases */
+	if (dax_mapping_is_dax(inode->i_mapping))
+		break_longterm(inode);
+
 	page = dax_layout_busy_page(inode->i_mapping);
 	if (!page)
 		return 0;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index be2d08080aa5..0e8b21240a71 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2459,6 +2459,14 @@ static inline int break_layout(struct inode *inode, bool wait)
 	return 0;
 }
 
+static inline int break_longterm(struct inode *inode)
+{
+	smp_mb();
+	if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease))
+		return __break_lease(inode, O_WRONLY, FL_LONGTERM);
+	return 0;
+}
+
 #else /* !CONFIG_FILE_LOCKING */
 static inline int break_lease(struct inode *inode, unsigned int mode)
 {
@@ -2486,6 +2494,11 @@ static inline int break_layout(struct inode *inode, bool wait)
 	return 0;
 }
 
+static inline int break_longterm(struct inode *inode, bool wait)
+{
+	return 0;
+}
+
 #endif /* CONFIG_FILE_LOCKING */
 
 /* fs/open.c */
-- 
2.20.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ