Check for message truncation in RADIUS client
The RADIUS client currently determines if a radius message is longer than the supported maximum length by checking whether the size of the received buffer and the length of the buffer (as returned by recv()) is equal. This method fails to detect if the buffer has actually been truncated. This change modifies the RADIUS client to instead use the recvmsg() call and then check the message header flags to determine whether or not the received message has been truncated and drop the message if that is the case. Signed-off-by: Anusha Datar <anusha@meter.com> Reviewed-by: Steve deRosier <derosier@cal-sierra.com> Reviewed-by: Julian Squires <julian@cipht.net>
This commit is contained in:
parent
5cb25307e4
commit
8f248d1aca
1 changed files with 13 additions and 4 deletions
|
@ -816,7 +816,9 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx)
|
||||||
struct hostapd_radius_servers *conf = radius->conf;
|
struct hostapd_radius_servers *conf = radius->conf;
|
||||||
RadiusType msg_type = (RadiusType) sock_ctx;
|
RadiusType msg_type = (RadiusType) sock_ctx;
|
||||||
int len, roundtrip;
|
int len, roundtrip;
|
||||||
unsigned char buf[RADIUS_MAX_MSG_LEN + 1];
|
unsigned char buf[RADIUS_MAX_MSG_LEN];
|
||||||
|
struct msghdr msghdr = {0};
|
||||||
|
struct iovec iov;
|
||||||
struct radius_msg *msg;
|
struct radius_msg *msg;
|
||||||
struct radius_hdr *hdr;
|
struct radius_hdr *hdr;
|
||||||
struct radius_rx_handler *handlers;
|
struct radius_rx_handler *handlers;
|
||||||
|
@ -836,15 +838,22 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx)
|
||||||
rconf = conf->auth_server;
|
rconf = conf->auth_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = recv(sock, buf, sizeof(buf), MSG_DONTWAIT);
|
iov.iov_base = buf;
|
||||||
|
iov.iov_len = RADIUS_MAX_MSG_LEN;
|
||||||
|
msghdr.msg_iov = &iov;
|
||||||
|
msghdr.msg_iovlen = 1;
|
||||||
|
msghdr.msg_flags = 0;
|
||||||
|
len = recvmsg(sock, &msghdr, MSG_DONTWAIT);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
wpa_printf(MSG_INFO, "recv[RADIUS]: %s", strerror(errno));
|
wpa_printf(MSG_INFO, "recvmsg[RADIUS]: %s", strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
|
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
|
||||||
HOSTAPD_LEVEL_DEBUG, "Received %d bytes from RADIUS "
|
HOSTAPD_LEVEL_DEBUG, "Received %d bytes from RADIUS "
|
||||||
"server", len);
|
"server", len);
|
||||||
if (len == sizeof(buf)) {
|
|
||||||
|
if (msghdr.msg_flags & MSG_TRUNC) {
|
||||||
wpa_printf(MSG_INFO, "RADIUS: Possibly too long UDP frame for our buffer - dropping it");
|
wpa_printf(MSG_INFO, "RADIUS: Possibly too long UDP frame for our buffer - dropping it");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue