Project: frr (frrouting/frr), language: c++
Vulnerability instance: frr.cve-2022-26126
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/FRRouting/frr/issues/10505
## Description:
Issue: FRRouting/frr#10505
Title: isisd: misusing strdup leads to stack overflow
State: closed
Created by: whichbug
Created at: 2022-02-05 05:11:16+00:00
Labels: triage

Issue Body:
At Line 470 in the code below, we call `yang_data_new`, which will further call `strdup(raw_pdu)`. However, `raw_pdu` is not guaranteed to be a zero-terminated string and, thus, will lead to a stack overflow in `strdup`. When I set `raw_pdu[raw_pdu_len - 1]` to `\0`, then the bug disappears. Note that `strdup` should be used with a C-string.

In the same file, `isis_nb_notifications.c`, there are **8 places** where `yang_data_new` are used with `raw_pdu` and, thus, may have the overflow bug. Please check and suggest a fix. I can give a pull request then.

https://github.com/FRRouting/frr/blob/eef8006341e85d80d0a3c21a642ced3b73a42375/isisd/isis_nb_notifications.c#L454-L471

What follows is the output of the address sanitizer:

```
==48351==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7ffe596a3a76 at pc 0x000000543e97 bp 0x7ffe596a3020 sp 0x7ffe596a27e0
READ of size 23 at 0x7ffe596a3a76 thread T0
    #0 0x543e96 in strdup (/home/parallels/myfrr/isisd/isisd+0x543e96)
    #1 0x84f73d in yang_data_new /home/parallels/myfrr/lib/yang.c:608:17
    #2 0x6716eb in isis_notif_id_len_mismatch /home/parallels/myfrr/isisd/isis_nb_notifications.c:470:9
    #3 0x5cedcf in isis_handle_pdu /home/parallels/myfrr/isisd/isis_pdu.c:1706:3
```


Comments:
Comment by whichbug on 2022-02-08 16:10:47+00:00:
@idryzhov Could you also have a look at this issue?

---

Comment by idryzhov on 2022-02-09 22:58:47+00:00:
Hi @whichbug, I checked the issue. The problem here is that we're trying to represent binary data as a simple string, which is wrong.

The only correct solution here would be to implement new function `yang_data_new_binary(const char *xpath, const char *binary, size_t len)` which will create a correct textual representation of YANG binary data, which is Base 64 Encoding. And then use this function instead of simple `yang_data_new` whenever we need to convert `raw_pdu`.
I probably won't find time to implement it in the next couple of days, so feel free to submit a PR.

---

Comment by whichbug on 2022-02-09 23:04:56+00:00:
> Hi @whichbug, I checked the issue. The problem here is that we're trying to represent binary data as a simple string, which is wrong.
> 
> The only correct solution here would be to implement new function `yang_data_new_binary(const char *xpath, const char *binary, size_t len)` which will create a correct textual representation of YANG binary data, which is Base 64 Encoding. And then use this function instead of simple `yang_data_new` whenever we need to convert `raw_pdu`. I probably won't find time to implement it in the next couple of days, so feel free to submit a PR.

Hi, @idryzhov  thanks for your reply. I think your idea makes sense and I will try.

---

Comment by qlyoung on 2022-02-10 18:27:50+00:00:
Nice find. By the way, when you find issues like this, if you want you can just submit a pull request without filing an issue. We patch these kinds of things regularly without making an issue, since the pull request itself is records of both the issue and the appropriate fix for it. It's a little easier for us since we can track it in one place, and it helps keep our issues a little cleaner. It's up to you though.

---

Comment by whichbug on 2022-02-11 04:31:58+00:00:
> Nice find. By the way, when you find issues like this, if you want you can just submit a pull request without filing an issue. We patch these kinds of things regularly without making an issue, since the pull request itself is records of both the issue and the appropriate fix for it. It's a little easier for us since we can track it in one place, and it helps keep our issues a little cleaner. It's up to you though.

Sure. Many thanks!

---

Comment by qlyoung on 2022-03-28 18:20:02+00:00:
This is now filed as [CVE-2022-26126](https://nvd.nist.gov/vuln/detail/CVE-2022-26126), with an assigned severity score of 7.8.

No assessment of exploitability has been made.

Please see my comment [here](https://github.com/FRRouting/frr/issues/10507#issuecomment-1080985102).

Commit References:
eef8006341e85d80d0a3c21a642ced3b73a42375

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
cd $SRC/libyang
mkdir -p build; cd build
cmake -DBUILD_SHARED_LIBS=OFF -DENABLE_LYD_PRIV=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr \
    -D CMAKE_BUILD_TYPE:String="Release" ..
make -j$(nproc)
make install -j$(nproc)
export ASAN_OPTIONS=detect_leaks=0
./bootstrap.sh
./configure --enable-libfuzzer --enable-static --enable-static-bin --sbindir=$SRC/bin
cd $SRC/corpi

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y git autoconf automake libtool make libreadline-dev texinfo libjson-c-dev pkg-config bison flex python3-pip libc-ares-dev python3-dev python3-sphinx build-essential libsystemd-dev libsnmp-dev libcap-dev libelf-dev libpcre3-dev libpcre2-dev
RUN git clone https://github.com/frrouting/frr frr
RUN git -C frr checkout f72b987de1d4897919902b96559c8fd4da58b366
WORKDIR $SRC/frr
COPY build.sh $SRC/

Additional files: