diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2022-06-01 17:10:11 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2022-06-01 17:10:11 +0200 |
commit | c047b50638fd4bd9c5990ae0abf8195598c1929f (patch) | |
tree | 3731f96e7fa97aca7f38689492debfd547094cad /ospf6d | |
parent | Merge pull request #11326 from gromit1811/fix_init_stop_msgs2 (diff) | |
download | frr-c047b50638fd4bd9c5990ae0abf8195598c1929f.tar.xz frr-c047b50638fd4bd9c5990ae0abf8195598c1929f.zip |
ospf6d: fix rx/tx buffer sizes
OSPFv3 packets can be fragmented and up to 64k long, regardless of
interface MTU. Trying to size these buffers to MTU is just plain wrong.
To not make this a super intrusive change during the 8.3 release freeze,
just code this into ospf6_iobuf_size().
Since the buffer is now always 64k, don't waste time zeroing the entire
thing in receive; instead just zero kind of a "sled" of 128 bytes after
the buffer as a security precaution.
Fixes: #11298
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'ospf6d')
-rw-r--r-- | ospf6d/ospf6_message.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index ae7f16a9f..93a062b21 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1733,19 +1733,22 @@ static unsigned int iobuflen = 0; int ospf6_iobuf_size(unsigned int size) { - uint8_t *recvnew, *sendnew; + /* NB: there was previously code here that tried to dynamically size + * the buffer for whatever we see in MTU on interfaces. Which is + * _unconditionally wrong_ - we can always receive fragmented IPv6 + * up to the regular 64k length limit. (No jumbograms, thankfully.) + */ - if (size <= iobuflen) - return iobuflen; + if (!iobuflen) { + /* the + 128 is to have some runway at the end */ + size_t alloc_size = 65536 + 128; - recvnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size); - sendnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size); + assert(!recvbuf && !sendbuf); - XFREE(MTYPE_OSPF6_MESSAGE, recvbuf); - XFREE(MTYPE_OSPF6_MESSAGE, sendbuf); - recvbuf = recvnew; - sendbuf = sendnew; - iobuflen = size; + recvbuf = XMALLOC(MTYPE_OSPF6_MESSAGE, alloc_size); + sendbuf = XMALLOC(MTYPE_OSPF6_MESSAGE, alloc_size); + iobuflen = alloc_size; + } return iobuflen; } @@ -1779,7 +1782,6 @@ static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6) memset(&src, 0, sizeof(src)); memset(&dst, 0, sizeof(dst)); ifindex = 0; - memset(recvbuf, 0, iobuflen); iovector[0].iov_base = recvbuf; iovector[0].iov_len = iobuflen; iovector[1].iov_base = NULL; @@ -1795,6 +1797,9 @@ static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6) return OSPF6_READ_ERROR; } + /* ensure some zeroes past the end, just as a security precaution */ + memset(recvbuf + len, 0, MIN(128, iobuflen - len)); + oi = ospf6_interface_lookup_by_ifindex(ifindex, ospf6->vrf_id); if (oi == NULL || oi->area == NULL || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) { |