Browse Source

Fix ownership of error data in ERR_peek_*.

The error queue should only take ownership of the data if ERR_get_* is called,
not ERR_peek_*. Add a test for ERR_peek_error_line_data.

Change-Id: I976fc90fb54437dff723418ef3afd94f1c967922
Reviewed-on: https://boringssl-review.googlesource.com/2237
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin 10 years ago
committed by Adam Langley
parent
commit
0d82482e47
2 changed files with 28 additions and 9 deletions
  1. +14
    -6
      crypto/err/err.c
  2. +14
    -3
      crypto/err/err_test.c

+ 14
- 6
crypto/err/err.c View File

@@ -181,6 +181,7 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
} }


if (top) { if (top) {
assert(!inc);
/* last error */ /* last error */
i = state->top; i = state->top;
} else { } else {
@@ -211,14 +212,21 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
if (flags != NULL) { if (flags != NULL) {
*flags = error->flags & ERR_FLAG_PUBLIC_MASK; *flags = error->flags & ERR_FLAG_PUBLIC_MASK;
} }
if (error->flags & ERR_FLAG_MALLOCED) {
if (state->to_free) {
OPENSSL_free(state->to_free);
/* If this error is being removed, take ownership of data from
* the error. The semantics are such that the caller doesn't
* take ownership either. Instead the error system takes
* ownership and retains it until the next call that affects the
* error queue. */
if (inc) {
if (error->flags & ERR_FLAG_MALLOCED) {
if (state->to_free) {
OPENSSL_free(state->to_free);
}
state->to_free = error->data;
} }
state->to_free = error->data;
error->data = NULL;
error->flags = 0;
} }
error->data = NULL;
error->flags = 0;
} }
} }




+ 14
- 3
crypto/err/err_test.c View File

@@ -42,9 +42,9 @@ static int test_overflow(void) {
} }


static int test_put_error(void) { static int test_put_error(void) {
uint32_t packed_error;
int line, flags;
const char *file, *data;
uint32_t peeked_packed_error, packed_error;
int peeked_line, line, peeked_flags, flags;
const char *peeked_file, *file, *peeked_data, *data;


if (ERR_get_error() != 0) { if (ERR_get_error() != 0) {
fprintf(stderr, "ERR_get_error returned value before an error was added.\n"); fprintf(stderr, "ERR_get_error returned value before an error was added.\n");
@@ -54,7 +54,18 @@ static int test_put_error(void) {
ERR_put_error(1, 2, 3, "test", 4); ERR_put_error(1, 2, 3, "test", 4);
ERR_add_error_data(1, "testing"); ERR_add_error_data(1, "testing");


peeked_packed_error = ERR_peek_error_line_data(&peeked_file, &peeked_line,
&peeked_data, &peeked_flags);
packed_error = ERR_get_error_line_data(&file, &line, &data, &flags); packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);

if (peeked_packed_error != packed_error ||
peeked_file != file ||
peeked_data != data ||
peeked_flags != flags) {
fprintf(stderr, "Bad peeked error data returned.\n");
return 0;
}

if (strcmp(file, "test") != 0 || if (strcmp(file, "test") != 0 ||
line != 4 || line != 4 ||
(flags & ERR_FLAG_STRING) == 0 || (flags & ERR_FLAG_STRING) == 0 ||


Loading…
Cancel
Save