Skip to content

Commit

Permalink
Merge pull request #315 from alltilla/filterx-fixes
Browse files Browse the repository at this point in the history
filterx: fix use after free in `strptime()` and macro caching
  • Loading branch information
MrAnno authored Sep 30, 2024
2 parents 1f591bb + d23d626 commit fd5dfb1
Show file tree
Hide file tree
Showing 47 changed files with 172 additions and 128 deletions.
8 changes: 4 additions & 4 deletions lib/filterx/expr-comparison.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ _convert_filterx_object_to_generic_number(FilterXObject *obj, GenericNumber *gn)
return;

const gchar *str;
if (filterx_object_extract_string(obj, &str, NULL))
if (filterx_object_extract_string_ref(obj, &str, NULL))
{
if (!parse_generic_number(str, gn))
gn_set_nan(gn);
Expand Down Expand Up @@ -77,9 +77,9 @@ static const gchar *
_convert_filterx_object_to_string(FilterXObject *obj, gsize *len)
{
const gchar *str;
if (filterx_object_extract_string(obj, &str, len) ||
filterx_object_extract_bytes(obj, &str, len) ||
filterx_object_extract_protobuf(obj, &str, len))
if (filterx_object_extract_string_ref(obj, &str, len) ||
filterx_object_extract_bytes_ref(obj, &str, len) ||
filterx_object_extract_protobuf_ref(obj, &str, len))
{
return str;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/filterx/expr-function.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ _get_literal_string_from_expr(FilterXExpr *expr, gsize *len)
goto error;

/* Literal message values don't exist, so we don't need to use the extractor. */
str = filterx_string_get_value(obj, len);
str = filterx_string_get_value_ref(obj, len);

/*
* We can unref both obj and expr, the underlying string will be kept alive as long as the literal expr is alive,
Expand Down
2 changes: 1 addition & 1 deletion lib/filterx/expr-regexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ _match(FilterXExpr *lhs_expr, pcre2_code_8 *pattern, FilterXReMatchState *state)
if (!state->lhs_obj)
goto error;

if (!filterx_object_extract_string(state->lhs_obj, &state->lhs_str, &state->lhs_str_len))
if (!filterx_object_extract_string_ref(state->lhs_obj, &state->lhs_str, &state->lhs_str_len))
{
msg_error("FilterX: Regexp matching left hand side must be string type",
evt_tag_str("type", state->lhs_obj->type->name));
Expand Down
9 changes: 7 additions & 2 deletions lib/filterx/expr-variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ _pull_variable_from_message(FilterXVariableExpr *self, FilterXEvalContext *conte
return NULL;
}

FilterXObject *msg_ref = filterx_message_value_new_borrowed(value, value_len, t);
FilterXObject *msg_ref;
if (log_msg_is_value_from_macro(value))
msg_ref = filterx_message_value_new(value, value_len, t);
else
msg_ref = filterx_message_value_new_borrowed(value, value_len, t);

filterx_scope_register_variable(context->scope, self->handle, msg_ref);
return msg_ref;
}
Expand Down Expand Up @@ -178,7 +183,7 @@ filterx_variable_expr_new(FilterXString *name, FilterXVariableType type)
self->super.unset = _unset;

self->variable_name = (FilterXObject *) name;
self->handle = filterx_scope_map_variable_to_handle(filterx_string_get_value(self->variable_name, NULL), type);
self->handle = filterx_scope_map_variable_to_handle(filterx_string_get_value_ref(self->variable_name, NULL), type);

return &self->super;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/filterx/filterx-metrics-labels.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ _init_label_name(FilterXExpr *name)
}

FilterXObject *obj = filterx_expr_eval_typed(name);
gchar *str = g_strdup(filterx_string_get_value(obj, NULL));
gchar *str = g_strdup(filterx_string_get_value_ref(obj, NULL));
if (!str)
filterx_eval_push_error_info("failed to initialize metrics label name, name must be a string literal", name,
g_strdup_printf("got %s instead", obj->type->name), TRUE);
Expand Down
4 changes: 2 additions & 2 deletions lib/filterx/filterx-metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ _format_sck_name(FilterXMetrics *self)

gsize len;
const gchar *name;
if (!filterx_object_extract_string(key_obj, &name, &len) || len == 0)
if (!filterx_object_extract_string_ref(key_obj, &name, &len) || len == 0)
{
filterx_eval_push_error("failed to format metrics key: key must be a non-empty string", self->key.expr, key_obj);
goto exit;
Expand Down Expand Up @@ -216,7 +216,7 @@ _init_key(FilterXMetrics *self, FilterXExpr *key)
}

/* There are no literal message values, so we don't need to call extract_string() here. */
self->key.str = g_strdup(filterx_string_get_value(key_obj, NULL));
self->key.str = g_strdup(filterx_string_get_value_ref(key_obj, NULL));
return TRUE;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/filterx/func-str-transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ _extract_str_arg(FilterXExpr *s, GPtrArray *args, gssize *len)
gsize inner_len;
FilterXObject *object = g_ptr_array_index(args, 0);

if (!filterx_object_extract_string(object, &str, &inner_len))
if (!filterx_object_extract_string_ref(object, &str, &inner_len))
{
filterx_simple_function_argument_error(s, "Object must be string", FALSE);
return NULL;
Expand Down
4 changes: 2 additions & 2 deletions lib/filterx/func-unset-empties.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static gboolean _should_unset_string(FilterXFunctionUnsetEmpties *self, FilterXO
gsize str_len = 0;
const gchar *str = NULL;
gchar *casefold_str = NULL;
if (!filterx_object_extract_string(obj, &str, &str_len))
if (!filterx_object_extract_string_ref(obj, &str, &str_len))
return FALSE;
g_assert(str);

Expand Down Expand Up @@ -376,7 +376,7 @@ _handle_target_object(FilterXFunctionUnsetEmpties *self, FilterXObject *target,
}
else if (filterx_object_is_type(target, &FILTERX_TYPE_NAME(string)))
{
const gchar *str = filterx_string_get_value(target, &len);
const gchar *str = filterx_string_get_value_ref(target, &len);
if (len == 0)
{
set_flag(&self->flags, FILTERX_FUNC_UNSET_EMPTIES_FLAG_REPLACE_EMPTY_STRING, TRUE);
Expand Down
7 changes: 4 additions & 3 deletions lib/filterx/object-datetime.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ filterx_typecast_datetime_isodate(FilterXExpr *s, GPtrArray *args)

const gchar *str;
gsize len;
if (!filterx_object_extract_string(object, &str, &len))
if (!filterx_object_extract_string_ref(object, &str, &len))
return NULL;

UnixTime ut = UNIX_TIME_INIT;
Expand Down Expand Up @@ -254,11 +254,11 @@ _strptime_eval(FilterXExpr *s)

const gchar *time_str;
gsize time_str_len;
gboolean extract_success = filterx_object_extract_string(time_str_obj, &time_str, &time_str_len);
filterx_object_unref(time_str_obj);
gboolean extract_success = filterx_object_extract_string_ref(time_str_obj, &time_str, &time_str_len);

if (!extract_success)
{
filterx_object_unref(time_str_obj);
filterx_eval_push_error("First argument must be string typed. " FILTERX_FUNC_STRPTIME_USAGE, s, NULL);
return NULL;
}
Expand Down Expand Up @@ -289,6 +289,7 @@ _strptime_eval(FilterXExpr *s)
else
result = filterx_null_new();

filterx_object_unref(time_str_obj);
return result;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/filterx/object-dict-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ _add_elem_to_json_object(FilterXObject *key_obj, FilterXObject *value_obj, gpoin

const gchar *key;
gsize len;
if (!filterx_object_extract_string(key_obj, &key, &len))
if (!filterx_object_extract_string_ref(key_obj, &key, &len))
return FALSE;

APPEND_ZERO(key, key, len);
Expand Down
18 changes: 9 additions & 9 deletions lib/filterx/object-extractor.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,32 @@
#include "filterx/object-json.h"

gboolean
filterx_object_extract_string(FilterXObject *obj, const gchar **value, gsize *len)
filterx_object_extract_string_ref(FilterXObject *obj, const gchar **value, gsize *len)
{
if (filterx_object_is_type(obj, &FILTERX_TYPE_NAME(message_value)))
return filterx_message_value_get_string(obj, value, len);
return filterx_message_value_get_string_ref(obj, value, len);

*value = filterx_string_get_value(obj, len);
*value = filterx_string_get_value_ref(obj, len);
return !!(*value);
}

gboolean
filterx_object_extract_bytes(FilterXObject *obj, const gchar **value, gsize *len)
filterx_object_extract_bytes_ref(FilterXObject *obj, const gchar **value, gsize *len)
{
if (filterx_object_is_type(obj, &FILTERX_TYPE_NAME(message_value)))
return filterx_message_value_get_bytes(obj, value, len);
return filterx_message_value_get_bytes_ref(obj, value, len);

*value = filterx_bytes_get_value(obj, len);
*value = filterx_bytes_get_value_ref(obj, len);
return !!(*value);
}

gboolean
filterx_object_extract_protobuf(FilterXObject *obj, const gchar **value, gsize *len)
filterx_object_extract_protobuf_ref(FilterXObject *obj, const gchar **value, gsize *len)
{
if (filterx_object_is_type(obj, &FILTERX_TYPE_NAME(message_value)))
return filterx_message_value_get_protobuf(obj, value, len);
return filterx_message_value_get_protobuf_ref(obj, value, len);

*value = filterx_protobuf_get_value(obj, len);
*value = filterx_protobuf_get_value_ref(obj, len);
return !!(*value);
}

Expand Down
6 changes: 3 additions & 3 deletions lib/filterx/object-extractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
#include "generic-number.h"
#include "compat/json.h"

gboolean filterx_object_extract_string(FilterXObject *obj, const gchar **value, gsize *len);
gboolean filterx_object_extract_bytes(FilterXObject *obj, const gchar **value, gsize *len);
gboolean filterx_object_extract_protobuf(FilterXObject *obj, const gchar **value, gsize *len);
gboolean filterx_object_extract_string_ref(FilterXObject *obj, const gchar **value, gsize *len);
gboolean filterx_object_extract_bytes_ref(FilterXObject *obj, const gchar **value, gsize *len);
gboolean filterx_object_extract_protobuf_ref(FilterXObject *obj, const gchar **value, gsize *len);
gboolean filterx_object_extract_boolean(FilterXObject *obj, gboolean *value);
gboolean filterx_object_extract_integer(FilterXObject *obj, gint64 *value);
gboolean filterx_object_extract_double(FilterXObject *obj, gdouble *value);
Expand Down
2 changes: 1 addition & 1 deletion lib/filterx/object-json-array.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ filterx_json_array_new_from_args(FilterXExpr *s, GPtrArray *args)

const gchar *repr;
gsize repr_len;
if (filterx_object_extract_string(arg, &repr, &repr_len))
if (filterx_object_extract_string_ref(arg, &repr, &repr_len))
return filterx_json_array_new_from_repr(repr, repr_len);

filterx_eval_push_error_info("Argument must be a json array, a string or a syslog-ng list", s,
Expand Down
6 changes: 3 additions & 3 deletions lib/filterx/object-json-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ _get_subscript(FilterXDict *s, FilterXObject *key)

const gchar *key_str;
gsize len;
if (!filterx_object_extract_string(key, &key_str, &len))
if (!filterx_object_extract_string_ref(key, &key_str, &len))
return NULL;

APPEND_ZERO(key_str, key_str, len);
Expand All @@ -128,7 +128,7 @@ _set_subscript(FilterXDict *s, FilterXObject *key, FilterXObject **new_value)

const gchar *key_str;
gsize len;
if (!filterx_object_extract_string(key, &key_str, &len))
if (!filterx_object_extract_string_ref(key, &key_str, &len))
return FALSE;

APPEND_ZERO(key_str, key_str, len);
Expand Down Expand Up @@ -168,7 +168,7 @@ _unset_key(FilterXDict *s, FilterXObject *key)

const gchar *key_str;
gsize len;
if (!filterx_object_extract_string(key, &key_str, &len))
if (!filterx_object_extract_string_ref(key, &key_str, &len))
return FALSE;

APPEND_ZERO(key_str, key_str, len);
Expand Down
2 changes: 1 addition & 1 deletion lib/filterx/object-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ filterx_json_new_from_args(FilterXExpr *s, GPtrArray *args)

const gchar *repr;
gsize repr_len;
if (filterx_object_extract_string(arg, &repr, &repr_len))
if (filterx_object_extract_string_ref(arg, &repr, &repr_len))
return filterx_json_new_from_repr(repr, repr_len);

filterx_eval_push_error_info("Argument must be a json, a string or a syslog-ng list", s,
Expand Down
6 changes: 3 additions & 3 deletions lib/filterx/object-message-value.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ typedef struct _FilterXMessageValue
} FilterXMessageValue;

gboolean
filterx_message_value_get_string(FilterXObject *s, const gchar **value, gsize *len)
filterx_message_value_get_string_ref(FilterXObject *s, const gchar **value, gsize *len)
{
FilterXMessageValue *self = (FilterXMessageValue *) s;

Expand All @@ -56,7 +56,7 @@ filterx_message_value_get_string(FilterXObject *s, const gchar **value, gsize *l
}

gboolean
filterx_message_value_get_bytes(FilterXObject *s, const gchar **value, gsize *len)
filterx_message_value_get_bytes_ref(FilterXObject *s, const gchar **value, gsize *len)
{
FilterXMessageValue *self = (FilterXMessageValue *) s;

Expand All @@ -69,7 +69,7 @@ filterx_message_value_get_bytes(FilterXObject *s, const gchar **value, gsize *le
}

gboolean
filterx_message_value_get_protobuf(FilterXObject *s, const gchar **value, gsize *len)
filterx_message_value_get_protobuf_ref(FilterXObject *s, const gchar **value, gsize *len)
{
FilterXMessageValue *self = (FilterXMessageValue *) s;

Expand Down
6 changes: 3 additions & 3 deletions lib/filterx/object-message-value.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ FilterXObject *filterx_message_value_new(const gchar *repr, gssize repr_len, Log
LogMessageValueType filterx_message_value_get_type(FilterXObject *s);
const gchar *filterx_message_value_get_value(FilterXObject *s, gsize *len);

gboolean filterx_message_value_get_string(FilterXObject *s, const gchar **value, gsize *len);
gboolean filterx_message_value_get_bytes(FilterXObject *s, const gchar **value, gsize *len);
gboolean filterx_message_value_get_protobuf(FilterXObject *s, const gchar **value, gsize *len);
gboolean filterx_message_value_get_string_ref(FilterXObject *s, const gchar **value, gsize *len);
gboolean filterx_message_value_get_bytes_ref(FilterXObject *s, const gchar **value, gsize *len);
gboolean filterx_message_value_get_protobuf_ref(FilterXObject *s, const gchar **value, gsize *len);
gboolean filterx_message_value_get_boolean(FilterXObject *s, gboolean *value);
gboolean filterx_message_value_get_integer(FilterXObject *s, gint64 *value);
gboolean filterx_message_value_get_double(FilterXObject *s, gdouble *value);
Expand Down
4 changes: 2 additions & 2 deletions lib/filterx/object-primitive.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ filterx_typecast_integer(FilterXExpr *s, GPtrArray *args)

const gchar *str;
gsize str_len;
if (filterx_object_extract_string(object, &str, &str_len))
if (filterx_object_extract_string_ref(object, &str, &str_len))
{
APPEND_ZERO(str, str, str_len);

Expand Down Expand Up @@ -334,7 +334,7 @@ filterx_typecast_double(FilterXExpr *s, GPtrArray *args)

const gchar *str;
gsize str_len;
if (filterx_object_extract_string(object, &str, &str_len))
if (filterx_object_extract_string_ref(object, &str, &str_len))
{
APPEND_ZERO(str, str, str_len);

Expand Down
24 changes: 12 additions & 12 deletions lib/filterx/object-string.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ struct _FilterXString
gchar str[];
};

/* NOTE: Consider using filterx_object_extract_string() to also support message_value. */
/* NOTE: Consider using filterx_object_extract_string_ref() to also support message_value. */
const gchar *
filterx_string_get_value(FilterXObject *s, gsize *length)
filterx_string_get_value_ref(FilterXObject *s, gsize *length)
{
FilterXString *self = (FilterXString *) s;

Expand All @@ -52,9 +52,9 @@ filterx_string_get_value(FilterXObject *s, gsize *length)
return self->str;
}

/* NOTE: Consider using filterx_object_extract_bytes() to also support message_value. */
/* NOTE: Consider using filterx_object_extract_bytes_ref() to also support message_value. */
const gchar *
filterx_bytes_get_value(FilterXObject *s, gsize *length)
filterx_bytes_get_value_ref(FilterXObject *s, gsize *length)
{
FilterXString *self = (FilterXString *) s;

Expand All @@ -67,9 +67,9 @@ filterx_bytes_get_value(FilterXObject *s, gsize *length)
return self->str;
}

/* NOTE: Consider using filterx_object_extract_protobuf() to also support message_value. */
/* NOTE: Consider using filterx_object_extract_protobuf_ref() to also support message_value. */
const gchar *
filterx_protobuf_get_value(FilterXObject *s, gsize *length)
filterx_protobuf_get_value_ref(FilterXObject *s, gsize *length)
{
FilterXString *self = (FilterXString *) s;

Expand Down Expand Up @@ -132,7 +132,7 @@ _string_add(FilterXObject *s, FilterXObject *object)

const gchar *other_str;
gsize other_str_len;
if (!filterx_object_extract_string(object, &other_str, &other_str_len))
if (!filterx_object_extract_string_ref(object, &other_str, &other_str_len))
return NULL;

GString *buffer = scratch_buffers_alloc();
Expand Down Expand Up @@ -234,7 +234,7 @@ _bytes_add(FilterXObject *s, FilterXObject *object)

const gchar *other_str;
gsize other_str_len;
if (!filterx_object_extract_bytes(object, &other_str, &other_str_len))
if (!filterx_object_extract_bytes_ref(object, &other_str, &other_str_len))
return NULL;

GString *buffer = scratch_buffers_alloc();
Expand Down Expand Up @@ -297,8 +297,8 @@ filterx_typecast_bytes(FilterXExpr *s, GPtrArray *args)

const gchar *data;
gsize size;
if (filterx_object_extract_string(object, &data, &size) ||
filterx_object_extract_protobuf(object, &data, &size))
if (filterx_object_extract_string_ref(object, &data, &size) ||
filterx_object_extract_protobuf_ref(object, &data, &size))
{
return filterx_bytes_new(data, size);
}
Expand All @@ -324,8 +324,8 @@ filterx_typecast_protobuf(FilterXExpr *s, GPtrArray *args)

const gchar *data;
gsize size;
if (filterx_object_extract_protobuf(object, &data, &size) ||
filterx_object_extract_bytes(object, &data, &size))
if (filterx_object_extract_protobuf_ref(object, &data, &size) ||
filterx_object_extract_bytes_ref(object, &data, &size))
return filterx_protobuf_new(data, size);

msg_error("filterx: invalid typecast",
Expand Down
Loading

0 comments on commit fd5dfb1

Please sign in to comment.