CVE-2023-28098: Insufficient Information (NVD-CWE-noinfo)
value: OpenSIPS is a Session Initiation Protocol (SIP) server implementation. Prior to versions 3.1.7 and 3.2.4, a specially crafted Authorization header causes OpenSIPS to crash or behave in an unexpected way due to a bug in the function `parse_param_name()` . This issue was discovered while performing coverage guided fuzzing of the function parse_msg. The AddressSanitizer identified that the issue occurred in the function `q_memchr()` which is being called by the function `parse_param_name()`. This issue may cause erratic program behaviour or a server crash. It affects configurations containing
functions that make use of the affected code, such as the function `www_authorize()` . Versions 3.1.7 and 3.2.4 contain a fix.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 7.5
Published: 2023-03-15T23:15Z
Repository: https://github.com/OpenSIPS/opensips
Language: C
Files changed: parser/digest/param_parser.c
Commit date: 2021-10-27 14:20:34 +0300
Commit message: parse_param_name(): Improve param parsing macros

Issue discovered during OpenSIPS Security Audit 2021,
    by Alfred Farrugia & Sandro Gauci (Enable Security)

https://github.com/OpenSIPS/opensips/security/advisories/GHSA-jrqg-vppj-hr2h

Diff: diff --git a/parser/digest/param_parser.c b/parser/digest/param_parser.c
index 5b6ab29eb..cb913f6ea 100644
--- a/parser/digest/param_parser.c
+++ b/parser/digest/param_parser.c
@@ -70,10 +70,11 @@
  * (Sparc for example)
  */
 #define READ(val) \
 (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
 
+#define NEED(bytes) do { if (end - p < (bytes)) goto other; } while (0)
 
 #define name_CASE                      \
         switch(LOWER_DWORD(val)) {     \
         case _name_:                   \
 		*_type = PAR_USERNAME; \
@@ -81,32 +82,34 @@
 		goto end;              \
         }
 
 
 #define user_CASE         \
-        p += 4;           \
+        p += 4; NEED(4);  \
         val = READ(p);    \
         name_CASE;        \
         goto other;
 
 
 #define real_CASE                         \
-        p += 4;                           \
+        p += 4; NEED(1);                  \
         if (LOWER_BYTE(*p) == 'm') {      \
 		*_type = PAR_REALM;       \
                 p++;                      \
 		goto end;                 \
-	}
+	}                                 \
+        goto other;
 
 
 #define nonc_CASE                         \
-        p += 4;                           \
+        p += 4; NEED(1);                  \
         if (LOWER_BYTE(*p) == 'e') {      \
 	        *_type = PAR_NONCE;       \
                 p++;                      \
 		goto end;                 \
-	}
+	}                                 \
+        goto other;
 
 
 #define onse_CASE                      \
         switch(LOWER_DWORD(val)) {     \
         case _onse_:                   \
@@ -115,18 +118,18 @@
 		goto end;              \
         }
 
 
 #define resp_CASE         \
-        p += 4;           \
+        p += 4; NEED(4);  \
         val = READ(p);    \
         onse_CASE;        \
         goto other;
 
 
 #define cnon_CASE                                 \
-        p += 4;                                   \
+        p += 4; NEED(2);                          \
         if (LOWER_BYTE(*p) == 'c') {              \
 		p++;                              \
 		if (LOWER_BYTE(*p) == 'e') {      \
 			*_type = PAR_CNONCE;      \
                         p++;                      \
@@ -135,11 +138,11 @@
 	}                                         \
         goto other;
 
 
 #define opaq_CASE                                 \
-        p += 4;                                   \
+        p += 4; NEED(2);                          \
         if (LOWER_BYTE(*p) == 'u') {              \
 		p++;                              \
 		if (LOWER_BYTE(*p) == 'e') {      \
 			*_type = PAR_OPAQUE;      \
                         p++;                      \
@@ -161,11 +164,11 @@
 		goto other;                       \
 	}
 
 
 #define algo_CASE         \
-        p += 4;           \
+        p += 4; NEED(5);  \
         val = READ(p);    \
         rith_CASE;        \
         goto other
 
 

Vulnerable code:         p += 4;           \
        p += 4;                           \
	}
        p += 4;                           \
	}
        p += 4;           \
        p += 4;                                   \
        p += 4;                                   \
        p += 4;           \
Fixed code: #define NEED(bytes) do { if (end - p < (bytes)) goto other; } while (0)
        p += 4; NEED(4);  \
        p += 4; NEED(1);                  \
	}                                 \
        goto other;
        p += 4; NEED(1);                  \
	}                                 \
        goto other;
        p += 4; NEED(4);  \
        p += 4; NEED(2);                          \
        p += 4; NEED(2);                          \
        p += 4; NEED(5);  \