mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-27 15:54:22 +02:00
bounds checking for getrrsetbyname() replacement;
Spotted by Coverity in CID 405033; ok millert@
This commit is contained in:
parent
89b8df518f
commit
0fda9d704d
@ -390,6 +390,9 @@ parse_dns_response(const u_char *answer, int size)
|
|||||||
struct dns_response *resp;
|
struct dns_response *resp;
|
||||||
const u_char *cp;
|
const u_char *cp;
|
||||||
|
|
||||||
|
if (size < HFIXEDSZ)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
/* allocate memory for the response */
|
/* allocate memory for the response */
|
||||||
resp = calloc(1, sizeof(*resp));
|
resp = calloc(1, sizeof(*resp));
|
||||||
if (resp == NULL)
|
if (resp == NULL)
|
||||||
@ -456,14 +459,22 @@ parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count)
|
|||||||
int i, length;
|
int i, length;
|
||||||
char name[MAXDNAME];
|
char name[MAXDNAME];
|
||||||
|
|
||||||
for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
|
#define NEED(need) \
|
||||||
|
do { \
|
||||||
|
if (*cp + need > answer + size) \
|
||||||
|
goto fail; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* allocate and initialize struct */
|
for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
|
||||||
curr = calloc(1, sizeof(struct dns_query));
|
if (*cp >= answer + size) {
|
||||||
if (curr == NULL) {
|
fail:
|
||||||
free_dns_query(head);
|
free_dns_query(head);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
/* allocate and initialize struct */
|
||||||
|
curr = calloc(1, sizeof(struct dns_query));
|
||||||
|
if (curr == NULL)
|
||||||
|
goto fail;
|
||||||
if (head == NULL)
|
if (head == NULL)
|
||||||
head = curr;
|
head = curr;
|
||||||
if (prev != NULL)
|
if (prev != NULL)
|
||||||
@ -481,16 +492,20 @@ parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count)
|
|||||||
free_dns_query(head);
|
free_dns_query(head);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
NEED(length);
|
||||||
*cp += length;
|
*cp += length;
|
||||||
|
|
||||||
/* type */
|
/* type */
|
||||||
|
NEED(INT16SZ);
|
||||||
curr->type = _getshort(*cp);
|
curr->type = _getshort(*cp);
|
||||||
*cp += INT16SZ;
|
*cp += INT16SZ;
|
||||||
|
|
||||||
/* class */
|
/* class */
|
||||||
|
NEED(INT16SZ);
|
||||||
curr->class = _getshort(*cp);
|
curr->class = _getshort(*cp);
|
||||||
*cp += INT16SZ;
|
*cp += INT16SZ;
|
||||||
}
|
}
|
||||||
|
#undef NEED
|
||||||
|
|
||||||
return (head);
|
return (head);
|
||||||
}
|
}
|
||||||
@ -503,14 +518,23 @@ parse_dns_rrsection(const u_char *answer, int size, const u_char **cp,
|
|||||||
int i, length;
|
int i, length;
|
||||||
char name[MAXDNAME];
|
char name[MAXDNAME];
|
||||||
|
|
||||||
for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
|
#define NEED(need) \
|
||||||
|
do { \
|
||||||
|
if (*cp + need > answer + size) \
|
||||||
|
goto fail; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* allocate and initialize struct */
|
for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
|
||||||
curr = calloc(1, sizeof(struct dns_rr));
|
if (*cp >= answer + size) {
|
||||||
if (curr == NULL) {
|
fail:
|
||||||
free_dns_rr(head);
|
free_dns_rr(head);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* allocate and initialize struct */
|
||||||
|
curr = calloc(1, sizeof(struct dns_rr));
|
||||||
|
if (curr == NULL)
|
||||||
|
goto fail;
|
||||||
if (head == NULL)
|
if (head == NULL)
|
||||||
head = curr;
|
head = curr;
|
||||||
if (prev != NULL)
|
if (prev != NULL)
|
||||||
@ -528,25 +552,31 @@ parse_dns_rrsection(const u_char *answer, int size, const u_char **cp,
|
|||||||
free_dns_rr(head);
|
free_dns_rr(head);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
NEED(length);
|
||||||
*cp += length;
|
*cp += length;
|
||||||
|
|
||||||
/* type */
|
/* type */
|
||||||
|
NEED(INT16SZ);
|
||||||
curr->type = _getshort(*cp);
|
curr->type = _getshort(*cp);
|
||||||
*cp += INT16SZ;
|
*cp += INT16SZ;
|
||||||
|
|
||||||
/* class */
|
/* class */
|
||||||
|
NEED(INT16SZ);
|
||||||
curr->class = _getshort(*cp);
|
curr->class = _getshort(*cp);
|
||||||
*cp += INT16SZ;
|
*cp += INT16SZ;
|
||||||
|
|
||||||
/* ttl */
|
/* ttl */
|
||||||
|
NEED(INT32SZ);
|
||||||
curr->ttl = _getlong(*cp);
|
curr->ttl = _getlong(*cp);
|
||||||
*cp += INT32SZ;
|
*cp += INT32SZ;
|
||||||
|
|
||||||
/* rdata size */
|
/* rdata size */
|
||||||
|
NEED(INT16SZ);
|
||||||
curr->size = _getshort(*cp);
|
curr->size = _getshort(*cp);
|
||||||
*cp += INT16SZ;
|
*cp += INT16SZ;
|
||||||
|
|
||||||
/* rdata itself */
|
/* rdata itself */
|
||||||
|
NEED(curr->size);
|
||||||
curr->rdata = malloc(curr->size);
|
curr->rdata = malloc(curr->size);
|
||||||
if (curr->rdata == NULL) {
|
if (curr->rdata == NULL) {
|
||||||
free_dns_rr(head);
|
free_dns_rr(head);
|
||||||
@ -555,6 +585,7 @@ parse_dns_rrsection(const u_char *answer, int size, const u_char **cp,
|
|||||||
memcpy(curr->rdata, *cp, curr->size);
|
memcpy(curr->rdata, *cp, curr->size);
|
||||||
*cp += curr->size;
|
*cp += curr->size;
|
||||||
}
|
}
|
||||||
|
#undef NEED
|
||||||
|
|
||||||
return (head);
|
return (head);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user