Skip to content

[BUG REPORT] Tcp inner::Inner is None panic in lifecycle.rs during repeated bind operations #1736

@nuczyc

Description

@nuczyc

Describe the bug

A kernel panic occurs in lifecycle.rs:12 when calling bind() multiple times on the same TCP socket. After the first successful bind, subsequent bind attempts log "Already Bound" and then panic with "Tcp inner::Inner is None", indicating the TCP socket's internal state is invalid.

match writer.take().expect("Tcp inner::Inner is None") {

To Reproduce

  1. Compile the program and run.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

/*
 * PoC for potential index out of bounds in DragonOS kernel sys_bind syscall
 * 
 * The crash occurs at /home/yuchen/dragon/DragonOS/kernel/src/net/syscall/sys_bind.rs:73
 * in the fd() function when accessing args[0]. This suggests the syscall arguments
 * array might be empty or shorter than expected when the kernel processes the bind syscall.
 * 
 * This PoC attempts to trigger the condition by calling bind() with various scenarios:
 * 1. Normal bind call (baseline)
 * 2. Bind with invalid file descriptor
 * 3. Bind with potentially problematic socket configurations
 * 
 * Note: The actual crash might not be triggerable from user space if the issue is in
 * the kernel's syscall argument handling mechanism rather than the bind logic itself.
 * However, we attempt various bind calls to stress the syscall path.
 */

int main() {
    int sockfd;
    struct sockaddr_in addr;
    int ret;
    
    // Create a socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket failed");
        return 1;
    }
    
    // Prepare address structure
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(8080);
    
    // Attempt 1: Normal bind call
    printf("Attempting normal bind call...\n");
    ret = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    if (ret < 0) {
        perror("bind failed (expected if port in use)");
    } else {
        printf("bind succeeded\n");
    }
    
    // Attempt 2: Bind with invalid file descriptor
    printf("Attempting bind with invalid fd...\n");
    ret = bind(-1, (struct sockaddr*)&addr, sizeof(addr));
    if (ret < 0) {
        perror("bind with invalid fd failed (expected)");
    }
    
    // Attempt 3: Bind with NULL address
    printf("Attempting bind with NULL address...\n");
    ret = bind(sockfd, NULL, 0);
    if (ret < 0) {
        perror("bind with NULL address failed (expected)");
    }
    
    // Attempt 4: Bind with very large addrlen
    printf("Attempting bind with large addrlen...\n");
    ret = bind(sockfd, (struct sockaddr*)&addr, 0xFFFF);
    if (ret < 0) {
        perror("bind with large addrlen failed (expected)");
    }
    
    // Attempt 5: Multiple rapid bind calls
    printf("Attempting multiple rapid bind calls...\n");
    for (int i = 0; i < 10; i++) {
        addr.sin_port = htons(8080 + i);
        ret = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
        if (ret < 0) {
            // Expected to fail after first successful bind
        }
    }
    
    close(sockfd);
    
    printf("PoC completed. If the kernel vulnerability is triggerable, it should have crashed.\n");
    printf("If not, the issue might be in internal kernel syscall handling not accessible from user space.\n");
    
    return 0;
}

Environment

Logs

s:~# /bin/ex3361___home__yuchen__dragon__DragonOS__kernel__s 
Attempting normal bind call...
bind succeeded
Attempting bind with invalid fd...
bind with invalid fd failed (expected): Bad file descriptor
Attempting bind with NULL address...
[ ERROR ] (src/net/posix.rs:250)         addr_len 0 < sizeof(sa_family_t)
bind with NULL address failed (expected): Invalid argument
Attempting bind with large addrlen...
[ ERROR ] (src/net/posix.rs:240)         addr_len 65535 exceeds MAX_SOCKADDR_LEN 128
bind with large addrlen failed (expected): Invalid argument
Attempting multiple rapid bind calls...
[ DEBUG ] (src/net/socket/inet/stream/inner.rs:134)      Already Bound
[ ERROR ] (src/debug/panic/mod.rs:43)    Kernel Panic Occurred. raw_pid: 20
Location:
        File: src/net/socket/inet/stream/lifecycle.rs
        Line: 12, Column: 29
Message:
        Tcp inner::Inner is None
Rust Panic Backtrace:
[1] function:_Unwind_Backtrace()        (+) 0051 address:0xffff8000004db083
Current PCB:
        ProcessControlBlock { pid: AtomicRawPid { container: 20 }, tgid: RawPid(20), thread_pid: RwLock { lock: 0, data: UnsafeCell { .. } }, pid_links: [PidLink { pid: RwLock { lock: 0, data: UnsafeCell { .. } } }, PidLink { pid: RwLock}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug-report这是一个bug报告(如果确认是一个bug,请管理人员添加`bug` label)enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions