Fail if a name or description string's length doesn't fit in 16 bits, if
the count of interfaces doesn't fit in 16 bits, or if the entire reply
length doesn't fit in 32 bits.
static int is_url(const char *source);
static int is_url(const char *source);
+/*
+ * Maximum sizes for fixed-bit-width values.
+ */
+#ifndef UINT16_MAX
+#define UINT16_MAX 65535U
+#endif
+
+#ifndef UINT32_MAX
+#define UINT32_MAX 4294967295U
+#endif
+
int
daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
int nullAuthAllowed, int uses_ssl)
int
daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
int nullAuthAllowed, int uses_ssl)
+/*
+ * Make sure that the reply length won't overflow 32 bits if we add the
+ * specified amount to it. If it won't, add that amount to it.
+ */
+#define CHECK_AND_INCREASE_REPLY_LEN(itemlen) \
+ if (replylen + (itemlen) < replylen) { \
+ pcap_strlcpy(errmsgbuf, "Reply length doesn't fit in 32 bits", \
+ sizeof (errmsgbuf)); \
+ goto error; \
+ } \
+ replylen += (uint32)itemlen;
+
static int
daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen)
{
static int
daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen)
{
- if (d->description)
- replylen += strlen(d->description);
- if (d->name)
- replylen += strlen(d->name);
+ if (d->description) {
+ size_t stringlen = strlen(d->description);
+ if (stringlen > UINT16_MAX) {
+ pcap_strlcpy(errmsgbuf,
+ "Description length doesn't fit in 16 bits",
+ sizeof (errmsgbuf));
+ goto error;
+ }
+ CHECK_AND_INCREASE_REPLY_LEN(stringlen);
+ }
+ if (d->name) {
+ size_t stringlen = strlen(d->name);
+ if (stringlen > UINT16_MAX) {
+ pcap_strlcpy(errmsgbuf,
+ "Name length doesn't fit in 16 bits",
+ sizeof (errmsgbuf));
+ goto error;
+ }
+ CHECK_AND_INCREASE_REPLY_LEN(stringlen);
+ }
- replylen += sizeof(struct rpcap_findalldevs_if);
+ CHECK_AND_INCREASE_REPLY_LEN(sizeof(struct rpcap_findalldevs_if));
for (address = d->addresses; address != NULL; address = address->next)
{
/*
for (address = d->addresses; address != NULL; address = address->next)
{
/*
#ifdef AF_INET6
case AF_INET6:
#endif
#ifdef AF_INET6
case AF_INET6:
#endif
- replylen += (sizeof(struct rpcap_sockaddr) * 4);
+ CHECK_AND_INCREASE_REPLY_LEN(sizeof(struct rpcap_sockaddr) * 4);
+ if (naddrs == UINT16_MAX) {
+ pcap_strlcpy(errmsgbuf,
+ "Number of interfaces doesn't fit in 16 bits",
+ sizeof (errmsgbuf));
+ goto error;
+ }
+ naddrs++;
- // RPCAP findalldevs command
+ // RPCAP findalldevs reply
if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf,
PCAP_ERRBUF_SIZE) == -1)
if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf,
PCAP_ERRBUF_SIZE) == -1)
memset(findalldevs_if, 0, sizeof(struct rpcap_findalldevs_if));
memset(findalldevs_if, 0, sizeof(struct rpcap_findalldevs_if));
- if (d->description) ldescr = (short) strlen(d->description);
- else ldescr = 0;
- if (d->name) lname = (short) strlen(d->name);
- else lname = 0;
+ /*
+ * We've already established that the string lengths
+ * fit in 16 bits.
+ */
+ if (d->description)
+ ldescr = (uint16) strlen(d->description);
+ else
+ ldescr = 0;
+ if (d->name)
+ lname = (uint16) strlen(d->name);
+ else
+ lname = 0;
findalldevs_if->desclen = htons(ldescr);
findalldevs_if->namelen = htons(lname);
findalldevs_if->desclen = htons(ldescr);
findalldevs_if->namelen = htons(lname);