Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crypto/err/build.info
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
err.c err_all.c err_prn.c
err_blocks.c err.c err_all.c err_prn.c
133 changes: 48 additions & 85 deletions crypto/err/err.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "internal/ctype.h"
#include "internal/constant_time_locl.h"
#include "e_os.h"
#include "err_locl.h"

static int err_load_strings(const ERR_STRING_DATA *str);

Expand Down Expand Up @@ -235,32 +236,14 @@ static void build_SYS_str_reasons(void)
}
#endif

#define err_clear_data(p, i) \
do { \
if ((p)->err_data_flags[i] & ERR_TXT_MALLOCED) {\
OPENSSL_free((p)->err_data[i]); \
(p)->err_data[i] = NULL; \
} \
(p)->err_data_flags[i] = 0; \
} while (0)

#define err_clear(p, i) \
do { \
err_clear_data(p, i); \
(p)->err_flags[i] = 0; \
(p)->err_buffer[i] = 0; \
(p)->err_file[i] = NULL; \
(p)->err_line[i] = -1; \
} while (0)

static void ERR_STATE_free(ERR_STATE *s)
{
int i;

if (s == NULL)
return;
for (i = 0; i < ERR_NUM_ERRORS; i++) {
err_clear_data(s, i);
err_clear_data(s, i, 1);
}
OPENSSL_free(s);
}
Expand Down Expand Up @@ -372,50 +355,6 @@ void err_free_strings_int(void)

/********************************************************/

void ERR_put_func_error(int lib, const char *func, int reason,
const char *file, int line)
{
ERR_put_error(lib, 0, reason, file, line);
ERR_add_error_data(2, "calling function ", func);
}

void ERR_put_error(int lib, int func, int reason, const char *file, int line)
{
ERR_STATE *es;

#ifdef _OSD_POSIX
/*
* In the BS2000-OSD POSIX subsystem, the compiler generates path names
* in the form "*POSIX(/etc/passwd)". This dirty hack strips them to
* something sensible. @@@ We shouldn't modify a const string, though.
*/
if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) {
char *end;

/* Skip the "*POSIX(" prefix */
file += sizeof("*POSIX(") - 1;
end = &file[strlen(file) - 1];
if (*end == ')')
*end = '\0';
/* Optional: use the basename of the path only. */
if ((end = strrchr(file, '/')) != NULL)
file = &end[1];
}
#endif
es = ERR_get_state();
if (es == NULL)
return;

es->top = (es->top + 1) % ERR_NUM_ERRORS;
if (es->top == es->bottom)
es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS;
es->err_flags[es->top] = 0;
es->err_buffer[es->top] = ERR_PACK(lib, func, reason);
es->err_file[es->top] = file;
es->err_line[es->top] = line;
err_clear_data(es, es->top);
}

