[PATCH] Fixed crash when requesting a BFD session on an unnumbered interface
Miao Wang
shankerwangmiao at gmail.com
Thu Mar 30 00:02:38 CEST 2023
Hi,
The bug can be reproduced with the following steps:
1. create an unnumbered interface:
# ip link add dummy0 type dummy
# ip link set dummy0 up
# ip neigh replace 169.254.0.1 lladdr <some:mac:add:ress> dev dummy0
2. Create a static route via this interface and request a bfd session
protocol device {
}
ipv4 table main4;
protocol bfd bfd1 {
strict bind;
accept direct;
}
protocol static {
ipv4{
table main4;
export all;
};
route 1.2.3.4/32 via 169.254.0.1%dummy0 onlink bfd;
}
The crash happens when dereferencing nb->ifa in static protocol module.
nb->ifa is null pointer in this case.
This patch also contains a fix in sk_setup(). When the source address
and the destination address of a socket are both zero, the socket will
be judged as an IPv6 socket since zero address is not a v4-mapped address.
As a result, IPV6_V6ONLY is set on this socket. This patch prevents
IPV6_V6ONLY from being set when both source address and destination address
are zero.
With below patch, I can confirm that bird won't crash and BFD packets can
be successfully sent.
Cheers,
Miao Wang
---
proto/static/static.c | 3 ++-
sysdep/unix/io.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/proto/static/static.c b/proto/static/static.c
index bb93305e..f2bb98c7 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -206,7 +206,8 @@ static_update_bfd(struct static_proto *p, struct static_route *r)
if (bfd_up && !r->bfd_req)
{
// ip_addr local = ipa_nonzero(r->local) ? r->local : nb->ifa->ip;
- r->bfd_req = bfd_request_session(p->p.pool, r->via, nb->ifa->ip,
+ r->bfd_req = bfd_request_session(p->p.pool, r->via,
+ nb->ifa ? nb->ifa->ip : IPA_NONE,
nb->iface, p->p.vrf,
static_bfd_notify, r, NULL);
}
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index e131ca41..8075c2bd 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -996,7 +996,7 @@ sk_setup(sock *s)
if (sk_is_ipv6(s))
{
- if ((s->type == SK_TCP_PASSIVE) || (s->type == SK_TCP_ACTIVE) || (s->type == SK_UDP))
+ if (((s->type == SK_TCP_PASSIVE) || (s->type == SK_TCP_ACTIVE) || (s->type == SK_UDP)) && (ipa_nonzero(s->saddr) || ipa_nonzero(s->daddr)))
if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, &y, sizeof(y)) < 0)
ERR("IPV6_V6ONLY");
--
2.39.0
More information about the Bird-users
mailing list