Browse Source

gdbstub: Try unlinking the unix socket before binding

In case an emulated process execve()s another emulated process, bind()
will fail, because the socket already exists. So try deleting it. Use
the existing unix_listen() function which does this. Link qemu-user
with qemu-sockets.c and add the monitor_get_fd() stub.

Note that it is not possible to handle this in do_execv(): deleting
gdbserver_user_state.socket_path before safe_execve() is not correct,
because the latter may fail, and afterwards we may lose control.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20250117001542.8290-3-iii@linux.ibm.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20250207153112.3939799-12-alex.bennee@linaro.org>
pull/281/head
Ilya Leoshkevich 2 years ago
committed by Alex Bennée
parent
commit
fccb744f41
  1. 29
      gdbstub/user.c
  2. 2
      stubs/meson.build
  3. 9
      stubs/monitor-fd.c
  4. 2
      util/meson.build

29
gdbstub/user.c

@ -315,12 +315,10 @@ static bool gdb_accept_socket(int gdb_fd)
return true;
}
static int gdbserver_open_socket(const char *path)
static int gdbserver_open_socket(const char *path, Error **errp)
{
g_autoptr(GString) buf = g_string_new("");
struct sockaddr_un sockaddr = {};
char *pid_placeholder;
int fd, ret;
pid_placeholder = strstr(path, "%d");
if (pid_placeholder != NULL) {
@ -330,28 +328,7 @@ static int gdbserver_open_socket(const char *path)
path = buf->str;
}
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
perror("create socket");
return -1;
}
sockaddr.sun_family = AF_UNIX;
pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
if (ret < 0) {
perror("bind socket");
close(fd);
return -1;
}
ret = listen(fd, 1);
if (ret < 0) {
perror("listen socket");
close(fd);
return -1;
}
return fd;
return unix_listen(path, errp);
}
static bool gdb_accept_tcp(int gdb_fd)
@ -424,7 +401,7 @@ bool gdbserver_start(const char *port_or_path, Error **errp)
if (port > 0) {
gdb_fd = gdbserver_open_port(port, errp);
} else {
gdb_fd = gdbserver_open_socket(port_or_path);
gdb_fd = gdbserver_open_socket(port_or_path, errp);
}
if (gdb_fd < 0) {

2
stubs/meson.build

@ -61,6 +61,8 @@ if have_user
if not have_system
stub_ss.add(files('qdev.c'))
endif
stub_ss.add(files('monitor-fd.c'))
endif
if have_system

9
stubs/monitor-fd.c

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "monitor/monitor.h"
int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
{
abort();
}

2
util/meson.build

@ -84,6 +84,8 @@ if have_block or have_ga
util_ss.add(files('qemu-coroutine.c', 'qemu-coroutine-lock.c', 'qemu-coroutine-io.c'))
util_ss.add(files(f'coroutine-@coroutine_backend@.c'))
util_ss.add(files('thread-pool.c', 'qemu-timer.c'))
endif
if have_block or have_ga or have_user
util_ss.add(files('qemu-sockets.c'))
endif
if have_block

Loading…
Cancel
Save