the length before attempting to malloc() the buffer.
- Don't try to free the buffer we attempted to allocate if malloc()
fails.
- Correctly handle the case of recv() failing with EINTR.
- Correctly handle recv() returning 0.
getlong(lbuf, len);
len += 4;
+ if (len < 58 || len > 1000)
+ {
+ closesocket(conn);
+ return 0;
+ }
+
*buf = malloc(len);
- if (!*buf || len < 58)
+ if (!*buf)
{
closesocket(conn);
- free(*buf);
return 0;
}
putlong(*buf, len);
more = recv(conn, *buf + *nread, len - *nread, 0);
- if (more == -1 && errno != EINTR)
+ switch (more)
{
- closesocket(conn);
- free(*buf);
- return 0;
+ case 0:
+ /* If we read 0 bytes, the remote end has gone away. */
+ break;
+ case -1:
+ /* If errno is EINTR, return -1 and try again, otherwise we failed. */
+ if (errno == EINTR)
+ return -1;
+ else
+ {
+ closesocket(conn);
+ free(*buf);
+ return 0;
+ }
+ break;
+ default:
+ *nread += more;
+ if (*nread != len)
+ return -1;
+ break;
}
- *nread += more;
-
- if (*nread != len)
- return -1;
-
if (memcmp(*buf + 4, challenge + 4, 34))
{
closesocket(conn);