diff options
author | Stefan Metzmacher <metze@samba.org> | 2021-02-17 11:00:53 +0100 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2021-03-15 08:04:58 +0100 |
commit | 167009f6ac1186aeeabffc29368bd5b375d9861f (patch) | |
tree | 4b6e67093b5fa6af7245583b578f6f89bf4d6627 | |
parent | 2cf4c543d614e3263fa261e4584716d5b7771f09 (diff) | |
download | socket_wrapper-167009f6ac1186aeeabffc29368bd5b375d9861f.tar.gz socket_wrapper-167009f6ac1186aeeabffc29368bd5b375d9861f.tar.xz socket_wrapper-167009f6ac1186aeeabffc29368bd5b375d9861f.zip |
swrap: call libc_write() directly for internal fds
Otherwise we may deadlock with a backtrace like this:
swrap_accept():
...
SWRAP_LOCK_SI(si);
swrap_pcap_dump_packet() ->
write() ->
swrap_write() ->
SWRAP_LOCK_SI(si) -> abort()
This can happen if libc_open() called from swrap_pcap_get_fd()
return a stale fd. This may happen if glibc calls socket()
and closes it with __close_nocancel() instead of close().
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14640
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
-rw-r--r-- | src/socket_wrapper.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index b6c7637..3bf60f1 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -3004,7 +3004,7 @@ static int swrap_pcap_get_fd(const char *fname) file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX; file_hdr.link_type = 0x0065; /* 101 RAW IP */ - if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) { + if (libc_write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) { libc_close(fd); fd = -1; } @@ -3339,7 +3339,7 @@ static void swrap_pcap_dump_packet(struct socket_info *si, fd = swrap_pcap_get_fd(file_name); if (fd != -1) { - if (write(fd, packet, packet_len) != (ssize_t)packet_len) { + if (libc_write(fd, packet, packet_len) != (ssize_t)packet_len) { free(packet); goto done; } @@ -5546,7 +5546,7 @@ static int swrap_sendmsg_unix_scm_rights(const struct cmsghdr *cmsg, return -1; } - sret = write(pipefd[1], &info, sizeof(info)); + sret = libc_write(pipefd[1], &info, sizeof(info)); if (sret != sizeof(info)) { int saved_errno = errno; if (sret != -1) { |