RE: [RFC] odd check in ceph_encode_encrypted_dname()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2025-02-18 at 23:52 +0000, Al Viro wrote:
> On Tue, Feb 18, 2025 at 01:21:32AM +0000, Al Viro wrote:
> 
> > See the problem?  strrchr() expects a NUL-terminated string; giving it an
> > array that has no zero bytes in it is an UB.
> > 
> > That one is -stable fodder on its own, IMO...
> 
> FWIW, it's more unpleasant; there are other call chains for parse_longname()
> where it's not feasible to NUL-terminate in place.  I suspect that the
> patch below is a better way to handle that.  Comments?
> 

Let me test the patch.

> From ed016e5ea89550b567306207ba3ca8b60e147d89 Mon Sep 17 00:00:00 2001
> From: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> Date: Tue, 18 Feb 2025 17:57:17 -0500
> Subject: [PATCH 1/3] [ceph] parse_longname(): strrchr() expects NUL-terminated
>  string
> 
> ... and parse_longname() is not guaranteed that.  That's the reason
> why it uses kmemdup_nul() to build the argument for kstrtou64();
> the problem is, kstrtou64() is not the only thing that need it.
> 
> Just get a NUL-terminated copy of the entire thing and be done
> with that...
> 
> Fixes: dd66df0053ef "ceph: add support for encrypted snapshot names"
> Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> ---
>  fs/ceph/crypto.c | 32 ++++++++++++--------------------
>  1 file changed, 12 insertions(+), 20 deletions(-)
> 
> diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c
> index 3b3c4d8d401e..164e7981aecb 100644
> --- a/fs/ceph/crypto.c
> +++ b/fs/ceph/crypto.c
> @@ -215,35 +215,30 @@ static struct inode *parse_longname(const struct inode *parent,
>  	struct ceph_client *cl = ceph_inode_to_client(parent);
>  	struct inode *dir = NULL;
>  	struct ceph_vino vino = { .snap = CEPH_NOSNAP };
> -	char *inode_number;
>  	char *name_end;
> -	int orig_len = *name_len;
>  	int ret = -EIO;
> -
> +	/* NUL-terminate */
> +	char *s __free(kfree) = kmemdup_nul(name, *name_len, GFP_KERNEL);

Maybe, str here? The s looks too extreme for my taste. :)

> +	if (!s)
> +		return ERR_PTR(-ENOMEM);
>  	/* Skip initial '_' */
> -	name++;
> -	name_end = strrchr(name, '_');
> +	s++;
> +	name_end = strrchr(s, '_');
>  	if (!name_end) {
> -		doutc(cl, "failed to parse long snapshot name: %s\n", name);
> +		doutc(cl, "failed to parse long snapshot name: %s\n", s);
>  		return ERR_PTR(-EIO);
>  	}
> -	*name_len = (name_end - name);
> +	*name_len = (name_end - s);
>  	if (*name_len <= 0) {
>  		pr_err_client(cl, "failed to parse long snapshot name\n");
>  		return ERR_PTR(-EIO);
>  	}
>  
>  	/* Get the inode number */
> -	inode_number = kmemdup_nul(name_end + 1,
> -				   orig_len - *name_len - 2,
> -				   GFP_KERNEL);
> -	if (!inode_number)
> -		return ERR_PTR(-ENOMEM);
> -	ret = kstrtou64(inode_number, 10, &vino.ino);
> +	ret = kstrtou64(name_end + 1, 10, &vino.ino);

The inode_number explains by itself what we are converting here. But name_end
sounds confusing and not informative for my taste. But I could have a bad taste.
:)

>  	if (ret) {
> -		doutc(cl, "failed to parse inode number: %s\n", name);
> -		dir = ERR_PTR(ret);
> -		goto out;
> +		doutc(cl, "failed to parse inode number: %s\n", s);
> +		return ERR_PTR(ret);
>  	}
>  
>  	/* And finally the inode */
> @@ -252,11 +247,8 @@ static struct inode *parse_longname(const struct inode *parent,
>  		/* This can happen if we're not mounting cephfs on the root */
>  		dir = ceph_get_inode(parent->i_sb, vino, NULL);
>  		if (IS_ERR(dir))
> -			doutc(cl, "can't find inode %s (%s)\n", inode_number, name);
> +			doutc(cl, "can't find inode %s (%s)\n", name_end + 1, name);

It's not critical, but we use name_end + 1 two times. Potentially, it could be a
source of somebody mistake in the future.

Thanks,
Slava.

>  	}
> -
> -out:
> -	kfree(inode_number);
>  	return dir;
>  }
>  





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux