Skip to content

Commit bd32a79

Browse files
authored
core: enforce bounds checks on input-derived lengths (#3888)
- transformations: account for base64 4/3 expansion in b64encode output length check - parser/parse_body: validate remaining buffer length before delimiter comparison in multipart boundary search - net/proto_tcp: validate Content-Length value before multiplication to prevent integer wraparound - sipmsgops: enforce header name length limit in sip_to_json conversion - msg_translator: validate total URI length in construct_uri before writing components
1 parent 6089db4 commit bd32a79

5 files changed

Lines changed: 34 additions & 3 deletions

File tree

modules/sipmsgops/sipmsgops.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,6 +2123,10 @@ static int w_sip_to_json(struct sip_msg *msg, pv_spec_t* out_json)
21232123
}
21242124

21252125
for (it=msg->headers;it;it=it->next) {
2126+
if (it->name.len >= sizeof(hdr_name_buf)) {
2127+
LM_WARN("header name too long (%d), skipping\n", it->name.len);
2128+
continue;
2129+
}
21262130
memcpy(hdr_name_buf,it->name.s,it->name.len);
21272131
hdr_name_buf[it->name.len] = 0;
21282132

msg_translator.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2906,6 +2906,7 @@ char *construct_uri(str *protocol,str *username,str *domain,str *port,
29062906
str *params,int *len)
29072907
{
29082908
int pos = 0;
2909+
int total_len;
29092910

29102911
if (!len)
29112912
{
@@ -2925,6 +2926,21 @@ char *construct_uri(str *protocol,str *username,str *domain,str *port,
29252926
return 0;
29262927
}
29272928

2929+
total_len = protocol->len + 1 /* ':' */ + domain->len;
2930+
if (username && username->s && username->len != 0)
2931+
total_len += username->len + 1; /* '@' */
2932+
if (port && port->s && port->len != 0)
2933+
total_len += port->len + 1; /* ':' */
2934+
if (params && params->s && params->len != 0)
2935+
total_len += params->len + 1; /* ';' */
2936+
total_len += 1; /* null terminator */
2937+
2938+
if (total_len > MAX_URI_LEN) {
2939+
LM_ERR("constructed URI too long (%d > %d)\n",
2940+
total_len, MAX_URI_LEN);
2941+
return 0;
2942+
}
2943+
29282944
memcpy(uri_buff,protocol->s,protocol->len);
29292945
pos += protocol->len;
29302946
uri_buff[pos++] = ':';

net/proto_tcp/tcp_common.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,14 @@ inline static void tcp_parse_headers(struct tcp_req *r,
294294
case '7':
295295
case '8':
296296
case '9':
297+
if (r->content_len>=TCP_BUF_SIZE) {
298+
LM_ERR("Content-Length value %d bigger than the "
299+
"reading buffer\n", r->content_len);
300+
r->error = TCP_REQ_BAD_LEN;
301+
r->state = H_SKIP;
302+
r->content_len = 0;
303+
break;
304+
}
297305
r->content_len=r->content_len*10+(*p-'0');
298306
if (r->content_len>=TCP_BUF_SIZE) {
299307
LM_ERR("Content-Length value %d bigger than the "

parser/parse_body.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ static char *find_line_delimiter(char* p, char* plimit, str delimiter)
130130
cp1 = l_memmem(cp, delimiterhead, plimit-cp, 2);
131131
if (cp1 == NULL)
132132
return NULL;
133+
/* ensure enough room for the delimiter match */
134+
if (plimit - cp1 < 2 + delimiter.len) {
135+
return NULL;
136+
}
133137
/* We matched '--',
134138
* now let's match the boundary delimiter */
135139
if (strncmp(cp1+2, delimiter.s, delimiter.len) == 0)
@@ -141,8 +145,6 @@ static char *find_line_delimiter(char* p, char* plimit, str delimiter)
141145
}
142146
if (cp1[-1] == '\n' || cp1[-1] == '\r')
143147
return cp1;
144-
if (plimit - cp1 < 2 + delimiter.len)
145-
return NULL;
146148
cp = cp1 + 2 + delimiter.len;
147149
}
148150
}

transformations.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,8 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
957957
val->flags |= PV_VAL_STR;
958958
break;
959959
}
960-
if(val->rs.len>TR_BUFFER_SIZE-1) {
960+
if(val->rs.len>TR_BUFFER_SIZE-1 ||
961+
calc_base64_encode_len(val->rs.len)>TR_BUFFER_SIZE) {
961962
LM_ERR("b64encode value larger than buffer\n");
962963
goto error;
963964
}

0 commit comments

Comments
 (0)