Browse code

tm: check end of header name in lw parser

- proper identification of header type, prior could mistakenly set the
type by matching the prefix of long header name
- GH #2572

(cherry picked from commit c0f5382bfbd2022896a9b206967977f827517700)

Daniel-Constantin Mierla authored on 03/12/2020 12:15:52 • Henning Westerholt committed on 21/12/2020 15:24:55
Showing 1 changed files
... ...
@@ -31,6 +31,16 @@
31 31
 #define READ(val) \
32 32
 	(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
33 33
 
34
+#define LW_HNAME_SET(_p, _end, _hnlen, _type, _htype) \
35
+	do { \
36
+		if(_end - _p > _hnlen) { \
37
+			if(_p[_hnlen] == ':' || _p[_hnlen] == ' ') { \
38
+				*_type = _htype; \
39
+				_p += _hnlen; \
40
+			} \
41
+		} \
42
+	} while(0)
43
+
34 44
 /*
35 45
  * lightweight header field name parser
36 46
  * used by build_local_reparse() function in order to construct ACK or CANCEL request
... ...
@@ -50,122 +60,111 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type)
50 60
 
51 61
 	p = begin;
52 62
 	val = LOWER_DWORD(READ(p));
63
+	*type = HDR_OTHER_T;
53 64
 
54 65
 	switch(val) {
55 66
 
56 67
 		case _cseq_: /* Cseq */
57
-			*type = HDR_CSEQ_T;
58
-			p += 4;
68
+			LW_HNAME_SET(p, end, 4, type, HDR_CSEQ_T);
59 69
 			break;
60 70
 
61 71
 		case _via1_: /* Via */
62 72
 		case _via2_:
63
-			*type = HDR_VIA_T;
64
-			p += 3;
73
+			LW_HNAME_SET(p, end, 3, type, HDR_VIA_T);
65 74
 			break;
66 75
 
67 76
 		case _from_: /* From */
68
-			*type = HDR_FROM_T;
69
-			p += 4;
77
+			LW_HNAME_SET(p, end, 4, type, HDR_FROM_T);
70 78
 			break;
71 79
 
72 80
 		case _to12_: /* To */
73
-			*type = HDR_TO_T;
74
-			p += 2;
81
+			LW_HNAME_SET(p, end, 2, type, HDR_TO_T);
75 82
 			break;
76 83
 
77 84
 		case _requ_: /* Require */
78
-			p += 4;
79
-			val = LOWER_DWORD(READ(p));
85
+			if(end - begin < 8) {
86
+				return begin;
87
+			}
88
+
89
+			val = LOWER_DWORD(READ(p + 4));
80 90
 
81 91
 			switch(val) {
82 92
 
83 93
 				case _ire1_:
84 94
 				case _ire2_:
85
-					p += 3;
86
-					*type = HDR_REQUIRE_T;
95
+					LW_HNAME_SET(p, end, 7, type, HDR_REQUIRE_T);
87 96
 					break;
88 97
 
89 98
 				default:
90
-					p -= 4;
91 99
 					*type = HDR_OTHER_T;
92 100
 					break;
93 101
 			}
94 102
 			break;
95 103
 
96 104
 		case _prox_: /* Proxy-Require */
105
+			if(end - begin < 14) {
106
+				return begin;
107
+			}
97 108
 
98 109
 			if((LOWER_DWORD(READ(p + 4)) == _y_re_)
99 110
 					&& (LOWER_DWORD(READ(p + 8)) == _quir_)
100 111
 					&& (LOWER_BYTE(*(p + 12)) == 'e')) {
101
-
102
-				p += 13;
103
-				*type = HDR_PROXYREQUIRE_T;
104
-				break;
105
-
106
-			} else {
107
-				*type = HDR_OTHER_T;
112
+				LW_HNAME_SET(p, end, 13, type, HDR_PROXYREQUIRE_T);
108 113
 				break;
109 114
 			}
115
+			break;
110 116
 
111 117
 		case _cont_: /* Content-Length */
118
+			if(end - begin < 15) {
119
+				return begin;
120
+			}
112 121
 
113 122
 			if((LOWER_DWORD(READ(p + 4)) == _ent__)
114 123
 					&& (LOWER_DWORD(READ(p + 8)) == _leng_)
115 124
 					&& (LOWER_BYTE(*(p + 12)) == 't')
116 125
 					&& (LOWER_BYTE(*(p + 13)) == 'h')) {
117
-
118
-				p += 14;
119
-				*type = HDR_CONTENTLENGTH_T;
120
-				break;
121
-			} else {
122
-				*type = HDR_OTHER_T;
126
+				LW_HNAME_SET(p, end, 14, type, HDR_CONTENTLENGTH_T);
123 127
 				break;
124 128
 			}
129
+			break;
125 130
 
126 131
 		case _call_: /* Call-Id */
132
+			if(end - begin < 8) {
133
+				return begin;
134
+			}
127 135
 
128
-			p += 4;
129
-			val = LOWER_DWORD(READ(p));
136
+			val = LOWER_DWORD(READ(p + 4));
130 137
 
131 138
 			switch(val) {
132
-
133 139
 				case __id1_:
134 140
 				case __id2_:
135
-					p += 3;
136
-					*type = HDR_CALLID_T;
137
-					break;
138
-
139
-				default:
140
-					p -= 4;
141
-					*type = HDR_OTHER_T;
141
+					LW_HNAME_SET(p, end, 7, type, HDR_CALLID_T);
142 142
 					break;
143 143
 			}
144 144
 			break;
145 145
 
146 146
 		case _rout_: /* Route */
147
+			if(end - begin < 6) {
148
+				return begin;
149
+			}
147 150
 
148 151
 			if(LOWER_BYTE(*(p + 4)) == 'e') {
149
-				p += 5;
150
-				*type = HDR_ROUTE_T;
151
-				break;
152
-			} else {
153
-				*type = HDR_OTHER_T;
152
+				LW_HNAME_SET(p, end, 5, type, HDR_ROUTE_T);
154 153
 				break;
155 154
 			}
155
+			break;
156 156
 
157 157
 		case _max__: /* Max-Forwards */
158
+			if(end - begin < 13) {
159
+				return begin;
160
+			}
158 161
 
159 162
 			if((LOWER_DWORD(READ(p + 4)) == _forw_)
160 163
 					&& (LOWER_DWORD(READ(p + 8)) == _ards_)) {
161
-
162
-				p += 12;
163
-				*type = HDR_MAXFORWARDS_T;
164
-				break;
165
-			} else {
166
-				*type = HDR_OTHER_T;
164
+				LW_HNAME_SET(p, end, 12, type, HDR_MAXFORWARDS_T);
167 165
 				break;
168 166
 			}
167
+			break;
169 168
 
170 169
 		default:
171 170
 			/* compact headers */
... ...
@@ -177,7 +176,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type)
177 176
 						*type = HDR_VIA_T;
