All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: "J . Bruce Fields" <bfields@fieldses.org>,
	Jeff Layton <jlayton@poochiereds.net>,
	Mimi Zohar <zohar@linux.ibm.com>,
	Al Viro <viro@zeniv.linux.org.uk>,
	linux-fsdevel@vger.kernel.org, linux-unionfs@vger.kernel.org,
	linux-integrity@vger.kernel.org
Subject: [PATCH 1/2] vfs: replace i_readcount with a biased i_count
Date: Sat,  8 Jun 2019 16:57:16 +0300	[thread overview]
Message-ID: <20190608135717.8472-2-amir73il@gmail.com> (raw)
In-Reply-To: <20190608135717.8472-1-amir73il@gmail.com>

Count struct files open RO together with inode reference count instead
of using a dedicated i_readcount field.  This will allow us to use the
RO count also when CONFIG_IMA is not defined and will reduce the size of
struct inode for 32bit archs when CONFIG_IMA is defined.

We need this RO count for posix leases code, which currently naively
checks i_count and d_count in an inaccurate manner.

Should regular i_count overflow into RO count bias by struct files
opened for write, it's not a big deal, as we mostly need the RO count
to be reliable when the first writer comes along.

Cc: <stable@vger.kernel.org> # v4.19
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 include/linux/fs.h                | 33 +++++++++++++++++++------------
 security/integrity/ima/ima_main.c |  2 +-
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index f7fdfe93e25d..504bf17967dd 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -694,9 +694,6 @@ struct inode {
 	atomic_t		i_count;
 	atomic_t		i_dio_count;
 	atomic_t		i_writecount;
-#ifdef CONFIG_IMA
-	atomic_t		i_readcount; /* struct files open RO */
-#endif
 	union {
 		const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
 		void (*free_inode)(struct inode *);
@@ -2890,26 +2887,36 @@ static inline bool inode_is_open_for_write(const struct inode *inode)
 	return atomic_read(&inode->i_writecount) > 0;
 }
 
-#ifdef CONFIG_IMA
+/*
+ * Count struct files open RO together with inode rerefernce count.
+ * We need this count for IMA and for posix leases. The RO count should not
+ * include files opened RDWR nor files opened O_PATH and internal kernel
+ * inode references, like the ones taken by overlayfs and inotify.
+ * Should regular i_count overflow into I_RO_COUNT_BIAS by struct files
+ * opened for write, it's not a big deal, as we mostly need
+ * inode_is_open_rdonly() to be reliable when the first writer comes along.
+ */
+#define I_RO_COUNT_SHIFT 10
+#define I_RO_COUNT_BIAS	(1UL << I_RO_COUNT_SHIFT)
+
 static inline void i_readcount_dec(struct inode *inode)
 {
-	BUG_ON(!atomic_read(&inode->i_readcount));
-	atomic_dec(&inode->i_readcount);
+	WARN_ON(atomic_read(&inode->i_count) < I_RO_COUNT_BIAS);
+	atomic_sub(I_RO_COUNT_BIAS, &inode->i_count);
 }
 static inline void i_readcount_inc(struct inode *inode)
 {
-	atomic_inc(&inode->i_readcount);
+	atomic_add(I_RO_COUNT_BIAS, &inode->i_count);
 }
-#else
-static inline void i_readcount_dec(struct inode *inode)
+static inline int i_readcount_read(const struct inode *inode)
 {
-	return;
+	return atomic_read(&inode->i_count) >> I_RO_COUNT_SHIFT;
 }
-static inline void i_readcount_inc(struct inode *inode)
+static inline bool inode_is_open_rdonly(const struct inode *inode)
 {
-	return;
+	return atomic_read(&inode->i_count) > I_RO_COUNT_BIAS;
 }
-#endif
+
 extern int do_pipe_flags(int *, int);
 
 #define __kernel_read_file_id(id) \
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 357edd140c09..766bac778d11 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -94,7 +94,7 @@ static void ima_rdwr_violation_check(struct file *file,
 	bool send_tomtou = false, send_writers = false;
 
 	if (mode & FMODE_WRITE) {
-		if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) {
+		if (inode_is_open_rdonly(inode) && IS_IMA(inode)) {
 			if (!iint)
 				iint = integrity_iint_find(inode);
 			/* IMA_MEASURE is set from reader side */
-- 
2.17.1

  reply	other threads:[~2019-06-08 13:57 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-08 13:57 [PATCH 0/2] Fix write leases on overlayfs Amir Goldstein
2019-06-08 13:57 ` Amir Goldstein [this message]
2019-06-09 19:36   ` [PATCH 1/2] vfs: replace i_readcount with a biased i_count Miklos Szeredi
     [not found]   ` <20190610151836.5E2A3207E0@mail.kernel.org>
2019-06-10 16:37     ` Amir Goldstein
2019-06-12 12:51   ` Mimi Zohar
2019-06-12 15:09     ` Amir Goldstein
2019-06-12 15:29       ` J . Bruce Fields
2019-06-12 15:35         ` Amir Goldstein
2019-06-12 15:59       ` Mimi Zohar
2019-06-08 13:57 ` [PATCH 2/2] locks: eliminate false positive conflicts for write lease Amir Goldstein
     [not found]   ` <20190610151835.2FFC12089E@mail.kernel.org>
2019-06-10 16:38     ` Amir Goldstein

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190608135717.8472-2-amir73il@gmail.com \
    --to=amir73il@gmail.com \
    --cc=bfields@fieldses.org \
    --cc=jlayton@poochiereds.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=viro@zeniv.linux.org.uk \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.