Skip to content

Commit 1cb55f0

Browse files
Merge pull request #29 from kosmas-valianos/moreMisc
Miscellaneous fixes
2 parents c9e55a3 + 27de2d4 commit 1cb55f0

3 files changed

Lines changed: 249 additions & 35 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
#
1818

19-
CFLAGS := -Wall -Wextra -Wshadow -Wimplicit-fallthrough=0 -ansi -fshort-enums -fpic
19+
CFLAGS := -Wall -Wextra -Wshadow -ansi -fshort-enums -fpic
2020

2121
all: build tests example
2222

src/proxy_protocol.c

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ static uint8_t parse_port(const char *value, uint16_t *usport)
217217
{
218218
char *endptr = NULL;
219219
uint64_t port = strtoul(value, &endptr, 10);
220-
if (endptr == value || port > UINT16_MAX)
220+
if (endptr == value || *endptr != '\0' || *value == '+' || port > UINT16_MAX)
221221
{
222222
return 0;
223223
}
@@ -286,7 +286,12 @@ static uint8_t tlv_array_append_tlv_new(tlv_array_t *tlv_array, uint8_t type, ui
286286

287287
static uint8_t tlv_array_append_tlv_new_usascii(tlv_array_t *tlv_array, uint8_t type, uint16_t length, const void *value)
288288
{
289-
pp2_tlv_t *tlv = tlv_new(type, length + 1, value);
289+
pp2_tlv_t *tlv;
290+
if (length == UINT16_MAX)
291+
{
292+
return 0;
293+
}
294+
tlv = tlv_new(type, length + 1, value);
290295
if (!tlv)
291296
{
292297
return 0;
@@ -409,20 +414,42 @@ uint8_t pp_info_add_ssl(pp_info_t *pp_info, const char *version, const char *cip
409414

410415
uint8_t pp_info_add_netns(pp_info_t *pp_info, const char *netns)
411416
{
412-
return tlv_array_append_tlv_new(&pp_info->pp2_info.tlv_array, PP2_TYPE_NETNS, (uint16_t) strlen(netns), netns);
417+
size_t netns_len;
418+
if (!netns)
419+
{
420+
return 0;
421+
}
422+
netns_len = strlen(netns);
423+
if (netns_len > UINT16_MAX)
424+
{
425+
return 0;
426+
}
427+
return tlv_array_append_tlv_new(&pp_info->pp2_info.tlv_array, PP2_TYPE_NETNS, (uint16_t) netns_len, netns);
413428
}
414429

415430
uint8_t pp_info_add_aws_vpce_id(pp_info_t *pp_info, const char *vpce_id)
416431
{
417-
uint16_t length = sizeof_pp2_tlv_aws_t + (uint16_t) strlen(vpce_id);
418-
pp2_tlv_aws_t *pp2_tlv_aws = malloc(length);
432+
size_t vpce_id_len;
433+
uint16_t length;
434+
pp2_tlv_aws_t *pp2_tlv_aws;
419435
uint8_t rc;
436+
if (!vpce_id)
437+
{
438+
return 0;
439+
}
440+
vpce_id_len = strlen(vpce_id);
441+
if (vpce_id_len > UINT16_MAX - sizeof_pp2_tlv_aws_t)
442+
{
443+
return 0;
444+
}
445+
length = (uint16_t)(sizeof_pp2_tlv_aws_t + vpce_id_len);
446+
pp2_tlv_aws = malloc(length);
420447
if (!pp2_tlv_aws)
421448
{
422449
return 0;
423450
}
424451
pp2_tlv_aws->type = PP2_SUBTYPE_AWS_VPCE_ID;
425-
memcpy(pp2_tlv_aws->value, vpce_id, strlen(vpce_id));
452+
memcpy(pp2_tlv_aws->value, vpce_id, vpce_id_len);
426453
rc = tlv_array_append_tlv_new(&pp_info->pp2_info.tlv_array, PP2_TYPE_AWS, length, pp2_tlv_aws);
427454
free(pp2_tlv_aws);
428455
return rc;
@@ -674,7 +701,8 @@ static uint32_t crc32c(const uint8_t* buf, uint32_t len)
674701
static uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len, int32_t *error)
675702
{
676703
proxy_hdr_v2_t proxy_hdr_v2 = { PP2_SIG, '\x21', 0, 0 };
677-
uint16_t proxy_addr_len, len, padding_bytes, index;
704+
uint16_t proxy_addr_len, padding_bytes, index;
705+
uint32_t len;
678706
proxy_addr_t proxy_addr;
679707
const tlv_array_t *tlv_array;
680708
uint32_t i;
@@ -755,7 +783,12 @@ static uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len,
755783
{
756784
len += sizeof_pp2_tlv_t + sizeof(uint32_t);
757785
}
758-
*pp2_hdr_len = sizeof(proxy_hdr_v2_t) + len;
786+
if (sizeof(proxy_hdr_v2_t) + len > UINT16_MAX)
787+
{
788+
*error = -ERR_PP2_LENGTH;
789+
return NULL;
790+
}
791+
*pp2_hdr_len = (uint16_t)(sizeof(proxy_hdr_v2_t) + len);
759792
if (pp_info->pp2_info.alignment_power > 1)
760793
{
761794
uint16_t alignment = 1 << pp_info->pp2_info.alignment_power;
@@ -767,13 +800,13 @@ static uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len,
767800
{
768801
pp2_hdr_len_padded += alignment;
769802
}
770-
padding_bytes = pp2_hdr_len_padded - sizeof(proxy_hdr_v2_t) - len - sizeof_pp2_tlv_t;
803+
padding_bytes = pp2_hdr_len_padded - (uint16_t)sizeof(proxy_hdr_v2_t) - (uint16_t)len - sizeof_pp2_tlv_t;
771804

772805
*pp2_hdr_len = pp2_hdr_len_padded;
773-
len = pp2_hdr_len_padded - sizeof(proxy_hdr_v2_t);
806+
len = pp2_hdr_len_padded - (uint32_t)sizeof(proxy_hdr_v2_t);
774807
}
775808
}
776-
proxy_hdr_v2.len = htons(len);
809+
proxy_hdr_v2.len = htons((uint16_t)len);
777810

778811
/* Create the PROXY protocol header */
779812
pp2_hdr = malloc(*pp2_hdr_len);
@@ -795,7 +828,7 @@ static uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len,
795828
memcpy(pp2_hdr + index, tlv_array->tlvs[i], tlv_len);
796829
index += tlv_len;
797830
}
798-
if (pp_info->pp2_info.alignment_power > 1)
831+
if (pp_info->pp2_info.alignment_power > 1 && padding_bytes > 0)
799832
{
800833
pp2_tlv_t tlv = { 0 };
801834
tlv.type = PP2_TYPE_NOOP;
@@ -884,7 +917,7 @@ static uint8_t *pp1_create_hdr(const pp_info_t *pp_info, uint16_t *pp1_hdr_len,
884917
}
885918
memcpy(src_addr, pp_info->src_addr, sizeof(src_addr));
886919
memcpy(dst_addr, pp_info->dst_addr, sizeof(dst_addr));
887-
*pp1_hdr_len = _sprintf(block, "PROXY %s %s %s %hu %hu"CRLF, fam, src_addr, dst_addr, pp_info->src_port, pp_info->dst_port);
920+
*pp1_hdr_len = (uint16_t)_sprintf(block, "PROXY %s %s %s %hu %hu"CRLF, fam, src_addr, dst_addr, pp_info->src_port, pp_info->dst_port);
888921
}
889922
else
890923
{
@@ -1055,12 +1088,12 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
10551088
}
10561089

10571090
/* TLVs */
1058-
/* Any TLV vector must be at least 3 bytes */
1059-
while (tlv_vectors_len > sizeof_pp2_tlv_t)
1091+
/* Any TLV vector must be at least 3 bytes (sizeof_pp2_tlv_t) */
1092+
while (tlv_vectors_len >= sizeof_pp2_tlv_t)
10601093
{
10611094
const pp2_tlv_t *pp2_tlv = (const pp2_tlv_t*) buffer;
10621095
uint16_t pp2_tlv_len = pp2_tlv->length_hi << 8 | pp2_tlv->length_lo;
1063-
uint16_t pp2_tlv_offset = sizeof_pp2_tlv_t + pp2_tlv_len;
1096+
uint32_t pp2_tlv_offset = (uint32_t) sizeof_pp2_tlv_t + pp2_tlv_len;
10641097
if (pp2_tlv_offset > tlv_vectors_len)
10651098
{
10661099
return -ERR_PP2_TLV_LENGTH;
@@ -1094,7 +1127,7 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
10941127
* Instead of zeroing the field in the buffer, compute CRC in 3 segments:
10951128
* before the checksum value, 4 zero bytes, after the checksum value. */
10961129
total_hdr_len = sizeof(proxy_hdr_v2_t) + len;
1097-
offset_to_chksum_value = (const uint8_t*)pp2_tlv->value - pp2_hdr;
1130+
offset_to_chksum_value = (uint32_t)((const uint8_t*)pp2_tlv->value - pp2_hdr);
10981131
after_chksum_offset = offset_to_chksum_value + sizeof(uint32_t);
10991132

11001133
crc = crc32c_continue(0xffffffff, pp2_hdr, offset_to_chksum_value);
@@ -1129,25 +1162,39 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
11291162
break;
11301163
case PP2_TYPE_SSL:
11311164
{
1132-
const pp2_tlv_ssl_t *pp2_tlv_ssl = (const pp2_tlv_ssl_t*) pp2_tlv->value;
1165+
const pp2_tlv_ssl_t *pp2_tlv_ssl;
11331166
uint16_t pp2_tlvs_ssl_len = 0, pp2_sub_tlv_offset = 0;
11341167
uint8_t tlv_ssl_version_found = 0;
11351168

1169+
if (pp2_tlv_len < sizeof(((pp2_tlv_ssl_t*)0)->client) + sizeof(((pp2_tlv_ssl_t*)0)->verify))
1170+
{
1171+
return -ERR_PP2_TYPE_SSL;
1172+
}
1173+
1174+
pp2_tlv_ssl = (const pp2_tlv_ssl_t*) pp2_tlv->value;
1175+
11361176
/* Set the pp2_ssl_info */
11371177
pp_info->pp2_info.pp2_ssl_info.ssl = !!(pp2_tlv_ssl->client & PP2_CLIENT_SSL);
11381178
pp_info->pp2_info.pp2_ssl_info.cert_in_connection = !!(pp2_tlv_ssl->client & PP2_CLIENT_CERT_CONN);
11391179
pp_info->pp2_info.pp2_ssl_info.cert_in_session = !!(pp2_tlv_ssl->client & PP2_CLIENT_CERT_SESS);
11401180
pp_info->pp2_info.pp2_ssl_info.cert_verified = !pp2_tlv_ssl->verify;
11411181

11421182
pp2_tlvs_ssl_len = pp2_tlv_len - sizeof(pp2_tlv_ssl->client) - sizeof(pp2_tlv_ssl->verify);
1143-
while (pp2_sub_tlv_offset < pp2_tlvs_ssl_len)
1183+
while (pp2_sub_tlv_offset + sizeof_pp2_tlv_t <= pp2_tlvs_ssl_len)
11441184
{
11451185
const pp2_tlv_t *pp2_sub_tlv_ssl = (const pp2_tlv_t*) ((const uint8_t*) pp2_tlv_ssl->sub_tlv + pp2_sub_tlv_offset);
11461186
uint16_t pp2_sub_tlv_ssl_len = pp2_sub_tlv_ssl->length_hi << 8 | pp2_sub_tlv_ssl->length_lo;
1187+
if ((uint32_t) sizeof_pp2_tlv_t + pp2_sub_tlv_ssl_len > (uint32_t)(pp2_tlvs_ssl_len - pp2_sub_tlv_offset))
1188+
{
1189+
return -ERR_PP2_TYPE_SSL;
1190+
}
1191+
if (pp2_sub_tlv_ssl->type == PP2_SUBTYPE_SSL_VERSION)
1192+
{
1193+
tlv_ssl_version_found = 1;
1194+
}
11471195
switch (pp2_sub_tlv_ssl->type)
11481196
{
11491197
case PP2_SUBTYPE_SSL_VERSION: /* US-ASCII */
1150-
tlv_ssl_version_found = 1;
11511198
case PP2_SUBTYPE_SSL_CIPHER: /* US-ASCII */
11521199
case PP2_SUBTYPE_SSL_SIG_ALG: /* US-ASCII */
11531200
case PP2_SUBTYPE_SSL_KEY_ALG: /* US-ASCII */
@@ -1171,7 +1218,7 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
11711218

11721219
pp2_sub_tlv_offset += sizeof_pp2_tlv_t + pp2_sub_tlv_ssl_len;
11731220
}
1174-
if (pp2_sub_tlv_offset > pp2_tlvs_ssl_len || (pp_info->pp2_info.pp2_ssl_info.ssl && !tlv_ssl_version_found))
1221+
if (pp2_sub_tlv_offset != pp2_tlvs_ssl_len || (pp_info->pp2_info.pp2_ssl_info.ssl && !tlv_ssl_version_found))
11751222
{
11761223
return -ERR_PP2_TYPE_SSL;
11771224
}
@@ -1213,8 +1260,7 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
12131260
/* Connection is done through Private Link service */
12141261
if (pp2_tlv_azure->type == PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID) /* 32-bit number */
12151262
{
1216-
pp2_tlv_t *tlv = tlv_new(pp2_tlv->type, pp2_tlv_len, pp2_tlv->value);
1217-
if (!tlv || !tlv_array_append_tlv(&pp_info->pp2_info.tlv_array, tlv))
1263+
if (!tlv_array_append_tlv_new(&pp_info->pp2_info.tlv_array, pp2_tlv->type, pp2_tlv_len, pp2_tlv->value))
12181264
{
12191265
return -ERR_HEAP_ALLOC;
12201266
}
@@ -1248,15 +1294,15 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
12481294
char src_port_str[6] = { 0 };
12491295
char dst_port_str[6] = { 0 };
12501296

1251-
memcpy(block, buffer, buffer_length < PP1_MAX_LENGTH ? buffer_length : PP1_MAX_LENGTH);
1297+
memcpy(block, buffer, buffer_length < PP1_MAX_LENGTH - 1 ? buffer_length : PP1_MAX_LENGTH - 1);
12521298

12531299
block_end = strstr(block, CRLF);
12541300
if (!block_end)
12551301
{
12561302
return -ERR_PP1_CRLF;
12571303
}
12581304
block_end += strlen(CRLF);
1259-
pp1_hdr_len = block_end - block;
1305+
pp1_hdr_len = (int32_t)(block_end - block);
12601306

12611307
/* PROXY */
12621308
if (memcmp(block, "PROXY", 5))
@@ -1277,7 +1323,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
12771323
if (!inet_family)
12781324
{
12791325
/* Unknown connection (short form) */
1280-
if (pp1_hdr_len == 15 || !memcmp(ptr, "UNKNOWN", 7))
1326+
if (pp1_hdr_len == 15 && !memcmp(ptr, "UNKNOWN", 7))
12811327
{
12821328
pp_info->address_family = ADDR_FAMILY_UNSPEC;
12831329
pp_info->transport_protocol = TRANSPORT_PROTOCOL_UNSPEC;
@@ -1324,7 +1370,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13241370
{
13251371
return sa_family == AF_INET ? -ERR_PP1_IPV4_SRC_IP : -ERR_PP1_IPV6_SRC_IP;
13261372
}
1327-
src_address_length = src_address_end - ptr;
1373+
src_address_length = (uint16_t)(src_address_end - ptr);
13281374
memcpy(pp_info->src_addr, ptr, src_address_length);
13291375
if (inet_pton(sa_family, pp_info->src_addr, &src_sin_addr) != 1)
13301376
{
@@ -1345,7 +1391,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13451391
{
13461392
return sa_family == AF_INET ? -ERR_PP1_IPV4_DST_IP : -ERR_PP1_IPV6_DST_IP;
13471393
}
1348-
dst_address_length = dst_address_end - ptr;
1394+
dst_address_length = (uint16_t)(dst_address_end - ptr);
13491395
memcpy(pp_info->dst_addr, ptr, dst_address_length);
13501396
if (inet_pton(sa_family, pp_info->dst_addr, &dst_sin_addr) != 1)
13511397
{
@@ -1366,7 +1412,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13661412
{
13671413
return -ERR_PP1_SRC_PORT;
13681414
}
1369-
src_port_length = src_port_end - ptr;
1415+
src_port_length = (uint16_t)(src_port_end - ptr);
13701416
if (src_port_length == 0 || src_port_length > 5)
13711417
{
13721418
return -ERR_PP1_SRC_PORT;
@@ -1391,7 +1437,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13911437
{
13921438
return -ERR_PP1_DST_PORT;
13931439
}
1394-
dst_port_length = dst_port_end - ptr;
1440+
dst_port_length = (uint16_t)(dst_port_end - ptr);
13951441
if (dst_port_length == 0 || dst_port_length > 5)
13961442
{
13971443
return -ERR_PP1_DST_PORT;

0 commit comments

Comments
 (0)