openssl: patch to fix devcrypto sessions leak
Applies a patch from https://github.com/openssl/openssl/pull/8213 that fixes an error where open /dev/crypto sessions were not closed. Thanks to Ansuel Smith for reporting it. Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
This commit is contained in:
		 Eneas U de Queiroz
					Eneas U de Queiroz
				
			
				
					committed by
					
						 Hauke Mehrtens
						Hauke Mehrtens
					
				
			
			
				
	
			
			
			 Hauke Mehrtens
						Hauke Mehrtens
					
				
			
						parent
						
							eabc1ddc45
						
					
				
				
					commit
					ddee1825de
				
			| @@ -0,0 +1,115 @@ | |||||||
|  | From 82b269fd77d20aa86d0825d798f3045dfe0a7a86 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Eneas U de Queiroz <cote2004-github@yahoo.com> | ||||||
|  | Date: Tue, 12 Feb 2019 10:44:19 -0200 | ||||||
|  | Subject: [PATCH] eng_devcrypto: close open session on init | ||||||
|  |  | ||||||
|  | cipher_init may be called on an already initialized context, without a | ||||||
|  | necessary cleanup.  This separates cleanup from initialization, closing | ||||||
|  | an eventual open session before creating a new one. | ||||||
|  |  | ||||||
|  | Move the /dev/crypto session cleanup code to its own function. | ||||||
|  |  | ||||||
|  | Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com> | ||||||
|  |  | ||||||
|  | --- a/crypto/engine/eng_devcrypto.c | ||||||
|  | +++ b/crypto/engine/eng_devcrypto.c | ||||||
|  | @@ -35,6 +35,15 @@ | ||||||
|  |   */ | ||||||
|  |  static int cfd; | ||||||
|  |   | ||||||
|  | +static int clean_devcrypto_session(struct session_op *sess) { | ||||||
|  | +    if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) { | ||||||
|  | +        SYSerr(SYS_F_IOCTL, errno); | ||||||
|  | +        return 0; | ||||||
|  | +    } | ||||||
|  | +    memset(sess, 0, sizeof(struct session_op)); | ||||||
|  | +    return 1; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  /****************************************************************************** | ||||||
|  |   * | ||||||
|  |   * Ciphers | ||||||
|  | @@ -143,7 +152,11 @@ static int cipher_init(EVP_CIPHER_CTX *c | ||||||
|  |      const struct cipher_data_st *cipher_d = | ||||||
|  |          get_cipher_data(EVP_CIPHER_CTX_nid(ctx)); | ||||||
|  |   | ||||||
|  | -    memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); | ||||||
|  | +    /* cleanup a previous session */ | ||||||
|  | +    if (cipher_ctx->sess.ses != 0 && | ||||||
|  | +        clean_devcrypto_session(&cipher_ctx->sess) == 0) | ||||||
|  | +        return 0; | ||||||
|  | + | ||||||
|  |      cipher_ctx->sess.cipher = cipher_d->devcryptoid; | ||||||
|  |      cipher_ctx->sess.keylen = cipher_d->keylen; | ||||||
|  |      cipher_ctx->sess.key = (void *)key; | ||||||
|  | @@ -282,15 +295,29 @@ static int ctr_do_cipher(EVP_CIPHER_CTX | ||||||
|  |   | ||||||
|  |  static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2) | ||||||
|  |  { | ||||||
|  | +    struct cipher_ctx *cipher_ctx = | ||||||
|  | +        (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); | ||||||
|  |      EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2; | ||||||
|  | -    struct cipher_ctx *cipher_ctx; | ||||||
|  | +    struct cipher_ctx *to_cipher_ctx; | ||||||
|  | + | ||||||
|  | +    switch (type) { | ||||||
|  |   | ||||||
|  | -    if (type == EVP_CTRL_COPY) { | ||||||
|  | +    case EVP_CTRL_COPY: | ||||||
|  | +        if (cipher_ctx == NULL) | ||||||
|  | +            return 1; | ||||||
|  |          /* when copying the context, a new session needs to be initialized */ | ||||||
|  | -        cipher_ctx = (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); | ||||||
|  | -        return (cipher_ctx == NULL) | ||||||
|  | -            || cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx), | ||||||
|  | +        to_cipher_ctx = | ||||||
|  | +            (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx); | ||||||
|  | +        memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess)); | ||||||
|  | +        return cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx), | ||||||
|  |                             (cipher_ctx->op == COP_ENCRYPT)); | ||||||
|  | + | ||||||
|  | +    case EVP_CTRL_INIT: | ||||||
|  | +        memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); | ||||||
|  | +        return 1; | ||||||
|  | + | ||||||
|  | +    default: | ||||||
|  | +        break; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      return -1; | ||||||
|  | @@ -301,12 +328,7 @@ static int cipher_cleanup(EVP_CIPHER_CTX | ||||||
|  |      struct cipher_ctx *cipher_ctx = | ||||||
|  |          (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); | ||||||
|  |   | ||||||
|  | -    if (ioctl(cfd, CIOCFSESSION, &cipher_ctx->sess.ses) < 0) { | ||||||
|  | -        SYSerr(SYS_F_IOCTL, errno); | ||||||
|  | -        return 0; | ||||||
|  | -    } | ||||||
|  | - | ||||||
|  | -    return 1; | ||||||
|  | +    return clean_devcrypto_session(&cipher_ctx->sess); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  | @@ -352,6 +374,7 @@ static void prepare_cipher_methods(void) | ||||||
|  |              || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i], | ||||||
|  |                                            cipher_data[i].flags | ||||||
|  |                                            | EVP_CIPH_CUSTOM_COPY | ||||||
|  | +                                          | EVP_CIPH_CTRL_INIT | ||||||
|  |                                            | EVP_CIPH_FLAG_DEFAULT_ASN1) | ||||||
|  |              || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init) | ||||||
|  |              || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i], | ||||||
|  | @@ -594,11 +617,8 @@ static int digest_cleanup(EVP_MD_CTX *ct | ||||||
|  |   | ||||||
|  |      if (digest_ctx == NULL) | ||||||
|  |          return 1; | ||||||
|  | -    if (ioctl(cfd, CIOCFSESSION, &digest_ctx->sess.ses) < 0) { | ||||||
|  | -        SYSerr(SYS_F_IOCTL, errno); | ||||||
|  | -        return 0; | ||||||
|  | -    } | ||||||
|  | -    return 1; | ||||||
|  | + | ||||||
|  | +    return clean_devcrypto_session(&digest_ctx->sess); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static int devcrypto_test_digest(size_t digest_data_index) | ||||||
		Reference in New Issue
	
	Block a user