ceph-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: "Luís Henriques" <lhenriques@suse.de>, "Xiubo Li" <xiubli@redhat.com>
Cc: idryomov@gmail.com, ceph-devel@vger.kernel.org,
	vshankar@redhat.com, mchangir@redhat.com
Subject: Re: [PATCH v16 25/68] ceph: make d_revalidate call fscrypt revalidator for encrypted dentries
Date: Wed, 08 Mar 2023 12:54:43 -0500	[thread overview]
Message-ID: <406dc339c219d98639b752342136461f5070f259.camel@kernel.org> (raw)
In-Reply-To: <87fsaf88sc.fsf@suse.de>

On Wed, 2023-03-08 at 17:14 +0000, Luís Henriques wrote:
> Xiubo Li <xiubli@redhat.com> writes:
> 
> > On 08/03/2023 17:29, Luís Henriques wrote:
> > > Xiubo Li <xiubli@redhat.com> writes:
> > > 
> > > > On 08/03/2023 02:53, Luís Henriques wrote:
> > > > > xiubli@redhat.com writes:
> > > > > 
> > > > > > From: Jeff Layton <jlayton@kernel.org>
> > > > > > 
> > > > > > If we have a dentry which represents a no-key name, then we need to test
> > > > > > whether the parent directory's encryption key has since been added.  Do
> > > > > > that before we test anything else about the dentry.
> > > > > > 
> > > > > > Reviewed-by: Xiubo Li <xiubli@redhat.com>
> > > > > > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > > > > > ---
> > > > > >     fs/ceph/dir.c | 8 ++++++--
> > > > > >     1 file changed, 6 insertions(+), 2 deletions(-)
> > > > > > 
> > > > > > diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
> > > > > > index d3c2853bb0f1..5ead9f59e693 100644
> > > > > > --- a/fs/ceph/dir.c
> > > > > > +++ b/fs/ceph/dir.c
> > > > > > @@ -1770,6 +1770,10 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
> > > > > >     	struct inode *dir, *inode;
> > > > > >     	struct ceph_mds_client *mdsc;
> > > > > >     +	valid = fscrypt_d_revalidate(dentry, flags);
> > > > > > +	if (valid <= 0)
> > > > > > +		return valid;
> > > > > > +
> > > > > This patch has confused me in the past, and today I found myself
> > > > > scratching my head again looking at it.
> > > > > 
> > > > > So, I've started seeing generic/123 test failing when running it with
> > > > > test_dummy_encryption.  I was almost sure that this test used to run fine
> > > > > before, but I couldn't find any evidence (somehow I lost my old testing
> > > > > logs...).
> > > > > 
> > > > > Anyway, the test is quite simple:
> > > > > 
> > > > > 1. Creates a directory with write permissions for root only
> > > > > 2. Writes into a file in that directory
> > > > > 3. Uses 'su' to try to modify that file as a different user, and
> > > > >       gets -EPERM
> > > > > 
> > > > > All these steps run fine, and the test should pass.  *However*, in the
> > > > > test cleanup function, a simple 'rm -rf <dir>' will fail with -ENOTEMPTY.
> > > > > 'strace' shows that calling unlinkat() to remove the file got a '-ENOENT'
> > > > > and then -ENOTEMPTY for the directory.
> > > > > 
> > > > > Some digging allowed me to figure out that running commands with 'su' will
> > > > > drop caches (I see 'su (874): drop_caches: 2' in the log).  And this is
> > > > > how I ended up looking at this patch.  fscrypt_d_revalidate() will return
> > > > > '0' if the parent directory does has a key (fscrypt_has_encryption_key()).
> > > > > Can we really say here that the dentry is *not* valid in that case?  Or
> > > > > should that '<= 0' be a '< 0'?
> > > > > 
> > > > > (But again, this patch has confused me before...)
> > > > Luis,
> > > > 
> > > > Could you reproduce it with the latest testing branch ?
> > > Yes, I'm seeing this with the latest code.
> > 
> > Okay. That's odd.
> > 
> > BTW, are you using the non-root user to run the test ?
> > 
> > Locally I am using the root user and still couldn't reproduce it.
> 
> Yes, I'm running the tests as root but I've also 'fsgqa' user in the
> system (which is used by this test.  Anyway, for reference, here's what
> I'm using in my fstests configuration:
> 
> TEST_FS_MOUNT_OPTS="-o name=admin,secret=<key>,copyfrom,ms_mode=crc,test_dummy_encryption"
> MOUNT_OPTIONS="-o name=admin,secret=<key>,copyfrom,ms_mode=crc,test_dummy_encryption"
> 
> > > 
> > > > I never seen the generic/123 failure yet. And just now I ran the test for many
> > > > times locally it worked fine.
> > > That's odd.  With 'test_dummy_encryption' mount option I can reproduce it
> > > every time.
> > > 
> > > >   From the generic/123 test code it will never touch the key while testing, that
> > > > means the dentries under the test dir will always have the keyed name. And then
> > > > the 'fscrypt_d_revalidate()' should return 1 always.
> > > > 
> > > > Only when we remove the key will it trigger evicting the inodes and then when we
> > > > add the key back will the 'fscrypt_d_revalidate()' return 0 by checking the
> > > > 'fscrypt_has_encryption_key()'.
> > > > 
> > > > As I remembered we have one or more fixes about this those days, not sure
> > > > whether you were hitting those bugs we have already fixed ?
> > > Yeah, I remember now, and I guess there's yet another one here!
> > > 
> > > I'll look closer into this and see if I can find out something else.  I'm
> > > definitely seeing 'fscrypt_d_revalidate()' returning 0, so probably the
> > > bug is in the error paths, when the 'fsgqa' user tries to write into the
> > > file.
> > 
> > Please add some debug logs in the code.
> 
> I *think* I've something.  The problem seems to be that, after the
> drop_caches, the test directory is evicted and ceph_evict_inode() will
> call fscrypt_put_encryption_info().  This last function will clear the
> inode fscrypt info.  Later on, when the test tries to write to the file
> with:
> 
>   _user_do "echo goo >> $my_test_subdir/data_coherency.txt"
> 
> function ceph_atomic_open() will correctly identify that '$my_test_subdir'
> is encrypted, but the key isn't set because the inode was evicted.  This
> means that fscrypt_has_encryption_key() will return '0' and DCACHE_NOKEY_NAME
> will be *incorrectly* added to the 'data_coherency.txt' dentry flags.
> 
> Later on, ceph_d_revalidate() will see the problem I initially described.
> 
> The (RFC) patch bellow seems to fix the issue.  Basically, it will force
> the fscrypt info to be set in the directory by calling __fscrypt_prepare_readdir()
> and the fscrypt_has_encryption_key() will then return 'true'.
> 


> Cheers
> --
> Luís
> 
> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> index dee3b445f415..3f2df84a6323 100644
> --- a/fs/ceph/file.c
> +++ b/fs/ceph/file.c
> @@ -795,7 +795,8 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
>  	ihold(dir);
>  	if (IS_ENCRYPTED(dir)) {
>  		set_bit(CEPH_MDS_R_FSCRYPT_FILE, &req->r_req_flags);
> -		if (!fscrypt_has_encryption_key(dir)) {
> +		err = __fscrypt_prepare_readdir(dir);

I want to say that i had something like this in place during an earlier
version of this series, but for different reasons. I think I convinced
myself later though that it wasn't needed? Oh well...

> +		if (err || (!err && !fscrypt_has_encryption_key(dir))) {
>  			spin_lock(&dentry->d_lock);
>  			dentry->d_flags |= DCACHE_NOKEY_NAME;
>  			spin_unlock(&dentry->d_lock);

Once an inode is evicted, my understanding was that it won't end up
being used anymore. It's on its way out of the cache and it's not hashed
anymore at that point.

How does a new atomic open after drop_caches end up with the inode
struct that existed before it?
-- 
Jeff Layton <jlayton@kernel.org>

  reply	other threads:[~2023-03-08 17:54 UTC|newest]

Thread overview: 84+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-27  3:27 [PATCH v16 00/68] ceph+fscrypt: full support xiubli
2023-02-27  3:27 ` [PATCH v16 01/68] libceph: add spinlock around osd->o_requests xiubli
2023-02-27  3:27 ` [PATCH v16 02/68] libceph: define struct ceph_sparse_extent and add some helpers xiubli
2023-02-27  3:27 ` [PATCH v16 03/68] libceph: add sparse read support to msgr2 crc state machine xiubli
2023-02-27  3:27 ` [PATCH v16 04/68] libceph: add sparse read support to OSD client xiubli
2023-02-27  3:27 ` [PATCH v16 05/68] libceph: support sparse reads on msgr2 secure codepath xiubli
2023-02-27  3:27 ` [PATCH v16 06/68] libceph: add sparse read support to msgr1 xiubli
2023-02-27  3:27 ` [PATCH v16 07/68] ceph: add new mount option to enable sparse reads xiubli
2023-02-27  3:27 ` [PATCH v16 08/68] ceph: preallocate inode for ops that may create one xiubli
2023-02-27  3:27 ` [PATCH v16 09/68] ceph: make ceph_msdc_build_path use ref-walk xiubli
2023-02-27  3:27 ` [PATCH v16 10/68] libceph: add new iov_iter-based ceph_msg_data_type and ceph_osd_data_type xiubli
2023-02-27  3:27 ` [PATCH v16 11/68] ceph: use osd_req_op_extent_osd_iter for netfs reads xiubli
2023-02-27  3:27 ` [PATCH v16 12/68] ceph: fscrypt_auth handling for ceph xiubli
2023-02-27  3:27 ` [PATCH v16 13/68] ceph: ensure that we accept a new context from MDS for new inodes xiubli
2023-02-27  3:27 ` [PATCH v16 14/68] ceph: add support for fscrypt_auth/fscrypt_file to cap messages xiubli
2023-02-27  3:27 ` [PATCH v16 15/68] ceph: implement -o test_dummy_encryption mount option xiubli
2023-02-27  3:27 ` [PATCH v16 16/68] ceph: decode alternate_name in lease info xiubli
2023-02-27  3:27 ` [PATCH v16 17/68] ceph: add fscrypt ioctls xiubli
2023-02-27  3:27 ` [PATCH v16 18/68] ceph: make the ioctl cmd more readable in debug log xiubli
2023-02-27  3:27 ` [PATCH v16 19/68] ceph: add base64 endcoding routines for encrypted names xiubli
2023-02-27  3:27 ` [PATCH v16 20/68] ceph: add encrypted fname handling to ceph_mdsc_build_path xiubli
2023-02-27  3:27 ` [PATCH v16 21/68] ceph: send altname in MClientRequest xiubli
2023-02-27  3:27 ` [PATCH v16 22/68] ceph: encode encrypted name in dentry release xiubli
2023-02-27  3:27 ` [PATCH v16 23/68] ceph: properly set DCACHE_NOKEY_NAME flag in lookup xiubli
2023-02-27  3:27 ` [PATCH v16 24/68] ceph: set DCACHE_NOKEY_NAME in atomic open xiubli
2023-02-27  3:27 ` [PATCH v16 25/68] ceph: make d_revalidate call fscrypt revalidator for encrypted dentries xiubli
2023-03-07 18:53   ` Luís Henriques
2023-03-08  1:50     ` Xiubo Li
2023-03-08  9:29       ` Luís Henriques
2023-03-08 10:42         ` Xiubo Li
2023-03-08 17:14           ` Luís Henriques
2023-03-08 17:54             ` Jeff Layton [this message]
2023-03-08 18:30               ` Luís Henriques
2023-03-08 19:32                 ` Jeff Layton
2023-03-09  9:52                   ` Luís Henriques
2023-03-09  7:06             ` Xiubo Li
2023-03-09  9:55               ` Luís Henriques
2023-03-09 11:41                 ` Xiubo Li
2023-02-27  3:27 ` [PATCH v16 26/68] ceph: add helpers for converting names for userland presentation xiubli
2023-02-27  3:27 ` [PATCH v16 27/68] ceph: fix base64 encoded name's length check in ceph_fname_to_usr() xiubli
2023-02-27  3:27 ` [PATCH v16 28/68] ceph: add fscrypt support to ceph_fill_trace xiubli
2023-02-27  3:27 ` [PATCH v16 29/68] ceph: pass the request to parse_reply_info_readdir() xiubli
2023-02-27  3:27 ` [PATCH v16 30/68] ceph: add ceph_encode_encrypted_dname() helper xiubli
2023-02-27  3:27 ` [PATCH v16 31/68] ceph: add support to readdir for encrypted filenames xiubli
2023-02-27  3:27 ` [PATCH v16 32/68] ceph: create symlinks with encrypted and base64-encoded targets xiubli
2023-02-27  3:27 ` [PATCH v16 33/68] ceph: make ceph_get_name decrypt filenames xiubli
2023-02-27  3:27 ` [PATCH v16 34/68] ceph: add a new ceph.fscrypt.auth vxattr xiubli
2023-02-27  3:27 ` [PATCH v16 35/68] ceph: add some fscrypt guardrails xiubli
2023-02-27  3:27 ` [PATCH v16 36/68] ceph: allow encrypting a directory while not having Ax caps xiubli
2023-02-27  3:27 ` [PATCH v16 37/68] ceph: mark directory as non-complete after loading key xiubli
2023-02-27  3:27 ` [PATCH v16 38/68] ceph: don't allow changing layout on encrypted files/directories xiubli
2023-02-27  3:27 ` [PATCH v16 39/68] libceph: add CEPH_OSD_OP_ASSERT_VER support xiubli
2023-02-27  3:27 ` [PATCH v16 40/68] ceph: size handling for encrypted inodes in cap updates xiubli
2023-02-27  3:27 ` [PATCH v16 41/68] ceph: fscrypt_file field handling in MClientRequest messages xiubli
2023-02-27  3:27 ` [PATCH v16 42/68] ceph: get file size from fscrypt_file when present in inode traces xiubli
2023-02-27  3:27 ` [PATCH v16 43/68] ceph: handle fscrypt fields in cap messages from MDS xiubli
2023-02-27  3:27 ` [PATCH v16 44/68] ceph: update WARN_ON message to pr_warn xiubli
2023-02-27  3:27 ` [PATCH v16 45/68] ceph: add __ceph_get_caps helper support xiubli
2023-02-27  3:27 ` [PATCH v16 46/68] ceph: add __ceph_sync_read " xiubli
2023-02-27  3:27 ` [PATCH v16 47/68] ceph: add object version support for sync read xiubli
2023-02-27  3:27 ` [PATCH v16 48/68] ceph: add infrastructure for file encryption and decryption xiubli
2023-02-27  3:27 ` [PATCH v16 49/68] ceph: add truncate size handling support for fscrypt xiubli
2023-02-27  3:27 ` [PATCH v16 50/68] libceph: allow ceph_osdc_new_request to accept a multi-op read xiubli
2023-02-27  3:27 ` [PATCH v16 51/68] ceph: disable fallocate for encrypted inodes xiubli
2023-02-27  3:27 ` [PATCH v16 52/68] ceph: disable copy offload on " xiubli
2023-02-27  3:27 ` [PATCH v16 53/68] ceph: don't use special DIO path for " xiubli
2023-02-27  3:27 ` [PATCH v16 54/68] ceph: align data in pages in ceph_sync_write xiubli
2023-02-27  3:28 ` [PATCH v16 55/68] ceph: add read/modify/write to ceph_sync_write xiubli
2023-02-27  3:28 ` [PATCH v16 56/68] ceph: plumb in decryption during sync reads xiubli
2023-02-27  3:28 ` [PATCH v16 57/68] ceph: add fscrypt decryption support to ceph_netfs_issue_op xiubli
2023-02-27  3:28 ` [PATCH v16 58/68] ceph: set i_blkbits to crypto block size for encrypted inodes xiubli
2023-02-27  3:28 ` [PATCH v16 59/68] ceph: add encryption support to writepage xiubli
2023-02-27  3:28 ` [PATCH v16 60/68] ceph: fscrypt support for writepages xiubli
2023-02-27  3:28 ` [PATCH v16 61/68] ceph: invalidate pages when doing direct/sync writes xiubli
2023-02-27  3:28 ` [PATCH v16 62/68] ceph: add support for encrypted snapshot names xiubli
2023-02-27  3:28 ` [PATCH v16 63/68] ceph: add support for handling " xiubli
2023-02-27  3:28 ` [PATCH v16 64/68] ceph: update documentation regarding snapshot naming limitations xiubli
2023-02-27  3:28 ` [PATCH v16 65/68] ceph: prevent snapshots to be created in encrypted locked directories xiubli
2023-02-27  3:28 ` [PATCH v16 66/68] ceph: report STATX_ATTR_ENCRYPTED on encrypted inodes xiubli
2023-02-27  3:28 ` [PATCH v16 67/68] libceph: defer removing the req from osdc just after req->r_callback xiubli
2023-02-27  3:28 ` [PATCH v16 68/68] ceph: drop the messages from MDS when unmounting xiubli
2023-02-27  9:27 ` [PATCH v16 00/68] ceph+fscrypt: full support Luís Henriques
2023-02-27  9:58   ` Xiubo Li
2023-02-27 10:30     ` Luís Henriques

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=406dc339c219d98639b752342136461f5070f259.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=ceph-devel@vger.kernel.org \
    --cc=idryomov@gmail.com \
    --cc=lhenriques@suse.de \
    --cc=mchangir@redhat.com \
    --cc=vshankar@redhat.com \
    --cc=xiubli@redhat.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 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).