Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp308593pxb; Wed, 23 Mar 2022 19:03:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwPxLXqYW7UqrLax54mywbfWOl69rTXFCipgjr58vPaSxD227AVvSgIPfNuAcLqP52kZkTf X-Received: by 2002:aa7:cc02:0:b0:411:487e:36fe with SMTP id q2-20020aa7cc02000000b00411487e36femr3854266edt.338.1648087382311; Wed, 23 Mar 2022 19:03:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648087382; cv=none; d=google.com; s=arc-20160816; b=rXbvYpHKlPThcC+ZSWrMLMWsAeUpont2j2QzZ2lkNb5K/0VmtyjelAmrpTNACqJuFx HEmn+fq5nTtyxyoxDDKjZihRowS6/Q1ot0AU68tKEJlWoqICTnB4lhfCjyFRlRRH9ogY KStFHjm58KtBoGEGZFIVKOrqNLmVoMsAVKypVVX7UAiNELcjK49Lnp2/ly4aJAFJfLI0 e7KTh6esxrQZnEumM/RdaXY0WpLx5lgt9HvxL8/hTW/VEY4rE3tp/IBUTZkEnFwepGHJ HoY0Bd1c7QQCI43Uqf+AK0UtlXJpBnu0I0RrcmfM9xf2KpOigG1kuN6TR7EvXrkGhcsI cPQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=LQg+YEgevjiQ3Fk9DF7a2VE3ACE0s+Iq82JhxnqPw2g=; b=V+B3zAVzVWvdC1OCbNv6FPkIHqh/aZ8qKHOiKXNH/utxX1Uj+SDdUFEA3F7Adtz5ew wlk5o7t8mfEXqVK8ni1TIcmEi/6f5NIktC5Cw030iarCZ1IQPUk6EfHM8R5EPWiL2kKp TSuxeDNNlZLf/Lm4dxOkrJoJiGXQ9ffe+9XDSLl88IiL/BpST7ukSGxzz6lcbQdMA5xe 8zFZURddzH70YHd/jIJ+5YLYZnVcmLNoI2vgZJlxPhGKs5Ylk7HLCTlD7XNo6kgXpxyR ZBJGrd2Cqbql+ZA5vYmPe3ivjzSkfGHCTWcEVluHpeLb/y2Wvw8IEZNB8fMqdHexU/ND 1deQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=WJKhwYF0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q23-20020a50aa97000000b00419297bb4a0si12628903edc.514.2022.03.23.19.02.37; Wed, 23 Mar 2022 19:03:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=WJKhwYF0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236956AbiCVOPv (ORCPT + 99 others); Tue, 22 Mar 2022 10:15:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50670 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236474AbiCVOPI (ORCPT ); Tue, 22 Mar 2022 10:15:08 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1A63B5B; Tue, 22 Mar 2022 07:13:40 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 632BCB81CFB; Tue, 22 Mar 2022 14:13:39 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 79C81C340EE; Tue, 22 Mar 2022 14:13:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1647958418; bh=lJtYp4YF5XEmdB7kK8sq8DEt9pC8dp6Fe46c9JOFrDs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WJKhwYF0QQ/rNWJOS/fHwWUthc1LxW+3ZoJj356KjwZ4QLgqjKlnzzzsBjrWj8hdT FqAs8aqM3u/iOUpgYiLonrzmnYYm9XTFmwL/WwvNVwSCz5KYw3M0MtzU96PabdPqLT M56XlSXd5Rf9ilMqye7teE4fOBDRvk1zyMFs0+z9RVafzCNxDkxirEv8JkzRWEg2xF FyB6wL+is8kAfFUjpYPEQ5TJ6jWu6GY1edt+rRae16wg0+nlWfrk9gPSNbnQWS/OuR DY9M/GKySqfPhgKTXInWSq+WhhLVR3+wWYM7AywIm3JU8SDRPZh765IwlIDj2gbdUS UiCGdmEKqPv8g== From: Jeff Layton To: idryomov@gmail.com, xiubli@redhat.com Cc: ceph-devel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org, lhenriques@suse.de Subject: [RFC PATCH v11 20/51] ceph: add helpers for converting names for userland presentation Date: Tue, 22 Mar 2022 10:12:45 -0400 Message-Id: <20220322141316.41325-21-jlayton@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220322141316.41325-1-jlayton@kernel.org> References: <20220322141316.41325-1-jlayton@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Define a new ceph_fname struct that we can use to carry information about encrypted dentry names. Add helpers for working with these objects, including ceph_fname_to_usr which formats an encrypted filename for userland presentation. Signed-off-by: Jeff Layton --- fs/ceph/crypto.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/ceph/crypto.h | 41 ++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c index 3e3b12cd3413..86de8483032f 100644 --- a/fs/ceph/crypto.c +++ b/fs/ceph/crypto.c @@ -174,3 +174,79 @@ int ceph_encode_encrypted_fname(const struct inode *parent, struct dentry *dentr dout("base64-encoded ciphertext name = %.*s\n", elen, buf); return elen; } + +/** + * ceph_fname_to_usr - convert a filename for userland presentation + * @fname: ceph_fname to be converted + * @tname: temporary name buffer to use for conversion (may be NULL) + * @oname: where converted name should be placed + * @is_nokey: set to true if key wasn't available during conversion (may be NULL) + * + * Given a filename (usually from the MDS), format it for presentation to + * userland. If @parent is not encrypted, just pass it back as-is. + * + * Otherwise, base64 decode the string, and then ask fscrypt to format it + * for userland presentation. + * + * Returns 0 on success or negative error code on error. + */ +int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname, + struct fscrypt_str *oname, bool *is_nokey) +{ + int ret; + struct fscrypt_str _tname = FSTR_INIT(NULL, 0); + struct fscrypt_str iname; + + if (!IS_ENCRYPTED(fname->dir)) { + oname->name = fname->name; + oname->len = fname->name_len; + return 0; + } + + /* Sanity check that the resulting name will fit in the buffer */ + if (fname->name_len > FSCRYPT_BASE64URL_CHARS(NAME_MAX)) + return -EIO; + + ret = __fscrypt_prepare_readdir(fname->dir); + if (ret) + return ret; + + /* + * Use the raw dentry name as sent by the MDS instead of + * generating a nokey name via fscrypt. + */ + if (!fscrypt_has_encryption_key(fname->dir)) { + memcpy(oname->name, fname->name, fname->name_len); + oname->len = fname->name_len; + if (is_nokey) + *is_nokey = true; + return 0; + } + + if (fname->ctext_len == 0) { + int declen; + + if (!tname) { + ret = fscrypt_fname_alloc_buffer(NAME_MAX, &_tname); + if (ret) + return ret; + tname = &_tname; + } + + declen = fscrypt_base64url_decode(fname->name, fname->name_len, tname->name); + if (declen <= 0) { + ret = -EIO; + goto out; + } + iname.name = tname->name; + iname.len = declen; + } else { + iname.name = fname->ctext; + iname.len = fname->ctext_len; + } + + ret = fscrypt_fname_disk_to_usr(fname->dir, 0, 0, &iname, oname); +out: + fscrypt_fname_free_buffer(&_tname); + return ret; +} diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h index 9a66a29d5c8b..7e56aded5124 100644 --- a/fs/ceph/crypto.h +++ b/fs/ceph/crypto.h @@ -13,6 +13,14 @@ struct ceph_fs_client; struct ceph_acl_sec_ctx; struct ceph_mds_request; +struct ceph_fname { + struct inode *dir; + char *name; // b64 encoded, possibly hashed + unsigned char *ctext; // binary crypttext (if any) + u32 name_len; // length of name buffer + u32 ctext_len; // length of crypttext +}; + struct ceph_fscrypt_auth { __le32 cfa_version; __le32 cfa_blob_len; @@ -61,6 +69,22 @@ int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, struct ceph_acl_sec_ctx *as); int ceph_encode_encrypted_fname(const struct inode *parent, struct dentry *dentry, char *buf); +static inline int ceph_fname_alloc_buffer(struct inode *parent, struct fscrypt_str *fname) +{ + if (!IS_ENCRYPTED(parent)) + return 0; + return fscrypt_fname_alloc_buffer(NAME_MAX, fname); +} + +static inline void ceph_fname_free_buffer(struct inode *parent, struct fscrypt_str *fname) +{ + if (IS_ENCRYPTED(parent)) + fscrypt_fname_free_buffer(fname); +} + +int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname, + struct fscrypt_str *oname, bool *is_nokey); + #else /* CONFIG_FS_ENCRYPTION */ static inline void ceph_fscrypt_set_ops(struct super_block *sb) @@ -89,6 +113,23 @@ static inline int ceph_encode_encrypted_fname(const struct inode *parent, { return -EOPNOTSUPP; } + +static inline int ceph_fname_alloc_buffer(struct inode *parent, struct fscrypt_str *fname) +{ + return 0; +} + +static inline void ceph_fname_free_buffer(struct inode *parent, struct fscrypt_str *fname) +{ +} + +static inline int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname, + struct fscrypt_str *oname, bool *is_nokey) +{ + oname->name = fname->name; + oname->len = fname->name_len; + return 0; +} #endif /* CONFIG_FS_ENCRYPTION */ #endif -- 2.35.1