diff options
author | ngie <ngie@FreeBSD.org> | 2016-06-10 18:21:05 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2016-06-10 18:21:05 +0000 |
commit | 1041f31e3fc8f35a727bf61982eba21bff549f67 (patch) | |
tree | d325f13f020f3ebca5313b32f94e0bea83ec99c3 /usr.sbin/rtadvd | |
parent | 9d59ff877210410003acf82de0dd05a30dbf1fc4 (diff) | |
download | FreeBSD-src-1041f31e3fc8f35a727bf61982eba21bff549f67.zip FreeBSD-src-1041f31e3fc8f35a727bf61982eba21bff549f67.tar.gz |
MFC r299513,r299515:
r299513 (by cem):
rtadvd(8): Don't use-after-free
This whole block of code as committed fully formed in r224144. I'm not really
sure what the intent was, but it seems plausible that !persist ifis could need
other member cleanup. Don't free the object until after we've finished
cleaning its members.
CID: 1006079
r299515 (by cem):
rtadvd(8): Fix use-after-close in cm_handler_client
cm_send() closes 'fd' on error. In that case, bail out early without trying to
recv from or close 'fd' again.
CID: 1006078
Diffstat (limited to 'usr.sbin/rtadvd')
-rw-r--r-- | usr.sbin/rtadvd/config.c | 3 | ||||
-rw-r--r-- | usr.sbin/rtadvd/control_client.c | 4 |
2 files changed, 5 insertions, 2 deletions
diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c index b781ecc..8f5970f 100644 --- a/usr.sbin/rtadvd/config.c +++ b/usr.sbin/rtadvd/config.c @@ -229,7 +229,6 @@ rm_ifinfo(struct ifinfo *ifi) TAILQ_REMOVE(&ifilist, ifi, ifi_next); syslog(LOG_DEBUG, "<%s>: ifinfo (idx=%d) removed.", __func__, ifi->ifi_ifindex); - free(ifi); } else { /* recreate an empty entry */ update_persist_ifinfo(&ifilist, ifi->ifi_ifname); @@ -273,6 +272,8 @@ rm_ifinfo(struct ifinfo *ifi) } syslog(LOG_DEBUG, "<%s> leave (%s).", __func__, ifi->ifi_ifname); + if (!ifi->ifi_persist) + free(ifi); return (0); } diff --git a/usr.sbin/rtadvd/control_client.c b/usr.sbin/rtadvd/control_client.c index 33efe37..ca5cb68 100644 --- a/usr.sbin/rtadvd/control_client.c +++ b/usr.sbin/rtadvd/control_client.c @@ -92,9 +92,11 @@ cm_handler_client(int fd, int state, char *buf_orig) case CM_STATE_MSG_DISPATCH: cm->cm_version = CM_VERSION; error = cm_send(fd, buf); - if (error) + if (error) { syslog(LOG_WARNING, "<%s> cm_send()", __func__); + return (-1); + } state = CM_STATE_ACK_WAIT; break; case CM_STATE_ACK_WAIT: |