linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net
Cc: Jaegeuk Kim <jaegeuk@kernel.org>,
	Michael Halcrow <mhalcrow@google.com>,
	Theodore Ts'o <tytso@mit.edu>
Subject: [PATCH 10/18] f2fs crypto: activate encryption support for fs APIs
Date: Fri,  8 May 2015 21:20:45 -0700	[thread overview]
Message-ID: <1431145253-2019-10-git-send-email-jaegeuk@kernel.org> (raw)
In-Reply-To: <1431145253-2019-1-git-send-email-jaegeuk@kernel.org>

This patch activates the following APIs for encryption support.

The rules quoted by ext4 are:
 - An unencrypted directory may contain encrypted or unencrypted files
   or directories.
 - All files or directories in a directory must be protected using the
   same key as their containing directory.
 - Encrypted inode for regular file should not have inline_data.
 - Encrypted symlink and directory may have inline_data and inline_dentry.

This patch activates the following APIs.
1. f2fs_link              : validate context
2. f2fs_lookup            :      ''
3. f2fs_rename            :      ''
4. f2fs_create/f2fs_mkdir : inherit its dir's context
5. f2fs_direct_IO         : do buffered io for regular files
6. f2fs_open              : check encryption info
7. f2fs_file_mmap         :      ''
8. f2fs_setattr           :      ''
9. f2fs_file_write_iter   :      ''           (Called by sys_io_submit)

Signed-off-by: Michael Halcrow <mhalcrow@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/data.c   |  3 +++
 fs/f2fs/dir.c    |  6 ++++++
 fs/f2fs/f2fs.h   | 11 +++++++++++
 fs/f2fs/file.c   | 34 ++++++++++++++++++++++++++++++++--
 fs/f2fs/inline.c |  3 +++
 fs/f2fs/namei.c  | 38 ++++++++++++++++++++++++++++++++------
 6 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 842fcdd..473b4d4 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1982,6 +1982,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
 			return err;
 	}
 
+	if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
+		return 0;
+
 	if (check_direct_IO(inode, iter, offset))
 		return 0;
 
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 9d558d2..f7293a2 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -390,6 +390,12 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
 		err = f2fs_init_security(inode, dir, name, page);
 		if (err)
 			goto put_error;
+
+		if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) {
+			err = f2fs_inherit_context(dir, inode, page);
+			if (err)
+				goto put_error;
+		}
 	} else {
 		page = get_node_page(F2FS_I_SB(dir), inode->i_ino);
 		if (IS_ERR(page))
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index e99205b..544766e 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1975,6 +1975,17 @@ static inline int f2fs_sb_has_crypto(struct super_block *sb)
 #endif
 }
 
+static inline bool f2fs_may_encrypt(struct inode *inode)
+{
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+	mode_t mode = inode->i_mode;
+
+	return (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode));
+#else
+	return 0;
+#endif
+}
+
 /* crypto_policy.c */
 int f2fs_is_child_context_consistent_with_parent(struct inode *,
 							struct inode *);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 7236be4..9f4b34c 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -408,6 +408,12 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct inode *inode = file_inode(file);
 
+	if (f2fs_encrypted_inode(inode)) {
+		int err = f2fs_get_encryption_info(inode);
+		if (err)
+			return 0;
+	}
+
 	/* we don't need to use inline_data strictly */
 	if (f2fs_has_inline_data(inode)) {
 		int err = f2fs_convert_inline_inode(inode);
@@ -420,6 +426,14 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma)
 	return 0;
 }
 
+static int f2fs_file_open(struct inode *inode, struct file *filp)
+{
+	if (f2fs_encrypted_inode(inode) && f2fs_get_encryption_info(inode))
+		return -EACCES;
+
+	return generic_file_open(inode, filp);
+}
+
 int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
 {
 	int nr_free = 0, ofs = dn->ofs_in_node;
@@ -627,6 +641,10 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
 		return err;
 
 	if (attr->ia_valid & ATTR_SIZE) {
+		if (f2fs_encrypted_inode(inode) &&
+				f2fs_get_encryption_info(inode))
+			return -EACCES;
+
 		if (attr->ia_size != i_size_read(inode)) {
 			truncate_setsize(inode, attr->ia_size);
 			f2fs_truncate(inode);
@@ -1466,6 +1484,18 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	}
 }
 
+static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+
+	if (f2fs_encrypted_inode(inode) &&
+				!f2fs_has_encryption_key(inode) &&
+				f2fs_get_encryption_info(inode))
+		return -EACCES;
+
+	return generic_file_write_iter(iocb, from);
+}
+
 #ifdef CONFIG_COMPAT
 long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
@@ -1486,8 +1516,8 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 const struct file_operations f2fs_file_operations = {
 	.llseek		= f2fs_llseek,
 	.read_iter	= generic_file_read_iter,
-	.write_iter	= generic_file_write_iter,
-	.open		= generic_file_open,
+	.write_iter	= f2fs_file_write_iter,
+	.open		= f2fs_file_open,
 	.release	= f2fs_release_file,
 	.mmap		= f2fs_file_mmap,
 	.fsync		= f2fs_sync_file,
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index d9b3033..5f5b34b 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -27,6 +27,9 @@ bool f2fs_may_inline_data(struct inode *inode)
 	if (i_size_read(inode) > MAX_INLINE_DATA)
 		return false;
 
+	if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
+		return false;
+
 	return true;
 }
 
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 90a9640..bc8992e 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -56,6 +56,10 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
 		goto out;
 	}
 
+	/* If the directory encrypted, then we should encrypt the inode. */
+	if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode))
+		f2fs_set_encrypted_inode(inode);
+
 	if (f2fs_may_inline_data(inode))
 		set_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
 	if (f2fs_may_inline_dentry(inode))
@@ -157,6 +161,10 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
 	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
 	int err;
 
+	if (f2fs_encrypted_inode(dir) &&
+		!f2fs_is_child_context_consistent_with_parent(dir, inode))
+		return -EPERM;
+
 	f2fs_balance_fs(sbi);
 
 	inode->i_ctime = CURRENT_TIME;
@@ -235,6 +243,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
 	struct f2fs_dir_entry *de;
 	struct page *page;
 	nid_t ino;
+	int err = 0;
 
 	if (dentry->d_name.len > F2FS_NAME_LEN)
 		return ERR_PTR(-ENAMETOOLONG);
@@ -251,16 +260,26 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
 	if (IS_ERR(inode))
 		return ERR_CAST(inode);
 
-	if (f2fs_has_inline_dots(inode)) {
-		int err;
+	if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode) &&
+		!f2fs_is_child_context_consistent_with_parent(dir, inode)) {
+		iput(inode);
+		f2fs_msg(inode->i_sb, KERN_WARNING,
+				"Inconsistent encryption contexts: %lu/%lu\n",
+				(unsigned long)dir->i_ino,
+				(unsigned long)inode->i_ino);
+		return ERR_PTR(-EPERM);
+	}
 
+	if (f2fs_has_inline_dots(inode)) {
 		err = __recover_dot_dentries(inode, dir->i_ino);
-		if (err) {
-			iget_failed(inode);
-			return ERR_PTR(err);
-		}
+		if (err)
+			goto err_out;
 	}
 	return d_splice_alias(inode, dentry);
+
+err_out:
+	iget_failed(inode);
+	return ERR_PTR(err);
 }
 
 static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
@@ -460,6 +479,13 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	struct f2fs_dir_entry *new_entry;
 	int err = -ENOENT;
 
+	if ((old_dir != new_dir) && f2fs_encrypted_inode(new_dir) &&
+		!f2fs_is_child_context_consistent_with_parent(new_dir,
+							old_inode)) {
+		err = -EPERM;
+		goto out;
+	}
+
 	f2fs_balance_fs(sbi);
 
 	old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page);
-- 
2.1.1


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y

  parent reply	other threads:[~2015-05-09  4:21 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-09  4:20 [PATCH 01/18] f2fs: avoid value overflow in showing current status Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 02/18] f2fs: report unwritten area in f2fs_fiemap Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 03/18] f2fs crypto: declare some definitions for f2fs encryption feature Jaegeuk Kim
2015-05-13  2:02   ` Dave Chinner
2015-05-13  2:23     ` nick
2015-05-13  6:48     ` Jaegeuk Kim
2015-05-14  0:37       ` Dave Chinner
2015-05-14  1:56         ` Jaegeuk Kim
2015-05-14 16:50           ` Tom Marshall
2015-05-16  1:14             ` Jaegeuk Kim
2015-05-16  4:47               ` Tom Marshall
2015-05-18  6:24                 ` Jaegeuk Kim
2015-05-16 13:24         ` Theodore Ts'o
2015-05-16 17:13           ` Tom Marshall
2015-05-09  4:20 ` [PATCH 04/18] f2fs crypto: add f2fs encryption Kconfig Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 05/18] f2fs crypto: add encryption xattr support Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 06/18] f2fs crypto: add encryption policy and password salt support Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 07/18] f2fs crypto: add f2fs encryption facilities Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 08/18] f2fs crypto: add encryption key management facilities Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 09/18] f2fs crypto: filename encryption facilities Jaegeuk Kim
2015-05-09  4:20 ` Jaegeuk Kim [this message]
2015-05-09  4:20 ` [PATCH 11/18] f2fs crypto: add encryption support in read/write paths Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 12/18] f2fs crypto: add filename encryption for f2fs_add_link Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 13/18] f2fs crypto: add filename encryption for f2fs_readdir Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 14/18] f2fs crypto: add filename encryption for f2fs_lookup Jaegeuk Kim
2015-05-11  2:52   ` hujianyang
2015-05-11  5:12     ` [f2fs-dev] " Jaegeuk Kim
2015-05-11  6:38       ` hujianyang
2015-05-09  4:20 ` [PATCH 15/18] f2fs crypto: add filename encryption for roll-forward recovery Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 16/18] f2fs crypto: add symlink encryption Jaegeuk Kim
2015-05-09  4:25   ` Al Viro
2015-05-11  5:15     ` Jaegeuk Kim
2015-05-12  3:48   ` [PATCH 16/18 v2] " Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 17/18] f2fs crypto: fix missing key when reading a page Jaegeuk Kim
2015-05-09  4:20 ` [PATCH 18/18] f2fs crypto: remove checking key context during lookup Jaegeuk Kim

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=1431145253-2019-10-git-send-email-jaegeuk@kernel.org \
    --to=jaegeuk@kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhalcrow@google.com \
    --cc=tytso@mit.edu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).