var: Use 16-bit container for type

Issue: 6855: Match sigmatch type field in var and bit structs

Align the size and datatype of type, idx, and next members across:
- FlowVarThreshold
- FlowBit
- FlowVar
- GenericVar
- XBit
- DetectVarList

Note that the FlowVar structure has been intentionally constrained to
match the structure size prior to this commit. To achieve this, the
keylen member was restricted to 8 bits after it was confirmed its value
is checked against a max of 0xff.
pull/12743/head
Jeff Lucovsky 9 months ago committed by Victor Julien
parent d8ddef4c14
commit 3d26f917ee

@ -56,8 +56,7 @@ enum DetectKeywordId {
DETECT_FLOW, DETECT_FLOW,
/* end prefilter sort */ /* end prefilter sort */
/* values used in util-var.c go here, to avoid int overflows /* values used in util-var.c go here, to avoid int overflows */
* TODO update var logic to use a larger type, see #6855. */
DETECT_THRESHOLD, DETECT_THRESHOLD,
DETECT_FLOWBITS, DETECT_FLOWBITS,
DETECT_FLOWVAR, DETECT_FLOWVAR,

@ -524,8 +524,8 @@ static void FlowThresholdEntryListFree(FlowThresholdEntryList *list)
/** struct for storing per flow thresholds. This will be stored in the Flow::flowvar list, so it /** struct for storing per flow thresholds. This will be stored in the Flow::flowvar list, so it
* needs to follow the GenericVar header format. */ * needs to follow the GenericVar header format. */
typedef struct FlowVarThreshold_ { typedef struct FlowVarThreshold_ {
uint8_t type; uint16_t type;
uint8_t pad[7]; uint8_t pad[6];
struct GenericVar_ *next; struct GenericVar_ *next;
FlowThresholdEntryList *thresholds; FlowThresholdEntryList *thresholds;
} FlowVarThreshold; } FlowVarThreshold;

@ -200,9 +200,8 @@ error:
} }
/** \brief Store flowvar in det_ctx so we can exec it post-match */ /** \brief Store flowvar in det_ctx so we can exec it post-match */
int DetectVarStoreMatchKeyValue(DetectEngineThreadCtx *det_ctx, int DetectVarStoreMatchKeyValue(DetectEngineThreadCtx *det_ctx, uint8_t *key, uint16_t key_len,
uint8_t *key, uint16_t key_len, uint8_t *buffer, uint16_t len, uint16_t type)
uint8_t *buffer, uint16_t len, int type)
{ {
DetectVarList *fs = SCCalloc(1, sizeof(*fs)); DetectVarList *fs = SCCalloc(1, sizeof(*fs));
if (unlikely(fs == NULL)) if (unlikely(fs == NULL))
@ -220,9 +219,8 @@ int DetectVarStoreMatchKeyValue(DetectEngineThreadCtx *det_ctx,
} }
/** \brief Store flowvar in det_ctx so we can exec it post-match */ /** \brief Store flowvar in det_ctx so we can exec it post-match */
int DetectVarStoreMatch(DetectEngineThreadCtx *det_ctx, int DetectVarStoreMatch(
uint32_t idx, DetectEngineThreadCtx *det_ctx, uint32_t idx, uint8_t *buffer, uint16_t len, uint16_t type)
uint8_t *buffer, uint16_t len, int type)
{ {
DetectVarList *fs = det_ctx->varlist; DetectVarList *fs = det_ctx->varlist;

@ -38,10 +38,9 @@ typedef struct DetectFlowvarData_ {
void DetectFlowvarRegister (void); void DetectFlowvarRegister (void);
int DetectFlowvarPostMatchSetup(DetectEngineCtx *de_ctx, Signature *s, uint32_t idx); int DetectFlowvarPostMatchSetup(DetectEngineCtx *de_ctx, Signature *s, uint32_t idx);
int DetectVarStoreMatch(DetectEngineThreadCtx *, int DetectVarStoreMatch(DetectEngineThreadCtx *, uint32_t, uint8_t *, uint16_t, uint16_t);
uint32_t, uint8_t *, uint16_t, int); int DetectVarStoreMatchKeyValue(
int DetectVarStoreMatchKeyValue(DetectEngineThreadCtx *, DetectEngineThreadCtx *, uint8_t *, uint16_t, uint8_t *, uint16_t, uint16_t);
uint8_t *, uint16_t, uint8_t *, uint16_t, int);
/* For use only by DetectFlowvarProcessList() */ /* For use only by DetectFlowvarProcessList() */
void DetectVarProcessListInternal(DetectVarList *fs, Flow *f, Packet *p); void DetectVarProcessListInternal(DetectVarList *fs, Flow *f, Packet *p);

@ -129,7 +129,7 @@ static int GetFlowVarByKey(lua_State *luastate, Flow *f, FlowVar **ret_fv)
LUA_ERROR("key len out of range: max 256"); LUA_ERROR("key len out of range: max 256");
} }
FlowVar *fv = FlowVarGetByKey(f, (const uint8_t *)keystr, (uint16_t)keylen); FlowVar *fv = FlowVarGetByKey(f, (const uint8_t *)keystr, (uint8_t)keylen);
if (fv == NULL) { if (fv == NULL) {
LUA_ERROR("no flow var"); LUA_ERROR("no flow var");
} }
@ -302,7 +302,7 @@ static int LuaSetFlowvarByKey(lua_State *luastate)
} }
memcpy(keybuf, keystr, keylen); memcpy(keybuf, keystr, keylen);
keybuf[keylen] = '\0'; keybuf[keylen] = '\0';
FlowVarAddKeyValue(f, keybuf, (uint16_t)keylen, buffer, (uint16_t)len); FlowVarAddKeyValue(f, keybuf, (uint8_t)keylen, buffer, (uint16_t)len);
return 0; return 0;
} }

@ -760,10 +760,11 @@ typedef struct DetectReplaceList_ {
/** list for flowvar store candidates, to be stored from /** list for flowvar store candidates, to be stored from
* post-match function */ * post-match function */
typedef struct DetectVarList_ { typedef struct DetectVarList_ {
uint16_t type; /**< type of store candidate POSTMATCH or ALWAYS */
uint8_t pad[2];
uint32_t idx; /**< flowvar name idx */ uint32_t idx; /**< flowvar name idx */
uint16_t len; /**< data len */ uint16_t len; /**< data len */
uint16_t key_len; uint16_t key_len;
int type; /**< type of store candidate POSTMATCH or ALWAYS */
uint8_t *key; uint8_t *key;
uint8_t *buffer; /**< alloc'd buffer, may be freed by uint8_t *buffer; /**< alloc'd buffer, may be freed by
post-match, post-non-match */ post-match, post-non-match */

@ -28,8 +28,8 @@
#include "util-var.h" #include "util-var.h"
typedef struct FlowBit_ { typedef struct FlowBit_ {
uint8_t type; /* type, DETECT_FLOWBITS in this case */ uint16_t type; /* type, DETECT_FLOWBITS in this case */
uint8_t pad[3]; uint8_t pad[2];
uint32_t idx; /* name idx */ uint32_t idx; /* name idx */
GenericVar *next; /* right now just implement this as a list, GenericVar *next; /* right now just implement this as a list,
* in the long run we have think of something * in the long run we have think of something

@ -51,7 +51,7 @@ static void FlowVarUpdateInt(FlowVar *fv, uint32_t value)
* \note flow is not locked by this function, caller is * \note flow is not locked by this function, caller is
* responsible * responsible
*/ */
FlowVar *FlowVarGetByKey(Flow *f, const uint8_t *key, uint16_t keylen) FlowVar *FlowVarGetByKey(Flow *f, const uint8_t *key, FlowVarKeyLenType keylen)
{ {
if (f == NULL) if (f == NULL)
return NULL; return NULL;
@ -91,7 +91,8 @@ FlowVar *FlowVarGet(Flow *f, uint32_t idx)
} }
/* add a flowvar to the flow, or update it */ /* add a flowvar to the flow, or update it */
void FlowVarAddKeyValue(Flow *f, uint8_t *key, uint16_t keysize, uint8_t *value, uint16_t size) void FlowVarAddKeyValue(
Flow *f, uint8_t *key, FlowVarKeyLenType keylen, uint8_t *value, uint16_t size)
{ {
FlowVar *fv = SCCalloc(1, sizeof(FlowVar)); FlowVar *fv = SCCalloc(1, sizeof(FlowVar));
if (unlikely(fv == NULL)) if (unlikely(fv == NULL))
@ -103,7 +104,7 @@ void FlowVarAddKeyValue(Flow *f, uint8_t *key, uint16_t keysize, uint8_t *value,
fv->data.fv_str.value = value; fv->data.fv_str.value = value;
fv->data.fv_str.value_len = size; fv->data.fv_str.value_len = size;
fv->key = key; fv->key = key;
fv->keylen = keysize; fv->keylen = keylen;
fv->next = NULL; fv->next = NULL;
GenericVarAppend(&f->flowvar, (GenericVar *)fv); GenericVarAppend(&f->flowvar, (GenericVar *)fv);

@ -33,6 +33,7 @@
#define FLOWVAR_TYPE_STR 1 #define FLOWVAR_TYPE_STR 1
#define FLOWVAR_TYPE_INT 2 #define FLOWVAR_TYPE_INT 2
typedef uint8_t FlowVarKeyLenType;
/** Struct used to hold the string data type for flowvars */ /** Struct used to hold the string data type for flowvars */
typedef struct FlowVarTypeStr { typedef struct FlowVarTypeStr {
uint8_t *value; uint8_t *value;
@ -46,9 +47,9 @@ typedef struct FlowVarTypeInt_ {
/** Generic Flowvar Structure */ /** Generic Flowvar Structure */
typedef struct FlowVar_ { typedef struct FlowVar_ {
uint8_t type; /* type, DETECT_FLOWVAR in this case */ uint16_t type; /* type, DETECT_FLOWVAR in this case */
uint8_t datatype; uint8_t datatype;
uint16_t keylen; FlowVarKeyLenType keylen;
uint32_t idx; /* name idx */ uint32_t idx; /* name idx */
GenericVar *next; /* right now just implement this as a list, GenericVar *next; /* right now just implement this as a list,
* in the long run we have think of something * in the long run we have think of something
@ -63,12 +64,13 @@ typedef struct FlowVar_ {
/** Flowvar Interface API */ /** Flowvar Interface API */
void FlowVarAddIdValue(Flow *, uint32_t id, uint8_t *value, uint16_t size); void FlowVarAddIdValue(Flow *, uint32_t id, uint8_t *value, uint16_t size);
void FlowVarAddKeyValue(Flow *f, uint8_t *key, uint16_t keysize, uint8_t *value, uint16_t size); void FlowVarAddKeyValue(
Flow *f, uint8_t *key, FlowVarKeyLenType keylen, uint8_t *value, uint16_t size);
void FlowVarAddIntNoLock(Flow *, uint32_t, uint32_t); void FlowVarAddIntNoLock(Flow *, uint32_t, uint32_t);
void FlowVarAddInt(Flow *, uint32_t, uint32_t); void FlowVarAddInt(Flow *, uint32_t, uint32_t);
FlowVar *FlowVarGet(Flow *, uint32_t); FlowVar *FlowVarGet(Flow *, uint32_t);
FlowVar *FlowVarGetByKey(Flow *f, const uint8_t *key, uint16_t keylen); FlowVar *FlowVarGetByKey(Flow *f, const uint8_t *key, FlowVarKeyLenType keylen);
void FlowVarFree(FlowVar *); void FlowVarFree(FlowVar *);
void FlowVarPrint(GenericVar *); void FlowVarPrint(GenericVar *);

@ -46,17 +46,16 @@ enum VarTypes {
VAR_TYPE_IPPAIR_VAR, VAR_TYPE_IPPAIR_VAR,
}; };
/** \todo see ticket #6855. The type field should be 16 bits. */
typedef struct GenericVar_ { typedef struct GenericVar_ {
uint8_t type; /**< variable type, uses detection sm_type */ uint16_t type; /**< variable type, uses detection sm_type */
uint8_t pad[3]; uint8_t pad[2];
uint32_t idx; uint32_t idx;
struct GenericVar_ *next; struct GenericVar_ *next;
} GenericVar; } GenericVar;
typedef struct XBit_ { typedef struct XBit_ {
uint8_t type; /* type, DETECT_XBITS in this case */ uint16_t type; /* type, DETECT_XBITS in this case */
uint8_t pad[3]; uint8_t pad[2];
uint32_t idx; /* name idx */ uint32_t idx; /* name idx */
GenericVar *next; GenericVar *next;
uint32_t expire; uint32_t expire;

Loading…
Cancel
Save