mirror of
https://github.com/openssl/openssl.git
synced 2026-05-07 20:12:39 +00:00
Add an ownership token for OSSL_FN_CTX frames
This prevents ending a frame that wasn't started by the caller. Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.foundation> MergeDate: Thu Apr 30 09:18:52 2026 (Merged from https://github.com/openssl/openssl/pull/30886)
This commit is contained in:
+8
-5
@@ -112,16 +112,16 @@ void OSSL_FN_CTX_free(OSSL_FN_CTX *ctx)
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
int OSSL_FN_CTX_start(OSSL_FN_CTX *ctx)
|
||||
const void *OSSL_FN_CTX_start(OSSL_FN_CTX *ctx)
|
||||
{
|
||||
if (!ossl_assert(ctx != NULL))
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
struct ossl_fn_ctx_frame_st *last_frame = ctx->last_frame;
|
||||
size_t used = (last_frame == NULL) ? 0 : last_frame->free_memory - ctx->memory;
|
||||
|
||||
if (ctx->msize - used < sizeof(struct ossl_fn_ctx_frame_st))
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
if (ctx->last_frame == NULL)
|
||||
ctx->last_frame = (struct ossl_fn_ctx_frame_st *)ctx->memory;
|
||||
@@ -134,16 +134,19 @@ int OSSL_FN_CTX_start(OSSL_FN_CTX *ctx)
|
||||
frame->free_memory = frame->memory;
|
||||
frame->msize = ctx->msize - used - sizeof(*frame);
|
||||
|
||||
return 1;
|
||||
return ctx->last_frame;
|
||||
}
|
||||
|
||||
int OSSL_FN_CTX_end(OSSL_FN_CTX *ctx)
|
||||
int OSSL_FN_CTX_end(OSSL_FN_CTX *ctx, const void *token)
|
||||
{
|
||||
if (!ossl_assert(ctx != NULL) || !ossl_assert(ctx->last_frame != NULL))
|
||||
return 0;
|
||||
|
||||
struct ossl_fn_ctx_frame_st *last_frame = ctx->last_frame;
|
||||
|
||||
if (last_frame != token)
|
||||
return 0;
|
||||
|
||||
ctx->last_frame = last_frame->previous_frame;
|
||||
|
||||
return 1;
|
||||
|
||||
+4
-4
@@ -16,13 +16,13 @@
|
||||
|
||||
int OSSL_FN_mul(OSSL_FN *r, const OSSL_FN *a, const OSSL_FN *b, OSSL_FN_CTX *ctx)
|
||||
{
|
||||
if (!OSSL_FN_CTX_start(ctx))
|
||||
return 0;
|
||||
|
||||
size_t al = (size_t)a->dsize;
|
||||
size_t bl = (size_t)b->dsize;
|
||||
size_t rl = (size_t)r->dsize;
|
||||
size_t max = (size_t)(al + bl);
|
||||
const void *token = OSSL_FN_CTX_start(ctx);
|
||||
if (token == NULL)
|
||||
return 0;
|
||||
|
||||
int ret = 0;
|
||||
#ifdef BN_MUL_COMBA
|
||||
@@ -60,6 +60,6 @@ end:
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
OSSL_FN_CTX_end(ctx);
|
||||
OSSL_FN_CTX_end(ctx, token);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+3
-2
@@ -16,7 +16,8 @@
|
||||
|
||||
int OSSL_FN_sqr(OSSL_FN *r, const OSSL_FN *a, OSSL_FN_CTX *ctx)
|
||||
{
|
||||
if (!OSSL_FN_CTX_start(ctx))
|
||||
const void *token = OSSL_FN_CTX_start(ctx);
|
||||
if (token == NULL)
|
||||
return 0;
|
||||
|
||||
size_t al = (size_t)a->dsize;
|
||||
@@ -70,6 +71,6 @@ end:
|
||||
}
|
||||
|
||||
err:
|
||||
OSSL_FN_CTX_end(ctx);
|
||||
OSSL_FN_CTX_end(ctx, token);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+10
-3
@@ -184,9 +184,10 @@ void OSSL_FN_CTX_free(OSSL_FN_CTX *ctx);
|
||||
* call this must also clean up with a OSSL_FN_CTX_end() call.
|
||||
*
|
||||
* @param[in] ctx The OSSL_FN_CTX to start the frame in.
|
||||
* @returns 1 on success, 0 on error.
|
||||
* @returns Ownership token of the started frame, NULL on error.
|
||||
* This token must be passed to OSSL_FN_CTX_end().
|
||||
*/
|
||||
int OSSL_FN_CTX_start(OSSL_FN_CTX *ctx);
|
||||
const void *OSSL_FN_CTX_start(OSSL_FN_CTX *ctx);
|
||||
|
||||
/**
|
||||
* End the last OSSL_FN_CTX frame, resetting back to the previous
|
||||
@@ -194,9 +195,15 @@ int OSSL_FN_CTX_start(OSSL_FN_CTX *ctx);
|
||||
* this function before returning.
|
||||
*
|
||||
* @param[in] ctx The OSSL_FN_CTX to start the frame in.
|
||||
* @param[in] token Ownership token returned by OSSL_FN_CTX_start().
|
||||
* @returns 1 on success, 0 on error.
|
||||
*
|
||||
* @note The token parameter is validated but not used for choosing a
|
||||
* frame; only the most recent frame can be ended. Passing an incorrect
|
||||
* token indicates a programming error and the function will fail.
|
||||
* If NULL is passed, nothing will be done but the function will return 1.
|
||||
*/
|
||||
int OSSL_FN_CTX_end(OSSL_FN_CTX *ctx);
|
||||
int OSSL_FN_CTX_end(OSSL_FN_CTX *ctx, const void *token);
|
||||
|
||||
/**
|
||||
* Get a suitably sized OSSL_FN from an OSSL_FN_CTX.
|
||||
|
||||
+10
-8
@@ -97,6 +97,7 @@ static int test_ctx(void)
|
||||
int ret = 1;
|
||||
OSSL_FN_CTX *ctx = NULL;
|
||||
OSSL_FN *f = NULL;
|
||||
const void *token = NULL;
|
||||
|
||||
/*
|
||||
* Make a CTX that is likely to contain two 2048-bit or one 4096-bit OSSL_FN
|
||||
@@ -111,7 +112,7 @@ static int test_ctx(void)
|
||||
}
|
||||
|
||||
/* Check that we can get 1 2048-bit OSSL_FN instance, and check its metadata */
|
||||
if (!TEST_true(OSSL_FN_CTX_start(ctx))) {
|
||||
if (!TEST_ptr(token = OSSL_FN_CTX_start(ctx))) {
|
||||
ret = 0;
|
||||
/* It's pointless to try more tests after this failure */
|
||||
goto end;
|
||||
@@ -120,14 +121,14 @@ static int test_ctx(void)
|
||||
|| !TEST_false(ossl_fn_is_dynamically_allocated(f))
|
||||
|| !TEST_false(ossl_fn_is_securely_allocated(f)))
|
||||
ret = 0;
|
||||
if (!TEST_true(OSSL_FN_CTX_end(ctx))) {
|
||||
if (!TEST_true(OSSL_FN_CTX_end(ctx, token))) {
|
||||
ret = 0;
|
||||
/* It's pointless to try more tests after this failure */
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Check that we can get 2 2048-bit OSSL_FN instances, but not 3 */
|
||||
if (!TEST_true(OSSL_FN_CTX_start(ctx))) {
|
||||
if (!TEST_ptr(token = OSSL_FN_CTX_start(ctx))) {
|
||||
ret = 0;
|
||||
/* It's pointless to try more tests after this failure */
|
||||
goto end;
|
||||
@@ -136,14 +137,14 @@ static int test_ctx(void)
|
||||
|| !TEST_ptr(f = OSSL_FN_CTX_get_bits(ctx, 2048))
|
||||
|| !TEST_ptr_null(f = OSSL_FN_CTX_get_bits(ctx, 2048)))
|
||||
ret = 0;
|
||||
if (!TEST_true(OSSL_FN_CTX_end(ctx))) {
|
||||
if (!TEST_true(OSSL_FN_CTX_end(ctx, token))) {
|
||||
ret = 0;
|
||||
/* It's pointless to try more tests after this failure */
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Check that we can get 1 4096-bit OSSL_FN instance, but not 2 */
|
||||
if (!TEST_true(OSSL_FN_CTX_start(ctx))) {
|
||||
if (!TEST_ptr(token = OSSL_FN_CTX_start(ctx))) {
|
||||
ret = 0;
|
||||
/* It's pointless to try more tests after this failure */
|
||||
goto end;
|
||||
@@ -151,7 +152,7 @@ static int test_ctx(void)
|
||||
if (!TEST_ptr(f = OSSL_FN_CTX_get_bits(ctx, 4096))
|
||||
|| !TEST_ptr_null(f = OSSL_FN_CTX_get_bits(ctx, 2048)))
|
||||
ret = 0;
|
||||
if (!TEST_true(OSSL_FN_CTX_end(ctx))) {
|
||||
if (!TEST_true(OSSL_FN_CTX_end(ctx, token))) {
|
||||
ret = 0;
|
||||
/* It's pointless to try more tests after this failure */
|
||||
goto end;
|
||||
@@ -168,6 +169,7 @@ static int test_secure_ctx(void)
|
||||
int ret = 1;
|
||||
OSSL_FN_CTX *ctx = NULL;
|
||||
OSSL_FN *f = NULL;
|
||||
const void *token = NULL;
|
||||
|
||||
/*
|
||||
* Make a CTX that is likely to contain two 2048-bit OSSL_FN and one frame
|
||||
@@ -182,7 +184,7 @@ static int test_secure_ctx(void)
|
||||
}
|
||||
|
||||
/* Check that we can get 1 2048-bit OSSL_FN instance, and check its metadata */
|
||||
if (!TEST_true(OSSL_FN_CTX_start(ctx))) {
|
||||
if (!TEST_ptr(token = OSSL_FN_CTX_start(ctx))) {
|
||||
ret = 0;
|
||||
/* It's pointless to try more tests after this failure */
|
||||
goto end;
|
||||
@@ -191,7 +193,7 @@ static int test_secure_ctx(void)
|
||||
|| !TEST_false(ossl_fn_is_dynamically_allocated(f))
|
||||
|| !TEST_true(ossl_fn_is_securely_allocated(f)))
|
||||
ret = 0;
|
||||
if (!TEST_true(OSSL_FN_CTX_end(ctx))) {
|
||||
if (!TEST_true(OSSL_FN_CTX_end(ctx, token))) {
|
||||
ret = 0;
|
||||
/* It's pointless to try more tests after this failure */
|
||||
goto end;
|
||||
|
||||
Reference in New Issue
Block a user