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