summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2021-02-17 11:00:53 +0100
committerAndreas Schneider <asn@samba.org>2021-03-15 08:04:58 +0100
commit167009f6ac1186aeeabffc29368bd5b375d9861f (patch)
tree4b6e67093b5fa6af7245583b578f6f89bf4d6627
parent2cf4c543d614e3263fa261e4584716d5b7771f09 (diff)
downloadsocket_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.c6
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) {