Commit b9e7ec61 authored by Daniel Salzman's avatar Daniel Salzman

libknot: rework knot_map_errno and keep just one variant

The previous knot_map_errno was vulnerable to stack buffer undeflow
if the input list was not terminated with a zero.
parent 7afb8835
......@@ -14,15 +14,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#if HAVE_LMDB
#include <lmdb.h>
#endif
#include "libknot/errcode.h"
#include "libknot/internal/errcode.h"
#include "libknot/internal/macros.h"
#include "dnssec/error.h"
......@@ -189,15 +186,3 @@ const char *knot_strerror(int code)
return fallback_message(code);
}
_public_
int knot_map_errno(int arg0, ...)
{
/* Iterate all variable-length arguments. */
va_list ap;
va_start(ap, arg0);
int ret = knot_map_errno_internal(KNOT_ERROR, arg0, ap);
va_end(ap);
return ret;
}
......@@ -27,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include <errno.h>
#include "libknot/internal/errcode.h"
/*!
......@@ -39,11 +38,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
const char *knot_strerror(int code);
/*!
* \brief Map POSIX errno to Knot error code.
*
* KNOT_ERROR is used as a fallback error, the list is terminated implicitly.
*/
int knot_map_errno(int arg0, ...);
/*! @} */
......@@ -14,35 +14,46 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#if HAVE_LMDB
#include <lmdb.h>
#endif
#include "libknot/internal/errcode.h"
#include "libknot/internal/macros.h"
#define ERR_ITEM(name) { name, KNOT_##name }
typedef struct {
int errno_code;
int libknot_code;
} err_table_t;
/*!
* \brief Errno to libknot error mapping table.
*/
static const err_table_t errno_to_errcode[] = {
ERR_ITEM(ENOMEM),
ERR_ITEM(EINVAL),
ERR_ITEM(ENOTSUP),
ERR_ITEM(EBUSY),
ERR_ITEM(EAGAIN),
ERR_ITEM(EACCES),
ERR_ITEM(ECONNREFUSED),
ERR_ITEM(EISCONN),
ERR_ITEM(EADDRINUSE),
ERR_ITEM(ENOENT),
ERR_ITEM(EEXIST),
ERR_ITEM(ERANGE),
ERR_ITEM(EADDRNOTAVAIL),
/* Terminator - default value. */
{ 0, KNOT_ERROR }
};
_public_
int knot_map_errno_internal(int fallback, int arg0, ...)
int knot_map_errno(void)
{
/* Iterate all variable-length arguments. */
va_list ap;
va_start(ap, arg0);
/* KNOT_ERROR serves as a sentinel. */
for (int c = arg0; c != 0; c = va_arg(ap, int)) {
/* Error code matches with mapped. */
if (c == errno) {
/* Return negative value of the code. */
va_end(ap);
return -abs(c);
}
const err_table_t *err = errno_to_errcode;
while (err->errno_code != 0 && err->errno_code != errno) {
err++;
}
va_end(ap);
/* Fallback error code. */
return KNOT_ERROR;
return err->libknot_code;
}
......@@ -145,13 +145,8 @@ enum knot_error {
/*!
* \brief Get a POSIX errno mapped to Knot error code.
*
* \internal
*
* \param fallback Falback error code.
* \param arg0... Error codes allowed for lookup, list must be terminated by 0.
*
* \return Mapped errno or fallback error code.
* \return Mapped errno or KNOT_ERROR if unknown.
*/
int knot_map_errno_internal(int fallback, int arg0, ...);
int knot_map_errno(void);
/*! @} */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment