]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/iprep: allow 0 as a reputation value
authorVictor Julien <vjulien@oisf.net>
Thu, 25 Apr 2024 15:07:52 +0000 (17:07 +0200)
committerVictor Julien <vjulien@oisf.net>
Thu, 2 May 2024 09:00:05 +0000 (11:00 +0200)
Rules would allow checking against value 0, but internally the value
was used to indicate "no value". To address this, the internals now
return negative values for not found. This way value 0 can be fully
supported.

Bug: #6834.
(cherry picked from commit 64dc217f9f64b2e731757ce7bac40cf616e5166c)

src/detect-iprep.c
src/reputation.c
src/reputation.h

index 649ba24a2e28888c945d0be59e90423f90166a70..3d7ee1d5cd32a582d216f12055503d72d67d67a1 100644 (file)
@@ -75,65 +75,66 @@ void DetectIPRepRegister (void)
     sigmatch_table[DETECT_IPREP].flags |= SIGMATCH_IPONLY_COMPAT;
 }
 
-static inline uint8_t GetRep(const SReputation *r, const uint8_t cat, const uint32_t version)
+static inline int8_t GetRep(const SReputation *r, const uint8_t cat, const uint32_t version)
 {
     /* allow higher versions as this happens during
      * rule reload */
     if (r != NULL && r->version >= version) {
         return r->rep[cat];
     }
-    return 0;
+    return -1;
 }
 
-static uint8_t GetHostRepSrc(Packet *p, uint8_t cat, uint32_t version)
+/** \returns: -2 no host, -1 no rep entry, 0-127 rep values */
+static int8_t GetHostRepSrc(Packet *p, uint8_t cat, uint32_t version)
 {
     if (p->flags & PKT_HOST_SRC_LOOKED_UP && p->host_src == NULL) {
-        return 0;
+        return -2;
     } else if (p->host_src != NULL) {
         Host *h = (Host *)p->host_src;
         HostLock(h);
         /* use_cnt: 1 for having iprep, 1 for packet ref */
         DEBUG_VALIDATE_BUG_ON(h->iprep != NULL && SC_ATOMIC_GET(h->use_cnt) < 2);
-        uint8_t val = GetRep(h->iprep, cat, version);
+        int8_t val = GetRep(h->iprep, cat, version);
         HostUnlock(h);
         return val;
     } else {
         Host *h = HostLookupHostFromHash(&(p->src));
         p->flags |= PKT_HOST_SRC_LOOKED_UP;
         if (h == NULL)
-            return 0;
+            return -2;
         HostReference(&p->host_src, h);
         /* use_cnt: 1 for having iprep, 1 for HostLookupHostFromHash,
          * 1 for HostReference to packet */
         DEBUG_VALIDATE_BUG_ON(h->iprep != NULL && SC_ATOMIC_GET(h->use_cnt) < 3);
-        uint8_t val = GetRep(h->iprep, cat, version);
+        int8_t val = GetRep(h->iprep, cat, version);
         HostRelease(h); /* use_cnt >= 2: 1 for iprep, 1 for packet ref */
         return val;
     }
 }
 
