[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