lkml.org 
[lkml]   [2018]   [Apr]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 048/164] CIFS: refactor crypto shash/sdesc allocation&free
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Aurelien Aptel <aaptel@suse.com>

    commit 82fb82be05585426405667dd5f0510aa953ba439 upstream.

    shash and sdesc and always allocated and freed together.
    * abstract this in new functions cifs_alloc_hash() and cifs_free_hash().
    * make smb2/3 crypto allocation independent from each other.

    Signed-off-by: Aurelien Aptel <aaptel@suse.com>
    Signed-off-by: Steve French <smfrench@gmail.com>
    Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
    CC: Stable <stable@vger.kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/cifs/cifsencrypt.c | 78 ++++--------------------------------------------
    fs/cifs/cifsproto.h | 5 +++
    fs/cifs/link.c | 25 +++------------
    fs/cifs/misc.c | 54 +++++++++++++++++++++++++++++++++
    fs/cifs/smb2transport.c | 75 +++++++++-------------------------------------
    fs/cifs/smbencrypt.c | 25 +++------------
    6 files changed, 91 insertions(+), 171 deletions(-)

    --- a/fs/cifs/cifsencrypt.c
    +++ b/fs/cifs/cifsencrypt.c
    @@ -36,37 +36,6 @@
    #include <crypto/skcipher.h>
    #include <crypto/aead.h>

    -static int
    -cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server)
    -{
    - int rc;
    - unsigned int size;
    -
    - if (server->secmech.sdescmd5 != NULL)
    - return 0; /* already allocated */
    -
    - server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
    - if (IS_ERR(server->secmech.md5)) {
    - cifs_dbg(VFS, "could not allocate crypto md5\n");
    - rc = PTR_ERR(server->secmech.md5);
    - server->secmech.md5 = NULL;
    - return rc;
    - }
    -
    - size = sizeof(struct shash_desc) +
    - crypto_shash_descsize(server->secmech.md5);
    - server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
    - if (!server->secmech.sdescmd5) {
    - crypto_free_shash(server->secmech.md5);
    - server->secmech.md5 = NULL;
    - return -ENOMEM;
    - }
    - server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
    - server->secmech.sdescmd5->shash.flags = 0x0;
    -
    - return 0;
    -}
    -
    int __cifs_calc_signature(struct smb_rqst *rqst,
    struct TCP_Server_Info *server, char *signature,
    struct shash_desc *shash)
    @@ -132,13 +101,10 @@ static int cifs_calc_signature(struct sm
    if (!rqst->rq_iov || !signature || !server)
    return -EINVAL;

    - if (!server->secmech.sdescmd5) {
    - rc = cifs_crypto_shash_md5_allocate(server);
    - if (rc) {
    - cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__);
    - return -1;
    - }
    - }
    + rc = cifs_alloc_hash("md5", &server->secmech.md5,
    + &server->secmech.sdescmd5);
    + if (rc)
    + return -1;

    rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
    if (rc) {
    @@ -663,37 +629,6 @@ CalcNTLMv2_response(const struct cifs_se
    return rc;
    }

    -static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
    -{
    - int rc;
    - unsigned int size;
    -
    - /* check if already allocated */
    - if (server->secmech.sdeschmacmd5)
    - return 0;
    -
    - server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
    - if (IS_ERR(server->secmech.hmacmd5)) {
    - cifs_dbg(VFS, "could not allocate crypto hmacmd5\n");
    - rc = PTR_ERR(server->secmech.hmacmd5);
    - server->secmech.hmacmd5 = NULL;
    - return rc;
    - }
    -
    - size = sizeof(struct shash_desc) +
    - crypto_shash_descsize(server->secmech.hmacmd5);
    - server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
    - if (!server->secmech.sdeschmacmd5) {
    - crypto_free_shash(server->secmech.hmacmd5);
    - server->secmech.hmacmd5 = NULL;
    - return -ENOMEM;
    - }
    - server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
    - server->secmech.sdeschmacmd5->shash.flags = 0x0;
    -
    - return 0;
    -}
    -
    int
    setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
    {
    @@ -757,9 +692,10 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c

    mutex_lock(&ses->server->srv_mutex);

    - rc = crypto_hmacmd5_alloc(ses->server);
    + rc = cifs_alloc_hash("hmac(md5)",
    + &ses->server->secmech.hmacmd5,
    + &ses->server->secmech.sdeschmacmd5);
    if (rc) {
    - cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
    goto unlock;
    }

    --- a/fs/cifs/cifsproto.h
    +++ b/fs/cifs/cifsproto.h
    @@ -538,4 +538,9 @@ enum securityEnum cifs_select_sectype(st
    struct cifs_aio_ctx *cifs_aio_ctx_alloc(void);
    void cifs_aio_ctx_release(struct kref *refcount);
    int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw);
    +
    +int cifs_alloc_hash(const char *name, struct crypto_shash **shash,
    + struct sdesc **sdesc);
    +void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
    +
    #endif /* _CIFSPROTO_H */
    --- a/fs/cifs/link.c
    +++ b/fs/cifs/link.c
    @@ -50,25 +50,12 @@ static int
    symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
    {
    int rc;
    - unsigned int size;
    - struct crypto_shash *md5;
    - struct sdesc *sdescmd5;
    + struct crypto_shash *md5 = NULL;
    + struct sdesc *sdescmd5 = NULL;

    - md5 = crypto_alloc_shash("md5", 0, 0);
    - if (IS_ERR(md5)) {
    - rc = PTR_ERR(md5);
    - cifs_dbg(VFS, "%s: Crypto md5 allocation error %d\n",
    - __func__, rc);
    - return rc;
    - }
    - size = sizeof(struct shash_desc) + crypto_shash_descsize(md5);
    - sdescmd5 = kmalloc(size, GFP_KERNEL);
    - if (!sdescmd5) {
    - rc = -ENOMEM;
    + rc = cifs_alloc_hash("md5", &md5, &sdescmd5);
    + if (rc)
    goto symlink_hash_err;
    - }
    - sdescmd5->shash.tfm = md5;
    - sdescmd5->shash.flags = 0x0;

    rc = crypto_shash_init(&sdescmd5->shash);
    if (rc) {
    @@ -85,9 +72,7 @@ symlink_hash(unsigned int link_len, cons
    cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);

    symlink_hash_err:
    - crypto_free_shash(md5);
    - kfree(sdescmd5);
    -
    + cifs_free_hash(&md5, &sdescmd5);
    return rc;
    }

    --- a/fs/cifs/misc.c
    +++ b/fs/cifs/misc.c
    @@ -848,3 +848,57 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *
    iov_iter_bvec(&ctx->iter, ITER_BVEC | rw, ctx->bv, npages, ctx->len);
    return 0;
    }
    +
    +/**
    + * cifs_alloc_hash - allocate hash and hash context together
    + *
    + * The caller has to make sure @sdesc is initialized to either NULL or
    + * a valid context. Both can be freed via cifs_free_hash().
    + */
    +int
    +cifs_alloc_hash(const char *name,
    + struct crypto_shash **shash, struct sdesc **sdesc)
    +{
    + int rc = 0;
    + size_t size;
    +
    + if (*sdesc != NULL)
    + return 0;
    +
    + *shash = crypto_alloc_shash(name, 0, 0);
    + if (IS_ERR(*shash)) {
    + cifs_dbg(VFS, "could not allocate crypto %s\n", name);
    + rc = PTR_ERR(*shash);
    + *shash = NULL;
    + *sdesc = NULL;
    + return rc;
    + }
    +
    + size = sizeof(struct shash_desc) + crypto_shash_descsize(*shash);
    + *sdesc = kmalloc(size, GFP_KERNEL);
    + if (*sdesc == NULL) {
    + cifs_dbg(VFS, "no memory left to allocate crypto %s\n", name);
    + crypto_free_shash(*shash);
    + *shash = NULL;
    + return -ENOMEM;
    + }
    +
    + (*sdesc)->shash.tfm = *shash;
    + (*sdesc)->shash.flags = 0x0;
    + return 0;
    +}
    +
    +/**
    + * cifs_free_hash - free hash and hash context together
    + *
    + * Freeing a NULL hash or context is safe.
    + */
    +void
    +cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)
    +{
    + kfree(*sdesc);
    + *sdesc = NULL;
    + if (*shash)
    + crypto_free_shash(*shash);
    + *shash = NULL;
    +}
    --- a/fs/cifs/smb2transport.c
    +++ b/fs/cifs/smb2transport.c
    @@ -43,76 +43,31 @@
    static int
    smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
    {
    - int rc;
    - unsigned int size;
    -
    - if (server->secmech.sdeschmacsha256 != NULL)
    - return 0; /* already allocated */
    -
    - server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
    - if (IS_ERR(server->secmech.hmacsha256)) {
    - cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
    - rc = PTR_ERR(server->secmech.hmacsha256);
    - server->secmech.hmacsha256 = NULL;
    - return rc;
    - }
    -
    - size = sizeof(struct shash_desc) +
    - crypto_shash_descsize(server->secmech.hmacsha256);
    - server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
    - if (!server->secmech.sdeschmacsha256) {
    - crypto_free_shash(server->secmech.hmacsha256);
    - server->secmech.hmacsha256 = NULL;
    - return -ENOMEM;
    - }
    - server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
    - server->secmech.sdeschmacsha256->shash.flags = 0x0;
    -
    - return 0;
    + return cifs_alloc_hash("hmac(sha256)",
    + &server->secmech.hmacsha256,
    + &server->secmech.sdeschmacsha256);
    }

    static int
    smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
    {
    - unsigned int size;
    + struct cifs_secmech *p = &server->secmech;
    int rc;

    - if (server->secmech.sdesccmacaes != NULL)
    - return 0; /* already allocated */
    -
    - rc = smb2_crypto_shash_allocate(server);
    + rc = cifs_alloc_hash("hmac(sha256)",
    + &p->hmacsha256,
    + &p->sdeschmacsha256);
    if (rc)
    - return rc;
    -
    - server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
    - if (IS_ERR(server->secmech.cmacaes)) {
    - cifs_dbg(VFS, "could not allocate crypto cmac-aes");
    - kfree(server->secmech.sdeschmacsha256);
    - server->secmech.sdeschmacsha256 = NULL;
    - crypto_free_shash(server->secmech.hmacsha256);
    - server->secmech.hmacsha256 = NULL;
    - rc = PTR_ERR(server->secmech.cmacaes);
    - server->secmech.cmacaes = NULL;
    - return rc;
    - }
    + goto err;

    - size = sizeof(struct shash_desc) +
    - crypto_shash_descsize(server->secmech.cmacaes);
    - server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
    - if (!server->secmech.sdesccmacaes) {
    - cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
    - kfree(server->secmech.sdeschmacsha256);
    - server->secmech.sdeschmacsha256 = NULL;
    - crypto_free_shash(server->secmech.hmacsha256);
    - crypto_free_shash(server->secmech.cmacaes);
    - server->secmech.hmacsha256 = NULL;
    - server->secmech.cmacaes = NULL;
    - return -ENOMEM;
    - }
    - server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
    - server->secmech.sdesccmacaes->shash.flags = 0x0;
    + rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
    + if (rc)
    + goto err;

    return 0;
    +err:
    + cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
    + return rc;
    }

    static struct cifs_ses *
    @@ -457,7 +412,7 @@ smb3_calc_signature(struct smb_rqst *rqs
    cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
    return rc;
    }
    -
    +
    rc = __cifs_calc_signature(rqst, server, sigptr,
    &server->secmech.sdesccmacaes->shash);

    --- a/fs/cifs/smbencrypt.c
    +++ b/fs/cifs/smbencrypt.c
    @@ -121,25 +121,12 @@ int
    mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
    {
    int rc;
    - unsigned int size;
    - struct crypto_shash *md4;
    - struct sdesc *sdescmd4;
    + struct crypto_shash *md4 = NULL;
    + struct sdesc *sdescmd4 = NULL;

    - md4 = crypto_alloc_shash("md4", 0, 0);
    - if (IS_ERR(md4)) {
    - rc = PTR_ERR(md4);
    - cifs_dbg(VFS, "%s: Crypto md4 allocation error %d\n",
    - __func__, rc);
    - return rc;
    - }
    - size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
    - sdescmd4 = kmalloc(size, GFP_KERNEL);
    - if (!sdescmd4) {
    - rc = -ENOMEM;
    + rc = cifs_alloc_hash("md4", &md4, &sdescmd4);
    + if (rc)
    goto mdfour_err;
    - }
    - sdescmd4->shash.tfm = md4;
    - sdescmd4->shash.flags = 0x0;

    rc = crypto_shash_init(&sdescmd4->shash);
    if (rc) {
    @@ -156,9 +143,7 @@ mdfour(unsigned char *md4_hash, unsigned
    cifs_dbg(VFS, "%s: Could not generate md4 hash\n", __func__);

    mdfour_err:
    - crypto_free_shash(md4);
    - kfree(sdescmd4);
    -
    + cifs_free_hash(&md4, &sdescmd4);
    return rc;
    }


    \
     
     \ /
      Last update: 2018-04-22 17:34    [W:4.711 / U:0.264 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site