-static uint8_t GetHostRepDst(Packet *p, uint8_t cat, uint32_t version)
+static int8_t GetHostRepDst(Packet *p, uint8_t cat, uint32_t version)
 {
     if (p->flags & PKT_HOST_DST_LOOKED_UP && p->host_dst == NULL) {
-        return 0;
+        return -2;
     } else if (p->host_dst != NULL) {
         Host *h = (Host *)p->host_dst;
         HostLock(h);
         /* use_cnt: 1 for having iprep, 1 for packet ref */
         DEBUG_VALIDATE_BUG_ON(h->iprep != NULL && SC_ATOMIC_GET(h->use_cnt) < 2);
-        uint8_t val = GetRep(h->iprep, cat, version);
+        int8_t val = GetRep(h->iprep, cat, version);
         HostUnlock(h);
         return val;
     } else {
         Host *h = HostLookupHostFromHash(&(p->dst));
         p->flags |= PKT_HOST_DST_LOOKED_UP;
         if (h == NULL)
-            return 0;
+            return -2;
         HostReference(&p->host_dst, h);
         /* use_cnt: 1 for having iprep, 1 for HostLookupHostFromHash,
          * 1 for HostReference to packet */
         DEBUG_VALIDATE_BUG_ON(h->iprep != NULL && SC_ATOMIC_GET(h->use_cnt) < 3);
-        uint8_t val = GetRep(h->iprep, cat, version);
+        int8_t val = GetRep(h->iprep, cat, version);
         HostRelease(h); /* use_cnt >= 2: 1 for iprep, 1 for packet ref */
         return val;
     }
@@ -152,58 +153,58 @@ static int DetectIPRepMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
         return 0;
 
     uint32_t version = det_ctx->de_ctx->srep_version;
-    uint8_t val = 0;
+    int8_t val = 0;
 
     SCLogDebug("rd->cmd %u", rd->cmd);
     switch (rd->cmd) {
         case IPRepCmdAny:
             val = GetHostRepSrc(p, rd->cat, version);
-            if (val == 0)
+            if (val < 0)
                 val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
-            if (val > 0) {
-                if (DetectU8Match(val, &rd->du8))
+            if (val >= 0) {
+                if (DetectU8Match((uint8_t)val, &rd->du8))
                     return 1;
             }
             val = GetHostRepDst(p, rd->cat, version);
-            if (val == 0)
+            if (val < 0)
                 val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
-            if (val > 0) {
-                return DetectU8Match(val, &rd->du8);
+            if (val >= 0) {
+                return DetectU8Match((uint8_t)val, &rd->du8);
             }
             break;
 
         case IPRepCmdSrc:
             val = GetHostRepSrc(p, rd->cat, version);
-            SCLogDebug("checking src -- val %u (looking for cat %u, val %u)", val, rd->cat,
+            SCLogDebug("checking src -- val %d (looking for cat %u, val %u)", val, rd->cat,
                     rd->du8.arg1);
-            if (val == 0)
+            if (val < 0)
                 val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
-            if (val > 0) {
-                return DetectU8Match(val, &rd->du8);
+            if (val >= 0) {
+                return DetectU8Match((uint8_t)val, &rd->du8);
             }
             break;
 
         case IPRepCmdDst:
             SCLogDebug("checking dst");
             val = GetHostRepDst(p, rd->cat, version);
-            if (val == 0)
+            if (val < 0)
                 val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
-            if (val > 0) {
-                return DetectU8Match(val, &rd->du8);
+            if (val >= 0) {
+                return DetectU8Match((uint8_t)val, &rd->du8);
             }
             break;
 
         case IPRepCmdBoth:
             val = GetHostRepSrc(p, rd->cat, version);
-            if (val == 0)
+            if (val < 0)
                 val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
-            if (val == 0 || DetectU8Match(val, &rd->du8) == 0)
+            if (val < 0 || DetectU8Match((uint8_t)val, &rd->du8) == 0)
                 return 0;
             val = GetHostRepDst(p, rd->cat, version);
-            if (val == 0)
+            if (val < 0)
                 val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
-            if (val > 0) {
-                return DetectU8Match(val, &rd->du8);
+            if (val >= 0) {
+                return DetectU8Match((uint8_t)val, &rd->du8);
             }
             break;
     }
index 75f3ba0c3fa41209c0a86bcece70edce9b881cb0..cd517464904beb71ab63a0a803bfbdb366338f26 100644 (file)
@@ -124,31 +124,31 @@ static void SRepCIDRAddNetblock(SRepCIDRTree *cidr_ctx, char *ip, int cat, uint8
     }
 }
 
-static uint8_t SRepCIDRGetIPv4IPRep(SRepCIDRTree *cidr_ctx, uint8_t *ipv4_addr, uint8_t cat)
+static int8_t SRepCIDRGetIPv4IPRep(SRepCIDRTree *cidr_ctx, uint8_t *ipv4_addr, uint8_t cat)
 {
     void *user_data = NULL;
     (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, cidr_ctx->srepIPV4_tree[cat], &user_data);
     if (user_data == NULL)
-        return 0;
+        return -1;
 
     SReputation *r = (SReputation *)user_data;
     return r->rep[cat];
 }
 
-static uint8_t SRepCIDRGetIPv6IPRep(SRepCIDRTree *cidr_ctx, uint8_t *ipv6_addr, uint8_t cat)
+static int8_t SRepCIDRGetIPv6IPRep(SRepCIDRTree *cidr_ctx, uint8_t *ipv6_addr, uint8_t cat)
 {
     void *user_data = NULL;
     (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, cidr_ctx->srepIPV6_tree[cat], &user_data);
     if (user_data == NULL)
-        return 0;
+        return -1;
 
     SReputation *r = (SReputation *)user_data;
     return r->rep[cat];
 }
 
-uint8_t SRepCIDRGetIPRepSrc(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version)
+int8_t SRepCIDRGetIPRepSrc(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version)
 {
-    uint8_t rep = 0;
+    int8_t rep = -3;
 
     if (PKT_IS_IPV4(p))
         rep = SRepCIDRGetIPv4IPRep(cidr_ctx, (uint8_t *)GET_IPV4_SRC_ADDR_PTR(p), cat);
@@ -158,9 +158,9 @@ uint8_t SRepCIDRGetIPRepSrc(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint
     return rep;
 }
 
-uint8_t SRepCIDRGetIPRepDst(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version)
+int8_t SRepCIDRGetIPRepDst(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version)
 {
-    uint8_t rep = 0;
+    int8_t rep = -3;
 
     if (PKT_IS_IPV4(p))
         rep = SRepCIDRGetIPv4IPRep(cidr_ctx, (uint8_t *)GET_IPV4_DST_ADDR_PTR(p), cat);
index 3ed94d9851596aca8c8b68cda6d02efd7c3fc6b9..9f14adee65ee0f7ccba9aab3cace41a76c866de2 100644 (file)
@@ -49,8 +49,8 @@ void SRepDestroy(struct DetectEngineCtx_ *de_ctx);
 void SRepReloadComplete(void);
 int SRepHostTimedOut(Host *);
 
-uint8_t SRepCIDRGetIPRepSrc(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version);
-uint8_t SRepCIDRGetIPRepDst(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version);
+int8_t SRepCIDRGetIPRepSrc(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version);
+int8_t SRepCIDRGetIPRepDst(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version);
 void SRepResetVersion(void);
 int SRepLoadCatFileFromFD(FILE *fp);
 int SRepLoadFileFromFD(SRepCIDRTree *cidr_ctx, FILE *fp);