aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2024-01-11 04:51:53 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2024-01-11 04:51:53 +0000
commitd9b1f6fbf9935a9d54c78987a04af7cda3740c56 (patch)
treeb2f0e116432f0ce774190556d71a0dacc878771f
parentf75d7fac109bf8e322b07456c5361ee62f5635c2 (diff)
downloadsrc-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.c4
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;
}