Allow multiple nested marks
authorMatt Caswell <matt@openssl.org>
Fri, 6 Nov 2020 11:43:44 +0000 (11:43 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 19 Nov 2020 14:56:58 +0000 (14:56 +0000)
Previously we only ever allowed one mark to be set against an error in the
statck. If we attempted to nest them, then we would end up clearing all
the errors in the stack when we popped to the mark.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13335)

crypto/err/err.c
crypto/err/err_local.h
include/openssl/err.h.in

index 2c8240f0ba0470725edeabad17d20e76a3a5a2e7..a66ea63adfa4d67eef2958f486b310e06d086f8c 100644 (file)
@@ -838,7 +838,7 @@ int ERR_set_mark(void)
 
     if (es->bottom == es->top)
         return 0;
-    es->err_flags[es->top] |= ERR_FLAG_MARK;
+    es->err_marks[es->top]++;
     return 1;
 }
 
@@ -851,14 +851,14 @@ int ERR_pop_to_mark(void)
         return 0;
 
     while (es->bottom != es->top
-           && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) {
+           && es->err_marks[es->top] == 0) {
         err_clear(es, es->top, 0);
         es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1;
     }
 
     if (es->bottom == es->top)
         return 0;
-    es->err_flags[es->top] &= ~ERR_FLAG_MARK;
+    es->err_marks[es->top]--;
     return 1;
 }
 
@@ -873,13 +873,13 @@ int ERR_clear_last_mark(void)
 
     top = es->top;
     while (es->bottom != top
-           && (es->err_flags[top] & ERR_FLAG_MARK) == 0) {
+           && es->err_marks[top] == 0) {
         top = top > 0 ? top - 1 : ERR_NUM_ERRORS - 1;
     }
 
     if (es->bottom == top)
         return 0;
-    es->err_flags[top] &= ~ERR_FLAG_MARK;
+    es->err_marks[top]--;
     return 1;
 }
 
index 2f9caf2e0ee225dbc6fd96c2ed184a3786252f9d..cad67cc47642e327e94f02cf0afac241cf31e2d0 100644 (file)
@@ -64,6 +64,7 @@ static ossl_inline void err_set_data(ERR_STATE *es, size_t i,
 static ossl_inline void err_clear(ERR_STATE *es, size_t i, int deall)
 {
     err_clear_data(es, i, (deall));
+    es->err_marks[i] = 0;
     es->err_flags[i] = 0;
     es->err_buffer[i] = 0;
     es->err_file[i] = NULL;
index 35db02fad662f89850c41f39f36d009d62293f79..1f2fde83178d75494d889a888c456e9ba49f3589 100644 (file)
@@ -56,6 +56,7 @@ extern "C" {
 #  define ERR_NUM_ERRORS  16
 struct err_state_st {
     int err_flags[ERR_NUM_ERRORS];
+    int err_marks[ERR_NUM_ERRORS];
     unsigned long err_buffer[ERR_NUM_ERRORS];
     char *err_data[ERR_NUM_ERRORS];
     size_t err_data_size[ERR_NUM_ERRORS];