Skip to content

Incorrect handling of binding a socket to an already bound address (ql_syscall_bind) #1476

@carter-yagemann

Description

@carter-yagemann

Describe the bug

In Linux, when a target program binds a socket that is already bound, the OS should return an error code indicating that the address is already in use and the target program should proceed, but in Qiling an uncaught except is raised and execution is stopped, which is unexpected and undesired behavior.

Sample Code

Target Program Source Code: (adapted from man bind)

/* test.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define MY_SOCK_PATH "/tmp/testsocket"
#define LISTEN_BACKLOG 50

#define handle_error(msg) \
  do { perror(msg); exit(EXIT_FAILURE); } while (0)

int
main(void)
{
    int                 sfd, cfd;
    socklen_t           peer_addr_size;
    struct sockaddr_un  my_addr, peer_addr;

    sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1)
        handle_error("socket");

    memset(&my_addr, 0, sizeof(my_addr));
    my_addr.sun_family = AF_UNIX;
    strncpy(my_addr.sun_path, MY_SOCK_PATH,
        sizeof(my_addr.sun_path) - 1);

    printf("Bind 1\n");
    if (bind(sfd, (struct sockaddr *) &my_addr,
            sizeof(my_addr)) == -1)
        handle_error("bind");

    printf("Bind 2\n");
    if (bind(sfd, (struct sockaddr *) &my_addr,
            sizeof(my_addr)) == -1)
        handle_error("bind");

    return 0;
}

Real Execution:

gcc -o test -static test.c
./test
# output:
# Bind 1
# Bind 2
# bind: Address already in use

Qiling Emulation:

import qiling
ql = qiling.Qiling(["./root_fs/test"], "./root_fs")
ql.run()

[x] Syscall ERROR: ql_syscall_bind DEBUG: [Errno 98] Address already in use
Traceback (most recent call last):
File "/env/lib/python3.11/site-packages/qiling/os/posix/posix.py", line 374, in load_syscall
retval = syscall_hook(self.ql, *params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/env/lib/python3.11/site-packages/qiling/os/posix/syscall/socket.py", line 433, in ql_syscall_bind
sock.bind(dest)
File "/env/lib/python3.11/site-packages/qiling/os/posix/filestruct.py", line 83, in bind
return self.__socket.bind(address)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 98] Address already in use

Expected behavior
Qiling should correctly handle the case where the host OS returns an "Address already in use" error and return the proper return value to the target program. Many programs use the behavior like in test.c to check for already running instances of the program.

Screenshots
N/A

Additional context
N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions