All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Subject: [RFC PATCH v3 12/16] ceph: add encrypted fname handling to ceph_mdsc_build_path
Date: Mon, 14 Sep 2020 15:17:03 -0400	[thread overview]
Message-ID: <20200914191707.380444-13-jlayton@kernel.org> (raw)
In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org>

Allow ceph_mdsc_build_path to encrypt and base64 encode the filename
when the parent is encrypted and we're sending the path to the MDS.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/ceph/mds_client.c | 70 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 54 insertions(+), 16 deletions(-)

diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index e3dc061252d4..7eb504170981 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2314,18 +2314,27 @@ static inline  u64 __get_oldest_tid(struct ceph_mds_client *mdsc)
 	return mdsc->oldest_tid;
 }
 
-/*
- * Build a dentry's path.  Allocate on heap; caller must kfree.  Based
- * on build_path_from_dentry in fs/cifs/dir.c.
+/**
+ * ceph_mdsc_build_path - build a path string to a given dentry
+ * @dentry: dentry to which path should be built
+ * @plen: returned length of string
+ * @pbase: returned base inode number
+ * @for_wire: is this path going to be sent to the MDS?
+ *
+ * Build a string that represents the path to the dentry. This is mostly called
+ * for two different purposes:
+ *
+ * 1) we need to build a path string to send to the MDS (for_wire == true)
+ * 2) we need a path string for local presentation (e.g. debugfs) (for_wire == false)
  *
- * If @stop_on_nosnap, generate path relative to the first non-snapped
- * inode.
+ * The path is built in reverse, starting with the dentry. Walk back up toward
+ * the root, building the path until the first non-snapped inode is reached (for_wire)
+ * or the root inode is reached (!for_wire).
  *
  * Encode hidden .snap dirs as a double /, i.e.
  *   foo/.snap/bar -> foo//bar
  */
-char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase,
-			   int stop_on_nosnap)
+char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase, int for_wire)
 {
 	struct dentry *cur;
 	struct inode *inode;
@@ -2347,30 +2356,59 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase,
 	seq = read_seqbegin(&rename_lock);
 	cur = dget(dentry);
 	for (;;) {
-		struct dentry *temp;
+		struct dentry *parent;
 
 		spin_lock(&cur->d_lock);
 		inode = d_inode(cur);
+		parent = cur->d_parent;
 		if (inode && ceph_snap(inode) == CEPH_SNAPDIR) {
 			dout("build_path path+%d: %p SNAPDIR\n",
 			     pos, cur);
-		} else if (stop_on_nosnap && inode && dentry != cur &&
-			   ceph_snap(inode) == CEPH_NOSNAP) {
+			dget(parent);
+			spin_unlock(&cur->d_lock);
+		} else if (for_wire && inode && dentry != cur && ceph_snap(inode) == CEPH_NOSNAP) {
 			spin_unlock(&cur->d_lock);
 			pos++; /* get rid of any prepended '/' */
 			break;
-		} else {
+		} else if (!for_wire || !IS_ENCRYPTED(d_inode(parent))) {
 			pos -= cur->d_name.len;
 			if (pos < 0) {
 				spin_unlock(&cur->d_lock);
 				break;
 			}
 			memcpy(path + pos, cur->d_name.name, cur->d_name.len);
+			dget(parent);
+			spin_unlock(&cur->d_lock);
+		} else {
+			int err;
+			struct fscrypt_name fname = { };
+			int len;
+			char buf[FSCRYPT_BASE64_CHARS(NAME_MAX)];
+
+			dget(parent);
+			spin_unlock(&cur->d_lock);
+
+			err = fscrypt_setup_filename(d_inode(parent), &cur->d_name, 1, &fname);
+			if (err) {
+				dput(parent);
+				dput(cur);
+				return ERR_PTR(err);
+			}
+
+			/* base64 encode the encrypted name */
+			len = fscrypt_base64_encode(fname.disk_name.name, fname.disk_name.len, buf);
+			pos -= len;
+			if (pos < 0) {
+				dput(parent);
+				fscrypt_free_filename(&fname);
+				break;
+			}
+			memcpy(path + pos, buf, len);
+			dout("non-ciphertext name = %.*s\n", len, buf);
+			fscrypt_free_filename(&fname);
 		}
-		temp = cur;
-		cur = dget(temp->d_parent);
-		spin_unlock(&temp->d_lock);
-		dput(temp);
+		dput(cur);
+		cur = parent;
 
 		/* Are we at the root? */
 		if (IS_ROOT(cur))
@@ -2415,7 +2453,7 @@ static int build_dentry_path(struct dentry *dentry, struct inode *dir,
 	rcu_read_lock();
 	if (!dir)
 		dir = d_inode_rcu(dentry->d_parent);
-	if (dir && parent_locked && ceph_snap(dir) == CEPH_NOSNAP) {
+	if (dir && parent_locked && ceph_snap(dir) == CEPH_NOSNAP && !IS_ENCRYPTED(dir)) {
 		*pino = ceph_ino(dir);
 		rcu_read_unlock();
 		*ppath = dentry->d_name.name;
-- 
2.26.2


  parent reply	other threads:[~2020-09-14 19:18 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-14 19:16 [RFC PATCH v3 00/16] ceph+fscrypt: context, filename and symlink support Jeff Layton
2020-09-14 19:16 ` [RFC PATCH v3 01/16] vfs: export new_inode_pseudo Jeff Layton
2020-09-14 23:33   ` Eric Biggers
2020-09-23  3:41   ` Al Viro
2020-09-23 11:19     ` Jeff Layton
2020-09-14 19:16 ` [RFC PATCH v3 02/16] fscrypt: export fscrypt_base64_encode and fscrypt_base64_decode Jeff Layton
2020-09-14 23:44   ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 03/16] fscrypt: export fscrypt_d_revalidate Jeff Layton
2020-09-15  0:04   ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 04/16] fscrypt: add fscrypt_context_for_new_inode Jeff Layton
2020-09-15  0:15   ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 05/16] fscrypt: make fscrypt_fname_disk_to_usr return whether result is nokey name Jeff Layton
2020-09-15  0:23   ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 06/16] ceph: add fscrypt ioctls Jeff Layton
2020-09-15  0:45   ` Eric Biggers
2020-09-15 12:08     ` Jeff Layton
2020-09-14 19:16 ` [RFC PATCH v3 07/16] ceph: crypto context handling for ceph Jeff Layton
2020-09-15  1:00   ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 08/16] ceph: implement -o test_dummy_encryption mount option Jeff Layton
2020-09-15  1:23   ` Eric Biggers
2020-09-16 12:49     ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 09/16] ceph: preallocate inode for ops that may create one Jeff Layton
2020-09-15  1:30   ` Eric Biggers
2020-09-16 12:41     ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 10/16] ceph: add routine to create context prior to RPC Jeff Layton
2020-09-15  1:37   ` Eric Biggers
2020-09-16 12:18     ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 11/16] ceph: make ceph_msdc_build_path use ref-walk Jeff Layton
2020-09-14 19:17 ` Jeff Layton [this message]
2020-09-15  1:41   ` [RFC PATCH v3 12/16] ceph: add encrypted fname handling to ceph_mdsc_build_path Eric Biggers
2020-09-16 12:30     ` Jeff Layton
2020-09-16 17:36       ` Eric Biggers
2020-09-16 18:04         ` Jeff Layton
2020-09-16 18:42           ` Eric Biggers
2020-09-14 19:17 ` [RFC PATCH v3 13/16] ceph: make d_revalidate call fscrypt revalidator for encrypted dentries Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 14/16] ceph: add support to readdir for encrypted filenames Jeff Layton
2020-09-15  1:57   ` Eric Biggers
2020-09-15 13:27     ` Jeff Layton
2020-09-15 20:40       ` Eric Biggers
2020-09-16 12:16         ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 15/16] ceph: add fscrypt support to ceph_fill_trace Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 16/16] ceph: create symlinks with encrypted and base64-encoded targets Jeff Layton
2020-09-15  2:07   ` Eric Biggers
2020-09-15 14:05     ` Jeff Layton
2020-09-15 20:49       ` Eric Biggers
2020-09-16 12:15         ` Jeff Layton
2020-09-15  2:13 ` [RFC PATCH v3 00/16] ceph+fscrypt: context, filename and symlink support Eric Biggers
2020-09-15 13:38   ` Jeff Layton

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=20200914191707.380444-13-jlayton@kernel.org \
    --to=jlayton@kernel.org \
    --cc=ceph-devel@vger.kernel.org \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    /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.