Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Null Pointer Dereference in Function topic_filtern at mqtt_parser.c Leading to Runtime Error #1723

Closed
dqp10515 opened this issue Mar 26, 2024 · 1 comment

Comments

@dqp10515
Copy link

Describe the bug
A runtime error occurs in the topic_filtern function of the mqtt_parser.c file within the NanoMQ project. The function triggers an undefined behavior when the strncpy function is called with a null pointer as its second argument. This violates the non-null expectation for strncpy's arguments as declared in the standard library header string.h.

Expected behavior
The topic_filtern function is expected to safely copy a given number of characters from the input string to a newly allocated buffer. Before attempting to copy, the function should verify that the input pointer is not null to comply with the strncpy function's requirements.

Actual Behavior
When the topic_filtern function is invoked with a null input pointer, it proceeds to call strncpy without any checks for nullity. This results in a runtime error reported by the UndefinedBehaviorSanitizer, specifically stating "null pointer passed as argument 2, which is declared to never be null."

To Reproduce

Follow these steps to reproduce the issue:

  1. Compile NanoMQ with ASan and UBSan enabled:

    mkdir nanomq/build
    cd build
    cmake -DBUILD_BENCH=ON -DASAN=ON -DTSAN=ON \
        -DCMAKE_C_COMPILER=clang \
        -DCMAKE_CXX_COMPILER=clang++ \
        -DCMAKE_C_FLAGS="-g -fsanitize=address,undefined -fno-omit-frame-pointer" \
        -DCMAKE_CXX_FLAGS="-g -fsanitize=address,undefined -fno-omit-frame-pointer" \
        -DCMAKE_LD_FLAGS="-fsanitize=address,undefined" \
        ..
    make clean
    make -j 8
  2. Start the NanoMQ server with the following command:

    nanomq/build/nanomq/nanomq start --url nmq-tcp://0.0.0.0:5883 --url nmq-ws://localhost:5885 --max_tq_thread 8 -n 16
  3. Send a series of hexstreams to the server in sequence, which are stored in the file hexstream.txt using the code:

import socket

def send_packet(input):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect(('127.0.0.1', 5883))
        s.send(input)
    except ConnectionResetError:
        print("Connection was reset.")
    except ConnectionRefusedError:
        print("Connection refused.")
    finally:
        s.close()

with open('hexstream.txt', 'r') as f:
    crash_log = f.read().splitlines()

for c in crash_log:
    clean_c = ''.join(c.split())
    packet = bytearray.fromhex(clean_c)
    send_packet(packet)

All hexstreams that triggered the issue are in the file:
hexstream.txt

Environment Details

  • NanoMQ version 0.21.7
  • Operating system and version Ubuntu 20.04 LTS
  • Compiler and language used clang version 12.0.0
  • testing scenario

Crash Report
log of server:

2024-03-25 06:54:58 [391720] ERROR nanomq/nng/src/supplemental/nanolib/conf_ver2.c:1534 conf_parse_ver2: Configure file [(null)] or [/etc/nanomq.conf] not found or unreadable
NanoMQ Broker is started successfully!
2024-03-25 06:54:58 [391729] ERROR nanomq/nng/src/sp/transport/mqtt/broker_tcp.c:456 tcptran_pipe_nego_cb: connect nego error rv: Unknown error #130(130)
2024-03-25 06:54:58 [391733] ERROR nanomq/nng/src/sp/transport/mqtt/broker_tcp.c:456 tcptran_pipe_nego_cb: connect nego error rv: Unknown error #130(130)
2024-03-25 06:54:58 [391737] ERROR nanomq/nng/src/sp/protocol/mqtt/nmq_mqtt.c:1075 nano_pipe_recv_cb: Invalid subscribe packet!
2024-03-25 06:54:58 [391735] ERROR nanomq/nng/src/sp/protocol/mqtt/nmq_mqtt.c:1075 nano_pipe_recv_cb: Invalid subscribe packet!
2024-03-25 06:54:58 [391741] ERROR nanomq/nanomq/apps/broker.c:104 sig_handler: signal signumber: 6 received!



Here is the ASan report:

nanomq/nng/src/sp/protocol/mqtt/mqtt_parser.c:1865:16: runtime error: null pointer passed as argument 2, which is declared to never be null
/usr/include/string.h:127:14: note: nonnull attribute specified here
    #0 0x677646 in topic_filtern nanomq/nng/src/sp/protocol/mqtt/mqtt_parser.c:1865:2
    #1 0x67a850 in nano_ctx_send nanomq/nng/src/sp/protocol/mqtt/nmq_mqtt.c:415:8
    #2 0x615318 in nni_ctx_send nanomq/nng/src/core/socket.c:1438:2
    #3 0x5aef47 in nng_ctx_send nanomq/nng/src/nng.c:419:2
    #4 0x58ae3e in server_cb nanomq/nanomq/apps/broker.c:418:4
    #5 0x626485 in nni_task_exec nanomq/nng/src/core/taskq.c:144:3
    #6 0x5d08c3 in nni_aio_finish_impl nanomq/nng/src/core/aio.c:469:3
    #7 0x5d094c in nni_aio_finish_sync nanomq/nng/src/core/aio.c:484:2
    #8 0x68d84b in nano_pipe_recv_cb nanomq/nng/src/sp/protocol/mqtt/nmq_mqtt.c:1217:2
    #9 0x626485 in nni_task_exec nanomq/nng/src/core/taskq.c:144:3
    #10 0x5d08c3 in nni_aio_finish_impl nanomq/nng/src/core/aio.c:469:3
    #11 0x5d094c in nni_aio_finish_sync nanomq/nng/src/core/aio.c:484:2
    #12 0x92f2a7 in tcptran_pipe_recv_cb nanomq/nng/src/sp/transport/mqtt/broker_tcp.c:891:2
    #13 0x6253ae in nni_taskq_thread nanomq/nng/src/core/taskq.c:50:4
    #14 0x628eb8 in nni_thr_wrap nanomq/nng/src/core/thread.c:94:3
    #15 0x63bb0b in nni_plat_thr_main nanomq/nng/src/platform/posix/posix_thread.c:266:2
    #16 0x7ffae6287608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477:8
    #17 0x7ffae6015292 in clone /build/glibc-eX1tMB/glibc-2.31/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior nanomq/nng/src/sp/protocol/mqtt/mqtt_parser.c:1865:16 in 



@OdyWayne
Copy link
Collaborator

OdyWayne commented Mar 27, 2024

I believe it's fixed here --> nanomq/NanoNNG#903

@JaylinYu JaylinYu closed this as completed Apr 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants