rtadvd(8): Fix a typo in full msg receive logic

Check against the size of the struct, not the pointer.  Previously, a message
with a cm_len between 9 and 23 (inclusive) could cause int msglen to underflow
and read(2) to be invoked with msglen size (implicitly cast to signed),
overrunning the caller-provided buffer.

All users of cm_recv() supply a stack buffer.

On the other hand, the rtadvd control socket appears to only be writable by the
owner, who is probably root.

While here, correct some types to be size_t or ssize_t.

Reported by:	Coverity
CID:		1008477
Security:	unix socket remotes may overflow stack in rtadvd
Sponsored by:	EMC / Isilon Storage Division
This commit is contained in:
Conrad Meyer 2016-05-12 03:37:17 +00:00
parent eacb70ba70
commit 96aec9a5e9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=299507

View File

@ -59,7 +59,7 @@
int int
cm_recv(int fd, char *buf) cm_recv(int fd, char *buf)
{ {
int n; ssize_t n;
struct ctrl_msg_hdr *cm; struct ctrl_msg_hdr *cm;
char *msg; char *msg;
struct pollfd pfds[1]; struct pollfd pfds[1];
@ -98,7 +98,7 @@ cm_recv(int fd, char *buf)
} }
} }
if (n != sizeof(*cm)) { if (n != (ssize_t)sizeof(*cm)) {
syslog(LOG_WARNING, syslog(LOG_WARNING,
"<%s> received a too small message.", __func__); "<%s> received a too small message.", __func__);
goto cm_recv_err; goto cm_recv_err;
@ -123,11 +123,11 @@ cm_recv(int fd, char *buf)
"<%s> ctrl msg received: type=%d", __func__, "<%s> ctrl msg received: type=%d", __func__,
cm->cm_type); cm->cm_type);
if (cm->cm_len > sizeof(cm)) { if (cm->cm_len > sizeof(*cm)) {
int msglen = cm->cm_len - sizeof(*cm); size_t msglen = cm->cm_len - sizeof(*cm);
syslog(LOG_DEBUG, syslog(LOG_DEBUG,
"<%s> ctrl msg has payload (len=%d)", __func__, "<%s> ctrl msg has payload (len=%zu)", __func__,
msglen); msglen);
for (;;) { for (;;) {
@ -153,7 +153,7 @@ cm_recv(int fd, char *buf)
} }
break; break;
} }
if (n != msglen) { if (n != (ssize_t)msglen) {
syslog(LOG_WARNING, syslog(LOG_WARNING,
"<%s> payload size mismatch.", __func__); "<%s> payload size mismatch.", __func__);
goto cm_recv_err; goto cm_recv_err;