mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-11-01 07:30:02 +00:00
refine the header length check
This commit is contained in:
+3
-3
@@ -569,7 +569,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
struct sockaddr_in *addr = (struct sockaddr_in *)&storage;
|
||||
size_t in_addr_len = sizeof(struct in_addr);
|
||||
addr->sin_family = AF_INET;
|
||||
if (r > in_addr_len) {
|
||||
if (r > in_addr_len + 3) {
|
||||
addr->sin_addr = *(struct in_addr *)(server->buf + offset);
|
||||
dns_ntop(AF_INET, (const void *)(server->buf + offset),
|
||||
host, INET_ADDRSTRLEN);
|
||||
@@ -589,7 +589,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
} else if ((atyp & ADDRTYPE_MASK) == 3) {
|
||||
// Domain name
|
||||
uint8_t name_len = *(uint8_t *)(server->buf + offset);
|
||||
if (name_len < r) {
|
||||
if (name_len + 4 < r) {
|
||||
memcpy(host, server->buf + offset + 1, name_len);
|
||||
offset += name_len + 1;
|
||||
} else {
|
||||
@@ -627,7 +627,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&storage;
|
||||
size_t in6_addr_len = sizeof(struct in6_addr);
|
||||
addr->sin6_family = AF_INET6;
|
||||
if (r > in6_addr_len) {
|
||||
if (r > in6_addr_len + 3) {
|
||||
addr->sin6_addr = *(struct in6_addr *)(server->buf + offset);
|
||||
dns_ntop(AF_INET6, (const void *)(server->buf + offset),
|
||||
host, INET6_ADDRSTRLEN);
|
||||
|
||||
+22
-20
@@ -229,7 +229,7 @@ static int parse_udprealy_header(const char * buf, const int buf_len,
|
||||
if ((atyp & ADDRTYPE_MASK) == 1) {
|
||||
// IP V4
|
||||
size_t in_addr_len = sizeof(struct in_addr);
|
||||
if (buf_len > in_addr_len) {
|
||||
if (buf_len > in_addr_len + 3) {
|
||||
if (storage != NULL) {
|
||||
struct sockaddr_in *addr = (struct sockaddr_in *)storage;
|
||||
addr->sin_family = AF_INET;
|
||||
@@ -245,32 +245,34 @@ static int parse_udprealy_header(const char * buf, const int buf_len,
|
||||
} else if ((atyp & ADDRTYPE_MASK) == 3) {
|
||||
// Domain name
|
||||
uint8_t name_len = *(uint8_t *)(buf + offset);
|
||||
if (name_len < buf_len && name_len < 255 && name_len > 0) {
|
||||
if (name_len + 4 < buf_len) {
|
||||
if (storage != NULL) {
|
||||
char tmp[256] = {0};
|
||||
struct cork_ip ip;
|
||||
memcpy(tmp, buf + offset + 1, name_len);
|
||||
if (cork_ip_init(&ip, tmp) != -1) {
|
||||
if (ip.version == 4) {
|
||||
struct sockaddr_in *addr = (struct sockaddr_in *)storage;
|
||||
dns_pton(AF_INET, tmp, &(addr->sin_addr));
|
||||
addr->sin_port = *(uint16_t *)(buf + offset + 1 + name_len);
|
||||
addr->sin_family = AF_INET;
|
||||
} else if (ip.version == 6) {
|
||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage;
|
||||
dns_pton(AF_INET, tmp, &(addr->sin6_addr));
|
||||
addr->sin6_port = *(uint16_t *)(buf + offset + 1 + name_len);
|
||||
addr->sin6_family = AF_INET6;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (host != NULL) {
|
||||
memcpy(host, buf + offset + 1, name_len);
|
||||
}
|
||||
offset += name_len + 1;
|
||||
}
|
||||
if (storage != NULL) {
|
||||
struct cork_ip ip;
|
||||
if (cork_ip_init(&ip, host) != -1) {
|
||||
if (ip.version == 4) {
|
||||
struct sockaddr_in *addr = (struct sockaddr_in *)storage;
|
||||
dns_pton(AF_INET, host, &(addr->sin_addr));
|
||||
addr->sin_port = *(uint16_t *)(buf + offset);
|
||||
addr->sin_family = AF_INET;
|
||||
} else if (ip.version == 6) {
|
||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage;
|
||||
dns_pton(AF_INET, host, &(addr->sin6_addr));
|
||||
addr->sin6_port = *(uint16_t *)(buf + offset);
|
||||
addr->sin6_family = AF_INET6;
|
||||
}
|
||||
}
|
||||
offset += 1 + name_len;
|
||||
}
|
||||
} else if ((atyp & ADDRTYPE_MASK) == 4) {
|
||||
// IP V6
|
||||
size_t in6_addr_len = sizeof(struct in6_addr);
|
||||
if (buf_len > in6_addr_len) {
|
||||
if (buf_len > in6_addr_len + 3) {
|
||||
if (storage != NULL) {
|
||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage;
|
||||
addr->sin6_family = AF_INET6;
|
||||
|
||||
Reference in New Issue
Block a user