diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2024-01-11 04:51:53 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2024-01-11 04:51:53 +0000 |
commit | d9b1f6fbf9935a9d54c78987a04af7cda3740c56 (patch) | |
tree | b2f0e116432f0ce774190556d71a0dacc878771f | |
parent | f75d7fac109bf8e322b07456c5361ee62f5635c2 (diff) | |
download | src-d9b1f6fbf9935a9d54c78987a04af7cda3740c56.tar.gz src-d9b1f6fbf9935a9d54c78987a04af7cda3740c56.zip |
netlink: fix bug with socket buffer character counter underflow
Cover case when an nb that we are now reading in full had been partially
read by previous read(2) and now has positive offset. Throw couple
assertions that helped to catch that earlier.
-rw-r--r-- | sys/netlink/netlink_domain.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/sys/netlink/netlink_domain.c b/sys/netlink/netlink_domain.c index 7ecafbf99d26..777aff43000a 100644 --- a/sys/netlink/netlink_domain.c +++ b/sys/netlink/netlink_domain.c @@ -744,6 +744,7 @@ nl_soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, offset = nb->offset; while (offset < nb->datalen) { hdr = (struct nlmsghdr *)&nb->data[offset]; + MPASS(nb->offset + hdr->nlmsg_len <= nb->datalen); if (uio->uio_resid < len + hdr->nlmsg_len) { overflow = len + hdr->nlmsg_len - uio->uio_resid; @@ -784,7 +785,7 @@ nl_soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, msgrcv++; } MPASS(offset == nb->datalen); - datalen += nb->datalen; + datalen += nb->datalen - nb->offset; } nospace: last = nb; @@ -796,6 +797,7 @@ nospace: TAILQ_FIRST(&sb->nl_queue) = last; last->tailq.tqe_prev = &TAILQ_FIRST(&sb->nl_queue); } + MPASS(sb->sb_acc >= datalen); sb->sb_acc -= datalen; sb->sb_ccc -= datalen; } |