]> git.puffer.fish Git - matthieu/frr.git/commitdiff
staticd: Fix NULL pointer dereference
authorCarmine Scarpitta <cscarpit@cisco.com>
Sun, 2 Feb 2025 09:06:22 +0000 (10:06 +0100)
committerCarmine Scarpitta <cscarpit@cisco.com>
Sun, 2 Feb 2025 09:06:22 +0000 (10:06 +0100)
When staticd receives a `ZAPI_SRV6_SID_RELEASED` notification from SRv6
SID Manager, it tries to unset the validity flag of `sid`. But since
the `sid` variable is NULL, we get a NULL pointer dereference.

```
=================================================================
==13815==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000060 (pc 0xc14b813d9eac bp 0xffffcb135a40 sp 0xffffcb135a40 T0)
==13815==The signal is caused by a READ memory access.
==13815==Hint: address points to the zero page.
    #0 0xc14b813d9eac in static_zebra_srv6_sid_notify staticd/static_zebra.c:1172
    #1 0xe44e7aa2c194 in zclient_read lib/zclient.c:4746
    #2 0xe44e7a9b69d8 in event_call lib/event.c:1984
    #3 0xe44e7a85ac28 in frr_run lib/libfrr.c:1246
    #4 0xc14b813ccf98 in main staticd/static_main.c:193
    #5 0xe44e7a4773f8 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #6 0xe44e7a4774c8 in __libc_start_main_impl ../csu/libc-start.c:392
    #7 0xc14b813cc92c in _start (/usr/lib/frr/staticd+0x1c92c)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV staticd/static_zebra.c:1172 in static_zebra_srv6_sid_notify
==13815==ABORTING
```

This commit fixes the problem by doing a SID lookup first. If the SID
can't be found, we log an error and return. If the SID is found, we go
ahead and unset the validity flag.

Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
staticd/static_zebra.c

index 057193aa08b4bdfbff427a0a5fe837e295debe4e..6da2dfec90853ea30d85ea7f2931c4f1349077bf 100644 (file)
@@ -1169,6 +1169,19 @@ static int static_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS)
                DEBUGD(&static_dbg_srv6, "%s: SRv6 SID %pI6 %s: RELEASED", __func__, &sid_addr,
                       srv6_sid_ctx2str(buf, sizeof(buf), &ctx));
 
+               for (ALL_LIST_ELEMENTS_RO(srv6_sids, node, sid)) {
+                       if (IPV6_ADDR_SAME(&sid->addr.prefix, &sid_addr)) {
+                               found = true;
+                               break;
+                       }
+               }
+
+               if (!found || !sid) {
+                       zlog_err("SRv6 SID %pI6 %s: not found", &sid_addr,
+                                srv6_sid_ctx2str(buf, sizeof(buf), &ctx));
+                       return 0;
+               }
+
                UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID);
 
                break;