178 177
 						break;
179 178
 					}
180
-					*type = HDR_OTHER_T;
181 179
 					break;
182 180
 
183 181
 				case 'f': /* From */
... ...
@@ -186,7 +184,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type)
186 184
 						*type = HDR_FROM_T;
187 185
 						break;
188 186
 					}
189
-					*type = HDR_OTHER_T;
190 187
 					break;
191 188
 
192 189
 				case 't': /* To */
... ...
@@ -200,7 +197,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type)
200 197
 						*type = HDR_TO_T;
201 198
 						break;
202 199
 					}
203
-					*type = HDR_OTHER_T;
204 200
 					break;
205 201
 
206 202
 				case 'l': /* Content-Length */
... ...
@@ -209,7 +205,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type)
209 205
 						*type = HDR_CONTENTLENGTH_T;
210 206
 						break;
211 207
 					}
212
-					*type = HDR_OTHER_T;
213 208
 					break;
214 209
 
215 210
 				case 'i': /* Call-Id */
... ...
@@ -218,11 +213,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type)
218 213
 						*type = HDR_CALLID_T;
219 214
 						break;
220 215
 					}
221
-					*type = HDR_OTHER_T;
222
-					break;
223
-
224
-				default:
225
-					*type = HDR_OTHER_T;
226 216
 					break;
227 217
 			}
228 218
 	}