void ERR_clear_error(void)
{
int i;
Expand All @@ -426,7 +365,7 @@ void ERR_clear_error(void)
return;

for (i = 0; i < ERR_NUM_ERRORS; i++) {
err_clear(es, i);
err_clear(es, i, 0);
}
es->top = es->bottom = 0;
}
Expand Down Expand Up @@ -506,14 +445,14 @@ static unsigned long get_error_values(int inc, int top, const char **file,

while (es->bottom != es->top) {
if (es->err_flags[es->top] & ERR_FLAG_CLEAR) {
err_clear(es, es->top);
err_clear(es, es->top, 0);
es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1;
continue;
}
i = (es->bottom + 1) % ERR_NUM_ERRORS;
if (es->err_flags[i] & ERR_FLAG_CLEAR) {
es->bottom = i;
err_clear(es, es->bottom);
err_clear(es, es->bottom, 0);
continue;
}
break;
Expand Down Expand Up @@ -545,7 +484,7 @@ static unsigned long get_error_values(int inc, int top, const char **file,

if (data == NULL) {
if (inc) {
err_clear_data(es, i);
err_clear_data(es, i, 0);
}
} else {
if (es->err_data[i] == NULL) {
Expand Down Expand Up @@ -772,20 +711,17 @@ int ERR_get_next_error_library(void)
return ret;
}

static int err_set_error_data_int(char *data, int flags)
static int err_set_error_data_int(char *data, size_t size, int flags,
int deallocate)
{
ERR_STATE *es;
int i;

es = ERR_get_state();
if (es == NULL)
return 0;

i = es->top;

err_clear_data(es, i);
es->err_data[i] = data;
es->err_data_flags[i] = flags;
err_clear_data(es, es->top, deallocate);
err_set_data(es, es->top, data, size, flags);

return 1;
}
Expand All @@ -795,8 +731,18 @@ void ERR_set_error_data(char *data, int flags)
/*
* This function is void so we cannot propagate the error return. Since it
* is also in the public API we can't change the return type.
*
* We estimate the size of the data. If it's not flagged as allocated,
* then this is safe, and if it is flagged as allocated, then our size
* may be smaller than the actual allocation, but that doesn't matter
* too much, the buffer will remain untouched or will eventually be
* reallocated to a new size.
*
* callers should be advised that this function takes over ownership of
* the allocated memory, i.e. they can't count on the pointer to remain
* valid.
*/
err_set_error_data_int(data, flags);
err_set_error_data_int(data, strlen(data) + 1, flags, 1);
}

void ERR_add_error_data(int num, ...)
Expand All @@ -810,31 +756,48 @@ void ERR_add_error_data(int num, ...)
void ERR_add_error_vdata(int num, va_list args)
{
int i, len, size;
char *str, *p, *arg;
int flags = ERR_TXT_MALLOCED | ERR_TXT_STRING;
char *str, *arg;
ERR_STATE *es;

/* Get the current error data; if an allocated string get it. */
es = ERR_get_state();
if (es == NULL)
return;
i = es->top;
p = es->err_data_flags[i] == (ERR_TXT_MALLOCED | ERR_TXT_STRING)
? es->err_data[i] : "";

/* Start with initial (or empty) string and allocate a new buffer */
size = 80 + strlen(p);
if ((str = OPENSSL_malloc(size + 1)) == NULL) {
/* ERRerr(ERR_F_ERR_ADD_ERROR_VDATA, ERR_R_MALLOC_FAILURE); */
/*
* If err_data is allocated already, re-use the space.
* Otherwise, allocate a small new buffer.
*/
if ((es->err_data_flags[i] & flags) == flags) {
str = es->err_data[i];
size = es->err_data_size[i];

/*
* To protect the string we just grabbed from tampering by other
* functions we may call, or to protect them from freeing a pointer
* that may no longer be valid at that point, we clear away the
* data pointer and the flags. We will set them again at the end
* of this function.
*/
es->err_data[i] = NULL;
es->err_data_flags[i] = 0;
} else if ((str = OPENSSL_malloc(size = 81)) == NULL) {
return;
} else {
str[0] = '\0';
}
strcpy(str, p);
len = strlen(str);

for (len = 0; --num >= 0; ) {
arg = va_arg(args, char *);
if (arg == NULL)
arg = "<NULL>";
len += strlen(arg);
if (len > size) {
char *p;

size = len + 20;
p = OPENSSL_realloc(str, size + 1);
if (p == NULL) {
Expand All @@ -845,7 +808,7 @@ void ERR_add_error_vdata(int num, va_list args)
}
OPENSSL_strlcat(str, arg, (size_t)size + 1);
}
if (!err_set_error_data_int(str, ERR_TXT_MALLOCED | ERR_TXT_STRING))
if (!err_set_error_data_int(str, size, flags, 0))
OPENSSL_free(str);
}

Expand Down Expand Up @@ -873,7 +836,7 @@ int ERR_pop_to_mark(void)

while (es->bottom != es->top
&& (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) {
err_clear(es, es->top);
err_clear(es, es->top, 0);
es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1;
}

Expand Down
113 changes: 113 additions & 0 deletions crypto/err/err_blocks.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

#include <string.h>
#include <openssl/err.h>
#include "err_locl.h"

void ERR_new(void)
{
ERR_STATE *es;

es = ERR_get_state();
if (es == NULL)
return;

/* Allocate a slot */
err_get_slot(es);
err_clear(es, es->top, 0);
}

void ERR_set_debug(const char *file, int line, const char *func)
{
ERR_STATE *es;

es = ERR_get_state();
if (es == NULL)
return;

err_set_debug(es, es->top, file, line, func);
}

void ERR_set_error(int lib, int reason, const char *fmt, ...)
{
va_list args;

va_start(args, fmt);
ERR_vset_error(lib, reason, fmt, args);
va_end(args);
}

void ERR_vset_error(int lib, int reason, const char *fmt, va_list args)
{
ERR_STATE *es;
char *buf = NULL;
size_t buf_size = 0;
unsigned long flags = 0;
size_t i;

es = ERR_get_state();
if (es == NULL)
return;
i = es->top;

if (fmt != NULL) {
int printed_len = 0;
char *rbuf = NULL;

buf = es->err_data[i];
buf_size = es->err_data_size[i];

/*
* To protect the string we just grabbed from tampering by other
* functions we may call, or to protect them from freeing a pointer
* that may no longer be valid at that point, we clear away the
* data pointer and the flags. We will set them again at the end
* of this function.
*/
es->err_data[i] = NULL;
es->err_data_flags[i] = 0;

/*
* Try to maximize the space available. If that fails, we use what
* we have.
*/
if (buf_size < ERR_MAX_DATA_SIZE
&& (rbuf = OPENSSL_realloc(buf, ERR_MAX_DATA_SIZE)) != NULL) {
buf = rbuf;
buf_size = ERR_MAX_DATA_SIZE;
}

if (buf != NULL) {
printed_len = BIO_vsnprintf(buf, ERR_MAX_DATA_SIZE, fmt, args);
}
if (printed_len < 0)
printed_len = 0;
buf[printed_len] = '\0';

/*
* Try to reduce the size, but only if we maximized above. If that
* fails, we keep what we have.
* (According to documentation, realloc leaves the old buffer untouched
* if it fails)
*/
if ((rbuf = OPENSSL_realloc(buf, printed_len + 1)) != NULL) {
buf = rbuf;
buf_size = printed_len + 1;
}

if (buf != NULL)
flags = ERR_TXT_MALLOCED | ERR_TXT_STRING;
}

err_clear_data(es, es->top, 0);
err_set_error(es, es->top, lib, reason);
if (fmt != NULL)
err_set_data(es, es->top, buf, buf_size, flags);
}
Loading