From 86dbd9e755ae0472db3d8c04bc444c502193dc13 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Fri, 7 Sep 2018 14:19:38 -0700 Subject: [PATCH] *: set missing CLOEXEC on opened fds Otherwise these descriptors may leak across execve() during e.g. MDS respawn. Fixes: http://tracker.ceph.com/issues/35850 Signed-off-by: Patrick Donnelly --- CMakeLists.txt | 1 + src/auth/Crypto.cc | 4 +- src/ceph_osd.cc | 2 +- src/client/fuse_ll.cc | 2 +- src/common/CMakeLists.txt | 1 - src/common/HeartbeatMap.cc | 2 +- src/common/OutputDataSocket.cc | 22 ++-- src/common/Preforker.h | 19 +-- src/common/SubProcess.cc | 46 ++++--- src/common/admin_socket.cc | 23 ++-- src/common/admin_socket_client.cc | 6 +- src/common/blkdev.cc | 4 +- src/common/buffer.cc | 4 +- src/common/compat.cc | 118 +++++++++++++++++- src/common/config.cc | 2 +- src/common/pipe.c | 58 --------- src/common/pipe.h | 33 ----- src/crimson/CMakeLists.txt | 2 +- src/global/global_init.cc | 3 +- src/global/pidfile.cc | 2 +- src/global/signal_handler.cc | 8 +- src/include/compat.h | 2 + src/include/denc.h | 2 +- src/include/encoding.h | 2 +- src/include/random.h | 4 +- src/include/sock_compat.h | 16 +++ src/include/uuid.h | 7 +- src/kv/MemDB.cc | 4 +- src/log/Log.cc | 10 +- src/mds/MDCache.cc | 2 +- src/mon/LogMonitor.cc | 2 +- src/mon/Monitor.cc | 2 +- src/mon/MonitorDBStore.h | 2 +- src/msg/Message.cc | 2 +- src/msg/async/Event.cc | 8 +- src/msg/async/EventEpoll.cc | 9 ++ src/msg/async/PosixStack.cc | 5 +- src/msg/async/net_handler.cc | 22 +--- src/msg/async/net_handler.h | 1 - src/msg/async/rdma/RDMAConnectedSocketImpl.cc | 1 - src/msg/async/rdma/RDMAServerSocketImpl.cc | 7 +- src/msg/simple/Accepter.cc | 64 +++------- src/msg/simple/Pipe.cc | 8 +- src/os/bluestore/BlueStore.cc | 10 +- src/os/bluestore/KernelDevice.cc | 4 +- src/os/bluestore/NVMEDevice.cc | 2 +- src/os/bluestore/PMEMDevice.cc | 2 +- src/os/bluestore/bluestore_tool.cc | 4 +- src/os/filestore/BtrfsFileStoreBackend.cc | 6 +- src/os/filestore/FileJournal.cc | 2 +- src/os/filestore/FileStore.cc | 52 ++++---- src/os/filestore/GenericFileStoreBackend.cc | 13 +- src/os/filestore/LFNIndex.cc | 4 +- src/os/kstore/KStore.cc | 2 +- src/rgw/rgw_http_client.cc | 19 ++- src/test/objectstore/test_bluefs.cc | 5 +- 56 files changed, 343 insertions(+), 326 deletions(-) delete mode 100644 src/common/pipe.c delete mode 100644 src/common/pipe.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 27f8d0ce4ac03..b1e54fc10f412 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,7 @@ endif() CHECK_FUNCTION_EXISTS(strerror_r HAVE_Strerror_R) CHECK_FUNCTION_EXISTS(name_to_handle_at HAVE_NAME_TO_HANDLE_AT) CHECK_FUNCTION_EXISTS(pipe2 HAVE_PIPE2) +CHECK_FUNCTION_EXISTS(accept4 HAVE_ACCEPT4) include(CMakePushCheckState) cmake_push_check_state(RESET) diff --git a/src/auth/Crypto.cc b/src/auth/Crypto.cc index bd0ee383d87fd..2143a0699765b 100644 --- a/src/auth/Crypto.cc +++ b/src/auth/Crypto.cc @@ -15,6 +15,8 @@ #include #include +#include + #include "Crypto.h" #ifdef USE_OPENSSL # include @@ -54,7 +56,7 @@ void CryptoRandom::get_bytes(char *buf, int len) // open /dev/urandom once on construction and reuse the fd for all reads CryptoRandom::CryptoRandom() - : fd(TEMP_FAILURE_RETRY(::open("/dev/urandom", O_RDONLY))) + : fd(TEMP_FAILURE_RETRY(::open("/dev/urandom", O_CLOEXEC|O_RDONLY))) { if (fd < 0) { throw std::system_error(errno, std::system_category()); diff --git a/src/ceph_osd.cc b/src/ceph_osd.cc index 0cd40fa5dc94d..557188ec7a025 100644 --- a/src/ceph_osd.cc +++ b/src/ceph_osd.cc @@ -268,7 +268,7 @@ int main(int argc, const char **argv) { char fn[PATH_MAX]; snprintf(fn, sizeof(fn), "%s/type", data_path.c_str()); - int fd = ::open(fn, O_RDONLY); + int fd = ::open(fn, O_RDONLY|O_CLOEXEC); if (fd >= 0) { bufferlist bl; bl.read_fd(fd, 64); diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index 47140c784dab3..015c22c198472 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -418,7 +418,7 @@ static void fuse_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name, if (cfuse->fino_snap(parent) == CEPH_SNAPDIR && fuse_multithreaded && fuse_syncfs_on_mksnap) { int err = 0; - int fd = ::open(cfuse->mountpoint, O_RDONLY | O_DIRECTORY); + int fd = ::open(cfuse->mountpoint, O_RDONLY | O_DIRECTORY | O_CLOEXEC); if (fd < 0) { err = errno; } else { diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 0820b11e6b6de..06b251a26e1bb 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -79,7 +79,6 @@ set(common_srcs perf_counters.cc perf_histogram.cc pick_address.cc - pipe.c reverse.c run_cmd.cc scrub_types.cc diff --git a/src/common/HeartbeatMap.cc b/src/common/HeartbeatMap.cc index 222e0b41bab4b..8c9313ac953fa 100644 --- a/src/common/HeartbeatMap.cc +++ b/src/common/HeartbeatMap.cc @@ -170,7 +170,7 @@ void HeartbeatMap::check_touch_file() if (is_healthy()) { string path = m_cct->_conf->heartbeat_file; if (path.length()) { - int fd = ::open(path.c_str(), O_WRONLY|O_CREAT, 0644); + int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_CLOEXEC, 0644); if (fd >= 0) { ::utimes(path.c_str(), NULL); ::close(fd); diff --git a/src/common/OutputDataSocket.cc b/src/common/OutputDataSocket.cc index 9752ce318cc2a..c4ab890b526a7 100644 --- a/src/common/OutputDataSocket.cc +++ b/src/common/OutputDataSocket.cc @@ -14,9 +14,9 @@ #include "common/OutputDataSocket.h" #include "common/errno.h" -#include "common/pipe.h" #include "common/safe_io.h" #include "include/compat.h" +#include "include/sock_compat.h" #include #include @@ -117,10 +117,10 @@ OutputDataSocket::~OutputDataSocket() std::string OutputDataSocket::create_shutdown_pipe(int *pipe_rd, int *pipe_wr) { int pipefd[2]; - int ret = pipe_cloexec(pipefd); - if (ret < 0) { + if (pipe_cloexec(pipefd) < 0) { + int e = errno; ostringstream oss; - oss << "OutputDataSocket::create_shutdown_pipe error: " << cpp_strerror(ret); + oss << "OutputDataSocket::create_shutdown_pipe error: " << cpp_strerror(e); return oss.str(); } @@ -142,7 +142,7 @@ std::string OutputDataSocket::bind_and_listen(const std::string &sock_path, int << (sizeof(address.sun_path) - 1); return oss.str(); } - int sock_fd = socket(PF_UNIX, SOCK_STREAM, 0); + int sock_fd = socket_cloexec(PF_UNIX, SOCK_STREAM, 0); if (sock_fd < 0) { int err = errno; ostringstream oss; @@ -150,14 +150,6 @@ std::string OutputDataSocket::bind_and_listen(const std::string &sock_path, int << "failed to create socket: " << cpp_strerror(err); return oss.str(); } - int r = fcntl(sock_fd, F_SETFD, FD_CLOEXEC); - if (r < 0) { - r = errno; - VOID_TEMP_FAILURE_RETRY(::close(sock_fd)); - ostringstream oss; - oss << "OutputDataSocket::bind_and_listen: failed to fcntl on socket: " << cpp_strerror(r); - return oss.str(); - } memset(&address, 0, sizeof(struct sockaddr_un)); address.sun_family = AF_UNIX; snprintf(address.sun_path, sizeof(address.sun_path), @@ -241,15 +233,15 @@ bool OutputDataSocket::do_accept() struct sockaddr_un address; socklen_t address_length = sizeof(address); ldout(m_cct, 30) << "OutputDataSocket: calling accept" << dendl; - int connection_fd = accept(m_sock_fd, (struct sockaddr*) &address, + int connection_fd = accept_cloexec(m_sock_fd, (struct sockaddr*) &address, &address_length); - ldout(m_cct, 30) << "OutputDataSocket: finished accept" << dendl; if (connection_fd < 0) { int err = errno; lderr(m_cct) << "OutputDataSocket: do_accept error: '" << cpp_strerror(err) << dendl; return false; } + ldout(m_cct, 30) << "OutputDataSocket: finished accept" << dendl; handle_connection(connection_fd); close_connection(connection_fd); diff --git a/src/common/Preforker.h b/src/common/Preforker.h index a4d7af8f9a003..c0342c86049e6 100644 --- a/src/common/Preforker.h +++ b/src/common/Preforker.h @@ -8,9 +8,11 @@ #include #include -#include "include/ceph_assert.h" -#include "common/safe_io.h" #include "common/errno.h" +#include "common/safe_io.h" +#include "include/ceph_assert.h" +#include "include/compat.h" +#include "include/sock_compat.h" /** * pre-fork fork/daemonize helper class @@ -34,22 +36,23 @@ public: int prefork(std::string &err) { ceph_assert(!forked); - int r = ::socketpair(AF_UNIX, SOCK_STREAM, 0, fd); std::ostringstream oss; + int r = socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, fd); if (r < 0) { - oss << "[" << getpid() << "]: unable to create socketpair: " << cpp_strerror(errno); + int e = errno; + oss << "[" << getpid() << "]: unable to create socketpair: " << cpp_strerror(e); err = oss.str(); - return r; + return (errno = e, -1); } forked = true; childpid = fork(); if (childpid < 0) { - r = -errno; - oss << "[" << getpid() << "]: unable to fork: " << cpp_strerror(errno); + int e = errno; + oss << "[" << getpid() << "]: unable to fork: " << cpp_strerror(e); err = oss.str(); - return r; + return (errno = e, -1); } if (is_child()) { ::close(fd[0]); diff --git a/src/common/SubProcess.cc b/src/common/SubProcess.cc index 2bc1cf413a124..b7d6ca4ca8181 100644 --- a/src/common/SubProcess.cc +++ b/src/common/SubProcess.cc @@ -5,11 +5,13 @@ #include #endif #include +#include #include #include #include "common/errno.h" #include "include/ceph_assert.h" +#include "include/compat.h" SubProcess::SubProcess(const char *cmd_, std_fd_op stdin_op_, std_fd_op stdout_op_, std_fd_op stderr_op_) : cmd(cmd_), @@ -144,9 +146,9 @@ int SubProcess::spawn() { int ret = 0; - if ((stdin_op == PIPE && ::pipe(ipipe) == -1) || - (stdout_op == PIPE && ::pipe(opipe) == -1) || - (stderr_op == PIPE && ::pipe(epipe) == -1)) { + if ((stdin_op == PIPE && pipe_cloexec(ipipe) == -1) || + (stdout_op == PIPE && pipe_cloexec(opipe) == -1) || + (stderr_op == PIPE && pipe_cloexec(epipe) == -1)) { ret = -errno; errstr << "pipe failed: " << cpp_strerror(errno); goto fail; @@ -166,21 +168,33 @@ int SubProcess::spawn() { close(opipe[IN ]); close(epipe[IN ]); - if (ipipe[IN] != -1 && ipipe[IN] != STDIN_FILENO) { - ::dup2(ipipe[IN], STDIN_FILENO); - close(ipipe[IN]); + if (ipipe[IN] >= 0) { + if (ipipe[IN] == STDIN_FILENO) { + ::fcntl(STDIN_FILENO, F_SETFD, 0); /* clear FD_CLOEXEC */ + } else { + ::dup2(ipipe[IN], STDIN_FILENO); + ::close(ipipe[IN]); + } } - if (opipe[OUT] != -1 && opipe[OUT] != STDOUT_FILENO) { - ::dup2(opipe[OUT], STDOUT_FILENO); - close(opipe[OUT]); - static fd_buf buf(STDOUT_FILENO); - std::cout.rdbuf(&buf); + if (opipe[OUT] >= 0) { + if (opipe[OUT] == STDOUT_FILENO) { + ::fcntl(STDOUT_FILENO, F_SETFD, 0); /* clear FD_CLOEXEC */ + } else { + ::dup2(opipe[OUT], STDOUT_FILENO); + ::close(opipe[OUT]); + static fd_buf buf(STDOUT_FILENO); + std::cout.rdbuf(&buf); + } } - if (epipe[OUT] != -1 && epipe[OUT] != STDERR_FILENO) { - ::dup2(epipe[OUT], STDERR_FILENO); - close(epipe[OUT]); - static fd_buf buf(STDERR_FILENO); - std::cerr.rdbuf(&buf); + if (epipe[OUT] >= 0) { + if (epipe[OUT] == STDERR_FILENO) { + ::fcntl(STDERR_FILENO, F_SETFD, 0); /* clear FD_CLOEXEC */ + } else { + ::dup2(epipe[OUT], STDERR_FILENO); + ::close(epipe[OUT]); + static fd_buf buf(STDERR_FILENO); + std::cerr.rdbuf(&buf); + } } int maxfd = sysconf(_SC_OPEN_MAX); diff --git a/src/common/admin_socket.cc b/src/common/admin_socket.cc index decb8c3b8f54b..a88ce1a5cee88 100644 --- a/src/common/admin_socket.cc +++ b/src/common/admin_socket.cc @@ -18,7 +18,6 @@ #include "common/admin_socket_client.h" #include "common/dout.h" #include "common/errno.h" -#include "common/pipe.h" #include "common/safe_io.h" #include "common/Thread.h" #include "common/version.h" @@ -26,6 +25,8 @@ // re-include our assert to clobber the system one; fix dout: #include "include/ceph_assert.h" +#include "include/compat.h" +#include "include/sock_compat.h" #define dout_subsys ceph_subsys_asok #undef dout_prefix @@ -106,10 +107,10 @@ AdminSocket::~AdminSocket() std::string AdminSocket::create_shutdown_pipe(int *pipe_rd, int *pipe_wr) { int pipefd[2]; - int ret = pipe_cloexec(pipefd); - if (ret < 0) { + if (pipe_cloexec(pipefd) < 0) { + int e = errno; ostringstream oss; - oss << "AdminSocket::create_shutdown_pipe error: " << cpp_strerror(ret); + oss << "AdminSocket::create_shutdown_pipe error: " << cpp_strerror(e); return oss.str(); } @@ -158,7 +159,7 @@ std::string AdminSocket::bind_and_listen(const std::string &sock_path, int *fd) << (sizeof(address.sun_path) - 1); return oss.str(); } - int sock_fd = socket(PF_UNIX, SOCK_STREAM, 0); + int sock_fd = socket_cloexec(PF_UNIX, SOCK_STREAM, 0); if (sock_fd < 0) { int err = errno; ostringstream oss; @@ -166,14 +167,6 @@ std::string AdminSocket::bind_and_listen(const std::string &sock_path, int *fd) << "failed to create socket: " << cpp_strerror(err); return oss.str(); } - int r = fcntl(sock_fd, F_SETFD, FD_CLOEXEC); - if (r < 0) { - r = errno; - retry_sys_call(::close, sock_fd); - ostringstream oss; - oss << "AdminSocket::bind_and_listen: failed to fcntl on socket: " << cpp_strerror(r); - return oss.str(); - } memset(&address, 0, sizeof(struct sockaddr_un)); address.sun_family = AF_UNIX; snprintf(address.sun_path, sizeof(address.sun_path), @@ -284,15 +277,15 @@ bool AdminSocket::do_accept() struct sockaddr_un address; socklen_t address_length = sizeof(address); ldout(m_cct, 30) << "AdminSocket: calling accept" << dendl; - int connection_fd = accept(m_sock_fd, (struct sockaddr*) &address, + int connection_fd = accept_cloexec(m_sock_fd, (struct sockaddr*) &address, &address_length); - ldout(m_cct, 30) << "AdminSocket: finished accept" << dendl; if (connection_fd < 0) { int err = errno; lderr(m_cct) << "AdminSocket: do_accept error: '" << cpp_strerror(err) << dendl; return false; } + ldout(m_cct, 30) << "AdminSocket: finished accept" << dendl; char cmd[1024]; unsigned pos = 0; diff --git a/src/common/admin_socket_client.cc b/src/common/admin_socket_client.cc index 3742c3f1b2b24..9886bba6c06d7 100644 --- a/src/common/admin_socket_client.cc +++ b/src/common/admin_socket_client.cc @@ -13,6 +13,7 @@ */ #include +#include #include #include @@ -21,6 +22,9 @@ #include "common/safe_io.h" #include "common/admin_socket_client.h" +#include "include/compat.h" +#include "include/sock_compat.h" + using std::ostringstream; const char* get_rand_socket_path() @@ -43,7 +47,7 @@ const char* get_rand_socket_path() static std::string asok_connect(const std::string &path, int *fd) { - int socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); + int socket_fd = socket_cloexec(PF_UNIX, SOCK_STREAM, 0); if(socket_fd < 0) { int err = errno; ostringstream oss; diff --git a/src/common/blkdev.cc b/src/common/blkdev.cc index c206c0360fd54..00fdcb3fbff13 100644 --- a/src/common/blkdev.cc +++ b/src/common/blkdev.cc @@ -307,7 +307,7 @@ int _get_vdo_stats_handle(const char *devname, std::string *vdo_name) target[r] = 0; if (expect == target) { snprintf(fn, sizeof(fn), "/sys/kvdo/%s/statistics", de->d_name); - vdo_fd = ::open(fn, O_RDONLY); //DIRECTORY); + vdo_fd = ::open(fn, O_RDONLY|O_CLOEXEC); //DIRECTORY); if (vdo_fd >= 0) { *vdo_name = de->d_name; break; @@ -340,7 +340,7 @@ int get_vdo_stats_handle(const char *devname, std::string *vdo_name) int64_t get_vdo_stat(int vdo_fd, const char *property) { int64_t ret = 0; - int fd = ::openat(vdo_fd, property, O_RDONLY); + int fd = ::openat(vdo_fd, property, O_RDONLY|O_CLOEXEC); if (fd < 0) { return 0; } diff --git a/src/common/buffer.cc b/src/common/buffer.cc index c0c23f4bedc03..3b44f505c8fd3 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1931,7 +1931,7 @@ void buffer::list::decode_base64(buffer::list& e) int buffer::list::read_file(const char *fn, std::string *error) { - int fd = TEMP_FAILURE_RETRY(::open(fn, O_RDONLY)); + int fd = TEMP_FAILURE_RETRY(::open(fn, O_RDONLY|O_CLOEXEC)); if (fd < 0) { int err = errno; std::ostringstream oss; @@ -1986,7 +1986,7 @@ ssize_t buffer::list::read_fd(int fd, size_t len) int buffer::list::write_file(const char *fn, int mode) { - int fd = TEMP_FAILURE_RETRY(::open(fn, O_WRONLY|O_CREAT|O_TRUNC, mode)); + int fd = TEMP_FAILURE_RETRY(::open(fn, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode)); if (fd < 0) { int err = errno; cerr << "bufferlist::write_file(" << fn << "): failed to open file: " diff --git a/src/common/compat.cc b/src/common/compat.cc index 66f6e7e8f6b30..1cfc4db973ab9 100644 --- a/src/common/compat.cc +++ b/src/common/compat.cc @@ -1,19 +1,34 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * Copyright (C) 2018 Red Hat, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ +#include #include #include -#include #include -#include -#include -#include #include +#include +#include +#include +#include +#include #if defined(__linux__) #include #endif -#include "include/compat.h" +#include "include/compat.h" +#include "include/sock_compat.h" #include "common/safe_io.h" // The type-value for a ZFS FS in fstatfs. @@ -76,3 +91,96 @@ int ceph_posix_fallocate(int fd, off_t offset, off_t len) { #endif } +int pipe_cloexec(int pipefd[2]) +{ +#if defined(HAVE_PIPE2) + return pipe2(pipefd, O_CLOEXEC); +#else + if (pipe(pipefd) == -1) + return -1; + + /* + * The old-fashioned, race-condition prone way that we have to fall + * back on if pipe2 does not exist. + */ + if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) < 0) { + goto fail; + } + + if (fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) < 0) { + goto fail; + } + + return 0; +fail: + int save_errno = errno; + VOID_TEMP_FAILURE_RETRY(close(pipefd[0])); + VOID_TEMP_FAILURE_RETRY(close(pipefd[1])); + return (errno = save_errno, -1); +#endif +} + + +int socket_cloexec(int domain, int type, int protocol) +{ +#ifdef SOCK_CLOEXEC + return socket(domain, type|SOCK_CLOEXEC, protocol); +#else + int fd = socket(domain, type, protocol); + if (fd == -1) + return -1; + + if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) + goto fail; + + return fd; +fail: + int save_errno = errno; + VOID_TEMP_FAILURE_RETRY(close(fd)); + return (errno = save_errno, -1); +#endif +} + +int socketpair_cloexec(int domain, int type, int protocol, int sv[2]) +{ +#ifdef SOCK_CLOEXEC + return socketpair(domain, type|SOCK_CLOEXEC, protocol, sv); +#else + int rc = socketpair(domain, type, protocol, sv); + if (rc == -1) + return -1; + + if (fcntl(sv[0], F_SETFD, FD_CLOEXEC) < 0) + goto fail; + + if (fcntl(sv[1], F_SETFD, FD_CLOEXEC) < 0) + goto fail; + + return 0; +fail: + int save_errno = errno; + VOID_TEMP_FAILURE_RETRY(close(sv[0])); + VOID_TEMP_FAILURE_RETRY(close(sv[1])); + return (errno = save_errno, -1); +#endif +} + +int accept_cloexec(int sockfd, struct sockaddr* addr, socklen_t* addrlen) +{ +#ifdef HAVE_ACCEPT4 + return accept4(sockfd, addr, addrlen, SOCK_CLOEXEC); +#else + int fd = accept(sockfd, addr, addrlen); + if (fd == -1) + return -1; + + if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) + goto fail; + + return fd; +fail: + int save_errno = errno; + VOID_TEMP_FAILURE_RETRY(close(fd)); + return (errno = save_errno, -1); +#endif +} diff --git a/src/common/config.cc b/src/common/config.cc index f11412f0cf6c7..ef9f6a16f3e57 100644 --- a/src/common/config.cc +++ b/src/common/config.cc @@ -75,7 +75,7 @@ int ceph_resolve_file_search(const std::string& filename_list, int ret = -ENOENT; list::iterator iter; for (iter = ls.begin(); iter != ls.end(); ++iter) { - int fd = ::open(iter->c_str(), O_RDONLY); + int fd = ::open(iter->c_str(), O_RDONLY|O_CLOEXEC); if (fd < 0) { ret = -errno; continue; diff --git a/src/common/pipe.c b/src/common/pipe.c deleted file mode 100644 index 7353cb77f79b5..0000000000000 --- a/src/common/pipe.c +++ /dev/null @@ -1,58 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2011 New Dream Network - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ -#include "include/compat.h" - -#include -#include -#include - -int pipe_cloexec(int pipefd[2]) -{ - int ret; - -#if defined(HAVE_PIPE2) && defined(O_CLOEXEC) - ret = pipe2(pipefd, O_CLOEXEC); - if (ret == -1) - return -errno; - return 0; -#else - ret = pipe(pipefd); - if (ret == -1) - return -errno; - - /* - * The old-fashioned, race-condition prone way that we have to fall - * back on if O_CLOEXEC does not exist. - */ - ret = fcntl(pipefd[0], F_SETFD, FD_CLOEXEC); - if (ret == -1) { - ret = -errno; - goto out; - } - - ret = fcntl(pipefd[1], F_SETFD, FD_CLOEXEC); - if (ret == -1) { - ret = -errno; - goto out; - } - - return 0; - -out: - VOID_TEMP_FAILURE_RETRY(close(pipefd[0])); - VOID_TEMP_FAILURE_RETRY(close(pipefd[1])); - - return ret; -#endif -} diff --git a/src/common/pipe.h b/src/common/pipe.h deleted file mode 100644 index b57ec0cafd84c..0000000000000 --- a/src/common/pipe.h +++ /dev/null @@ -1,33 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2011 New Dream Network - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#ifndef CEPH_COMMON_PIPE_H -#define CEPH_COMMON_PIPE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** Create a pipe and set both ends to have F_CLOEXEC - * - * @param pipefd pipe array, just as in pipe(2) - * @return 0 on success, errno otherwise - */ -int pipe_cloexec(int pipefd[2]); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/crimson/CMakeLists.txt b/src/crimson/CMakeLists.txt index 1fe07e41b8741..ad72b61dc90ce 100644 --- a/src/crimson/CMakeLists.txt +++ b/src/crimson/CMakeLists.txt @@ -26,6 +26,7 @@ add_library(crimson-common STATIC ${PROJECT_SOURCE_DIR}/src/common/ceph_strings.cc ${PROJECT_SOURCE_DIR}/src/common/cmdparse.cc ${PROJECT_SOURCE_DIR}/src/common/common_init.cc + ${PROJECT_SOURCE_DIR}/src/common/compat.cc ${PROJECT_SOURCE_DIR}/src/common/code_environment.cc ${PROJECT_SOURCE_DIR}/src/common/config.cc ${PROJECT_SOURCE_DIR}/src/common/config_values.cc @@ -48,7 +49,6 @@ add_library(crimson-common STATIC ${PROJECT_SOURCE_DIR}/src/common/perf_counters.cc ${PROJECT_SOURCE_DIR}/src/common/perf_histogram.cc ${PROJECT_SOURCE_DIR}/src/common/page.cc - ${PROJECT_SOURCE_DIR}/src/common/pipe.c ${PROJECT_SOURCE_DIR}/src/common/snap_types.cc ${PROJECT_SOURCE_DIR}/src/common/safe_io.c ${PROJECT_SOURCE_DIR}/src/common/signal.cc diff --git a/src/global/global_init.cc b/src/global/global_init.cc index fc7e17704ccf6..df0d59e0c295f 100644 --- a/src/global/global_init.cc +++ b/src/global/global_init.cc @@ -426,7 +426,7 @@ void global_init_daemonize(CephContext *cct) int reopen_as_null(CephContext *cct, int fd) { - int newfd = open("/dev/null", O_RDONLY); + int newfd = open("/dev/null", O_RDONLY|O_CLOEXEC); if (newfd < 0) { int err = errno; lderr(cct) << __func__ << " failed to open /dev/null: " << cpp_strerror(err) @@ -444,6 +444,7 @@ int reopen_as_null(CephContext *cct, int fd) } // close newfd (we cloned it to target fd) VOID_TEMP_FAILURE_RETRY(close(newfd)); + // N.B. FD_CLOEXEC is cleared on fd (see dup2(2)) return 0; } diff --git a/src/global/pidfile.cc b/src/global/pidfile.cc index 79e2a98371512..76621e0f4965c 100644 --- a/src/global/pidfile.cc +++ b/src/global/pidfile.cc @@ -141,7 +141,7 @@ int pidfh::open(const ConfigProxy& conf) return -ENAMETOOLONG; int fd; - fd = ::open(pf_path, O_CREAT|O_RDWR, 0644); + fd = ::open(pf_path, O_CREAT|O_RDWR|O_CLOEXEC, 0644); if (fd < 0) { int err = errno; derr << __func__ << ": failed to open pid file '" diff --git a/src/global/signal_handler.cc b/src/global/signal_handler.cc index 1a3081515ef2f..3ac35626cb35e 100644 --- a/src/global/signal_handler.cc +++ b/src/global/signal_handler.cc @@ -189,7 +189,7 @@ static void handle_fatal_signal(int signum) if (r >= 0) { char fn[PATH_MAX*2]; snprintf(fn, sizeof(fn)-1, "%s/meta", base); - int fd = ::open(fn, O_CREAT|O_WRONLY, 0600); + int fd = ::open(fn, O_CREAT|O_WRONLY|O_CLOEXEC, 0600); if (fd >= 0) { JSONFormatter jf(true); jf.open_object_section("crash"); @@ -209,7 +209,7 @@ static void handle_fatal_signal(int signum) } #if defined(__linux__) // os-release - int in = ::open("/etc/os-release", O_RDONLY); + int in = ::open("/etc/os-release", O_RDONLY|O_CLOEXEC); if (in >= 0) { char buf[4096]; r = safe_read(in, buf, sizeof(buf)-1); @@ -406,7 +406,7 @@ struct SignalHandler : public Thread { : stop(false), lock("SignalHandler::lock") { // create signal pipe - int r = pipe(pipefd); + int r = pipe_cloexec(pipefd); ceph_assert(r == 0); r = fcntl(pipefd[0], F_SETFL, O_NONBLOCK); ceph_assert(r == 0); @@ -543,7 +543,7 @@ void SignalHandler::register_handler(int signum, signal_handler_t handler, bool safe_handler *h = new safe_handler; - r = pipe(h->pipefd); + r = pipe_cloexec(h->pipefd); ceph_assert(r == 0); r = fcntl(h->pipefd[0], F_SETFL, O_NONBLOCK); ceph_assert(r == 0); diff --git a/src/include/compat.h b/src/include/compat.h index b6c629b7e03dd..a027fe381f5d4 100644 --- a/src/include/compat.h +++ b/src/include/compat.h @@ -173,4 +173,6 @@ int ceph_posix_fallocate(int fd, off_t offset, off_t len); +int pipe_cloexec(int pipefd[2]); + #endif /* !CEPH_COMPAT_H */ diff --git a/src/include/denc.h b/src/include/denc.h index c8d79f8886893..9a5b0292d3c14 100644 --- a/src/include/denc.h +++ b/src/include/denc.h @@ -97,7 +97,7 @@ inline constexpr bool denc_supported = denc_traits::supported; snprintf(fn, sizeof(fn), \ ENCODE_STRINGIFY(ENCODE_DUMP_PATH) "/%s__%d.%x", #Type, \ getpid(), i++); \ - int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0644); \ + int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC, 0644); \ if (fd >= 0) { \ size_t len = p.get_pos() - __denc_dump_pre; \ int r = ::write(fd, __denc_dump_pre, len); \ diff --git a/src/include/encoding.h b/src/include/encoding.h index 3b21569c46dd6..fe07d4047d280 100644 --- a/src/include/encoding.h +++ b/src/include/encoding.h @@ -142,7 +142,7 @@ WRITE_INTTYPE_ENCODER(int16_t, le16) break; \ char fn[PATH_MAX]; \ snprintf(fn, sizeof(fn), ENCODE_STRINGIFY(ENCODE_DUMP_PATH) "/%s__%d.%x", #cl, getpid(), i++); \ - int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0644); \ + int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC, 0644); \ if (fd >= 0) { \ ::ceph::bufferlist sub; \ sub.substr_of(bl, pre_off, bl.length() - pre_off); \ diff --git a/src/include/random.h b/src/include/random.h index cbfee2d7235b1..b3cb80c31d29f 100644 --- a/src/include/random.h +++ b/src/include/random.h @@ -91,7 +91,7 @@ void randomize_rng(const SeedT seed, MutexT& m, EngineT& e) template void randomize_rng(MutexT& m, EngineT& e) { - thread_local std::random_device rd; + std::random_device rd; std::lock_guard lg(m); e.seed(rd()); @@ -107,7 +107,7 @@ void randomize_rng(const SeedT n) template void randomize_rng() { - thread_local std::random_device rd; + std::random_device rd; detail::engine().seed(rd()); } diff --git a/src/include/sock_compat.h b/src/include/sock_compat.h index f9dc24b1ddc6b..14b5efa1df2db 100644 --- a/src/include/sock_compat.h +++ b/src/include/sock_compat.h @@ -1,7 +1,19 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2018 Red Hat, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ + #ifndef CEPH_SOCK_COMPAT_H #define CEPH_SOCK_COMPAT_H #include "include/compat.h" +#include /* * This optimization may not be available on all platforms (e.g. OSX). @@ -24,4 +36,8 @@ # endif #endif +int socket_cloexec(int domain, int type, int protocol); +int socketpair_cloexec(int domain, int type, int protocol, int sv[2]); +int accept_cloexec(int sockfd, struct sockaddr* addr, socklen_t* addrlen); + #endif diff --git a/src/include/uuid.h b/src/include/uuid.h index 219def4b8aede..f957f87ab2e62 100644 --- a/src/include/uuid.h +++ b/src/include/uuid.h @@ -6,12 +6,13 @@ */ #include "encoding.h" + #include +#include #include #include #include -#include struct uuid_d { boost::uuids::uuid uuid; @@ -26,8 +27,8 @@ struct uuid_d { } void generate_random() { - boost::random::random_device rng("/dev/urandom"); - boost::uuids::basic_random_generator gen(&rng); + std::random_device rng; + boost::uuids::basic_random_generator gen(rng); uuid = gen(); } diff --git a/src/kv/MemDB.cc b/src/kv/MemDB.cc index c648dd9fb5151..d687d84f9c3b6 100644 --- a/src/kv/MemDB.cc +++ b/src/kv/MemDB.cc @@ -69,7 +69,7 @@ void MemDB::_save() dout(10) << __func__ << " Saving MemDB to file: "<< _get_data_fn().c_str() << dendl; int mode = 0644; int fd = TEMP_FAILURE_RETRY(::open(_get_data_fn().c_str(), - O_WRONLY|O_CREAT|O_TRUNC, mode)); + O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode)); if (fd < 0) { int err = errno; cerr << "write_file(" << _get_data_fn().c_str() << "): failed to open file: " @@ -95,7 +95,7 @@ int MemDB::_load() /* * Open file and read it in single shot. */ - int fd = TEMP_FAILURE_RETRY(::open(_get_data_fn().c_str(), O_RDONLY)); + int fd = TEMP_FAILURE_RETRY(::open(_get_data_fn().c_str(), O_RDONLY|O_CLOEXEC)); if (fd < 0) { int err = errno; cerr << "can't open " << _get_data_fn().c_str() << ": " diff --git a/src/log/Log.cc b/src/log/Log.cc index bfceb7b9c52c5..82196645bd498 100644 --- a/src/log/Log.cc +++ b/src/log/Log.cc @@ -17,6 +17,7 @@ #include "SubsystemMap.h" #include +#include #include #include @@ -109,12 +110,11 @@ void Log::reopen_log_file() if (m_fd >= 0) VOID_TEMP_FAILURE_RETRY(::close(m_fd)); if (m_log_file.length()) { - m_fd = ::open(m_log_file.c_str(), O_CREAT|O_WRONLY|O_APPEND, 0644); + m_fd = ::open(m_log_file.c_str(), O_CREAT|O_WRONLY|O_APPEND|O_CLOEXEC, 0644); if (m_fd >= 0 && (m_uid || m_gid)) { - int r = ::fchown(m_fd, m_uid, m_gid); - if (r < 0) { - r = -errno; - std::cerr << "failed to chown " << m_log_file << ": " << cpp_strerror(r) + if (::fchown(m_fd, m_uid, m_gid) < 0) { + int e = errno; + std::cerr << "failed to chown " << m_log_file << ": " << cpp_strerror(e) << std::endl; } } diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index fca027ddc2c5f..44b52817ca1ae 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -12086,7 +12086,7 @@ int MDCache::dump_cache(std::string_view fn, Formatter *f) dout(1) << "dump_cache to " << path << dendl; - fd = ::open(path, O_WRONLY|O_CREAT|O_EXCL, 0600); + fd = ::open(path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0600); if (fd < 0) { derr << "failed to open " << path << ": " << cpp_strerror(errno) << dendl; return errno; diff --git a/src/mon/LogMonitor.cc b/src/mon/LogMonitor.cc index 14ab4c8d110f6..8ca3bab0fc5a7 100644 --- a/src/mon/LogMonitor.cc +++ b/src/mon/LogMonitor.cc @@ -187,7 +187,7 @@ void LogMonitor::update_from_paxos(bool *need_bootstrap) << "' logging " << p->second.length() << " bytes" << dendl; string log_file = channels.get_log_file(p->first); - int fd = ::open(log_file.c_str(), O_WRONLY|O_APPEND|O_CREAT, 0600); + int fd = ::open(log_file.c_str(), O_WRONLY|O_APPEND|O_CREAT|O_CLOEXEC, 0600); if (fd < 0) { int err = -errno; dout(1) << "unable to write to '" << log_file << "' for channel '" diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index b03f68e727e01..c24b8ca436e18 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -5642,7 +5642,7 @@ int Monitor::write_default_keyring(bufferlist& bl) os << g_conf()->mon_data << "/keyring"; int err = 0; - int fd = ::open(os.str().c_str(), O_WRONLY|O_CREAT, 0600); + int fd = ::open(os.str().c_str(), O_WRONLY|O_CREAT|O_CLOEXEC, 0600); if (fd < 0) { err = -errno; dout(0) << __func__ << " failed to open " << os.str() diff --git a/src/mon/MonitorDBStore.h b/src/mon/MonitorDBStore.h index abc06f9ea4610..227b36e70a6a2 100644 --- a/src/mon/MonitorDBStore.h +++ b/src/mon/MonitorDBStore.h @@ -608,7 +608,7 @@ class MonitorDBStore if (!g_conf()->mon_debug_dump_json) { dump_fd_binary = ::open( g_conf()->mon_debug_dump_location.c_str(), - O_CREAT|O_APPEND|O_WRONLY, 0644); + O_CREAT|O_APPEND|O_WRONLY|O_CLOEXEC, 0644); if (dump_fd_binary < 0) { dump_fd_binary = -errno; derr << "Could not open log file, got " diff --git a/src/msg/Message.cc b/src/msg/Message.cc index 3785a01dc452d..92defd17d437e 100644 --- a/src/msg/Message.cc +++ b/src/msg/Message.cc @@ -264,7 +264,7 @@ void Message::encode(uint64_t features, int crcflags) snprintf(fn, sizeof(fn), ENCODE_STRINGIFY(ENCODE_DUMP) "/%s__%d.%x", abi::__cxa_demangle(typeid(*this).name(), 0, 0, &status), getpid(), i++); - int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0644); + int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC, 0644); if (fd >= 0) { bl.write_fd(fd); ::close(fd); diff --git a/src/msg/async/Event.cc b/src/msg/async/Event.cc index bb48622a226cc..c9c35bb58ab43 100644 --- a/src/msg/async/Event.cc +++ b/src/msg/async/Event.cc @@ -14,6 +14,7 @@ * */ +#include "include/compat.h" #include "common/errno.h" #include "Event.h" @@ -141,9 +142,10 @@ int EventCenter::init(int n, unsigned i, const std::string &t) return 0; int fds[2]; - if (pipe(fds) < 0) { - lderr(cct) << __func__ << " can't create notify pipe" << dendl; - return -errno; + if (pipe_cloexec(fds) < 0) { + int e = errno; + lderr(cct) << __func__ << " can't create notify pipe: " << cpp_strerror(e) << dendl; + return -e; } notify_receive_fd = fds[0]; diff --git a/src/msg/async/EventEpoll.cc b/src/msg/async/EventEpoll.cc index 17f3a294659c0..37b469736247f 100644 --- a/src/msg/async/EventEpoll.cc +++ b/src/msg/async/EventEpoll.cc @@ -15,6 +15,7 @@ */ #include "common/errno.h" +#include #include "EventEpoll.h" #define dout_subsys ceph_subsys_ms @@ -37,6 +38,14 @@ int EpollDriver::init(EventCenter *c, int nevent) << cpp_strerror(errno) << dendl; return -errno; } + if (::fcntl(epfd, F_SETFD, FD_CLOEXEC) == -1) { + int e = errno; + ::close(epfd); + lderr(cct) << __func__ << " unable to set cloexec: " + << cpp_strerror(e) << dendl; + + return -e; + } size = nevent; diff --git a/src/msg/async/PosixStack.cc b/src/msg/async/PosixStack.cc index 5dd8bb0bcae83..e2262d8886e58 100644 --- a/src/msg/async/PosixStack.cc +++ b/src/msg/async/PosixStack.cc @@ -30,6 +30,7 @@ #include "common/strtol.h" #include "common/dout.h" #include "msg/Messenger.h" +#include "include/compat.h" #include "include/sock_compat.h" #define dout_subsys ceph_subsys_ms @@ -185,12 +186,11 @@ int PosixServerSocketImpl::accept(ConnectedSocket *sock, const SocketOptions &op ceph_assert(sock); sockaddr_storage ss; socklen_t slen = sizeof(ss); - int sd = ::accept(_fd, (sockaddr*)&ss, &slen); + int sd = accept_cloexec(_fd, (sockaddr*)&ss, &slen); if (sd < 0) { return -errno; } - handler.set_close_on_exec(sd); int r = handler.set_nonblock(sd); if (r < 0) { ::close(sd); @@ -232,7 +232,6 @@ int PosixWorker::listen(entity_addr_t &sa, const SocketOptions &opt, return -errno; } - net.set_close_on_exec(listen_sd); r = net.set_socket_options(listen_sd, opt.nodelay, opt.rcbuf_size); if (r < 0) { ::close(listen_sd); diff --git a/src/msg/async/net_handler.cc b/src/msg/async/net_handler.cc index 99ca1f32d9279..4e9a2bcbec30b 100644 --- a/src/msg/async/net_handler.cc +++ b/src/msg/async/net_handler.cc @@ -22,8 +22,10 @@ #include #include "net_handler.h" -#include "common/errno.h" #include "common/debug.h" +#include "common/errno.h" +#include "include/compat.h" +#include "include/sock_compat.h" #define dout_subsys ceph_subsys_ms #undef dout_prefix @@ -36,7 +38,7 @@ int NetHandler::create_socket(int domain, bool reuse_addr) int s; int r = 0; - if ((s = ::socket(domain, SOCK_STREAM, 0)) == -1) { + if ((s = socket_cloexec(domain, SOCK_STREAM, 0)) == -1) { r = errno; lderr(cct) << __func__ << " couldn't create socket " << cpp_strerror(r) << dendl; return -r; @@ -82,22 +84,6 @@ int NetHandler::set_nonblock(int sd) return 0; } -void NetHandler::set_close_on_exec(int sd) -{ - int flags = fcntl(sd, F_GETFD, 0); - if (flags < 0) { - int r = errno; - lderr(cct) << __func__ << " fcntl(F_GETFD): " - << cpp_strerror(r) << dendl; - return; - } - if (fcntl(sd, F_SETFD, flags | FD_CLOEXEC)) { - int r = errno; - lderr(cct) << __func__ << " fcntl(F_SETFD): " - << cpp_strerror(r) << dendl; - } -} - int NetHandler::set_socket_options(int sd, bool nodelay, int size) { int r = 0; diff --git a/src/msg/async/net_handler.h b/src/msg/async/net_handler.h index c4fb73ee2914b..1904237724fe7 100644 --- a/src/msg/async/net_handler.h +++ b/src/msg/async/net_handler.h @@ -27,7 +27,6 @@ namespace ceph { int create_socket(int domain, bool reuse_addr=false); explicit NetHandler(CephContext *c): cct(c) {} int set_nonblock(int sd); - void set_close_on_exec(int sd); int set_socket_options(int sd, bool nodelay, int size); int connect(const entity_addr_t &addr, const entity_addr_t& bind_addr); diff --git a/src/msg/async/rdma/RDMAConnectedSocketImpl.cc b/src/msg/async/rdma/RDMAConnectedSocketImpl.cc index ebf328706c400..be3637c66818a 100644 --- a/src/msg/async/rdma/RDMAConnectedSocketImpl.cc +++ b/src/msg/async/rdma/RDMAConnectedSocketImpl.cc @@ -178,7 +178,6 @@ int RDMAConnectedSocketImpl::try_connect(const entity_addr_t& peer_addr, const S if (tcp_fd < 0) { return -errno; } - net.set_close_on_exec(tcp_fd); int r = net.set_socket_options(tcp_fd, opts.nodelay, opts.rcbuf_size); if (r < 0) { diff --git a/src/msg/async/rdma/RDMAServerSocketImpl.cc b/src/msg/async/rdma/RDMAServerSocketImpl.cc index b3bf46b92f312..1bdf5e716588b 100644 --- a/src/msg/async/rdma/RDMAServerSocketImpl.cc +++ b/src/msg/async/rdma/RDMAServerSocketImpl.cc @@ -17,6 +17,9 @@ #include "msg/async/net_handler.h" #include "RDMAStack.h" +#include "include/compat.h" +#include "include/sock_compat.h" + #define dout_subsys ceph_subsys_ms #undef dout_prefix #define dout_prefix *_dout << " RDMAServerSocketImpl " @@ -50,7 +53,6 @@ int RDMAServerSocketImpl::listen(entity_addr_t &sa, const SocketOptions &opt) if (rc < 0) { goto err; } - net.set_close_on_exec(server_setup_socket); rc = ::bind(server_setup_socket, sa.get_sockaddr(), sa.get_sockaddr_len()); if (rc < 0) { @@ -84,12 +86,11 @@ int RDMAServerSocketImpl::accept(ConnectedSocket *sock, const SocketOptions &opt sockaddr_storage ss; socklen_t slen = sizeof(ss); - int sd = ::accept(server_setup_socket, (sockaddr*)&ss, &slen); + int sd = accept_cloexec(server_setup_socket, (sockaddr*)&ss, &slen); if (sd < 0) { return -errno; } - net.set_close_on_exec(sd); int r = net.set_nonblock(sd); if (r < 0) { ::close(sd); diff --git a/src/msg/simple/Accepter.cc b/src/msg/simple/Accepter.cc index b2712f8f6216a..e647594079afb 100644 --- a/src/msg/simple/Accepter.cc +++ b/src/msg/simple/Accepter.cc @@ -13,6 +13,7 @@ */ #include "include/compat.h" +#include "include/sock_compat.h" #include #include #include @@ -41,37 +42,19 @@ * Accepter */ -static int set_close_on_exec(int fd) -{ - int flags = fcntl(fd, F_GETFD, 0); - if (flags < 0) { - return errno; - } - if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC)) { - return errno; - } - return 0; -} - int Accepter::create_selfpipe(int *pipe_rd, int *pipe_wr) { int selfpipe[2]; -#ifdef HAVE_PIPE2 - int ret = ::pipe2(selfpipe, (O_CLOEXEC|O_NONBLOCK)); -#else - int ret = ::pipe(selfpipe); - if (ret == 0) { - for (size_t i = 0; i < std::size(selfpipe); i++) { - int f = fcntl(selfpipe[i], F_GETFL); - ceph_assert(f != -1); - f = fcntl(selfpipe[i], F_SETFL, f | O_NONBLOCK); - ceph_assert(f != -1); - } - } -#endif - if (ret < 0 ) { + if (pipe_cloexec(selfpipe) < 0) { + int e = errno; lderr(msgr->cct) << __func__ << " unable to create the selfpipe: " - << cpp_strerror(errno) << dendl; - return -errno; + << cpp_strerror(e) << dendl; + return -e; + } + for (size_t i = 0; i < std::size(selfpipe); i++) { + int rc = fcntl(selfpipe[i], F_GETFL); + ceph_assert(rc != -1); + rc = fcntl(selfpipe[i], F_SETFL, rc | O_NONBLOCK); + ceph_assert(rc != -1); } *pipe_rd = selfpipe[0]; *pipe_wr = selfpipe[1]; @@ -97,19 +80,14 @@ int Accepter::bind(const entity_addr_t &bind_addr, const set& avoid_ports) } /* socket creation */ - listen_sd = ::socket(family, SOCK_STREAM, 0); - ldout(msgr->cct,10) << __func__ << " socket sd: " << listen_sd << dendl; + listen_sd = socket_cloexec(family, SOCK_STREAM, 0); if (listen_sd < 0) { + int e = errno; lderr(msgr->cct) << __func__ << " unable to create socket: " - << cpp_strerror(errno) << dendl; - return -errno; - } - - if (set_close_on_exec(listen_sd)) { - lderr(msgr->cct) << __func__ << " unable to set_close_exec(): " - << cpp_strerror(errno) << dendl; + << cpp_strerror(e) << dendl; + return -e; } - + ldout(msgr->cct,10) << __func__ << " socket sd: " << listen_sd << dendl; // use whatever user specified (if anything) entity_addr_t listen_addr = bind_addr; @@ -346,20 +324,16 @@ void *Accepter::entry() // accept sockaddr_storage ss; socklen_t slen = sizeof(ss); - int sd = ::accept(listen_sd, (sockaddr*)&ss, &slen); + int sd = accept_cloexec(listen_sd, (sockaddr*)&ss, &slen); if (sd >= 0) { - int r = set_close_on_exec(sd); - if (r) { - ldout(msgr->cct,1) << __func__ << " set_close_on_exec() failed " - << cpp_strerror(r) << dendl; - } errors = 0; ldout(msgr->cct,10) << __func__ << " incoming on sd " << sd << dendl; msgr->add_accept_pipe(sd); } else { + int e = errno; ldout(msgr->cct,0) << __func__ << " no incoming connection? sd = " << sd - << " errno " << errno << " " << cpp_strerror(errno) << dendl; + << " errno " << e << " " << cpp_strerror(e) << dendl; if (++errors > msgr->cct->_conf->ms_max_accept_failures) { lderr(msgr->cct) << "accetper has encoutered enough errors, just do ceph_abort()." << dendl; ceph_abort(); diff --git a/src/msg/simple/Pipe.cc b/src/msg/simple/Pipe.cc index 434a8e67854c2..0b59bdcfaf7c4 100644 --- a/src/msg/simple/Pipe.cc +++ b/src/msg/simple/Pipe.cc @@ -34,6 +34,7 @@ #include "auth/cephx/CephxProtocol.h" #include "auth/AuthSessionHandler.h" +#include "include/compat.h" #include "include/sock_compat.h" #include "include/random.h" @@ -1022,10 +1023,11 @@ int Pipe::connect() ::close(sd); // create socket? - sd = ::socket(peer_addr.get_family(), SOCK_STREAM, 0); + sd = socket_cloexec(peer_addr.get_family(), SOCK_STREAM, 0); if (sd < 0) { - rc = -errno; - lderr(msgr->cct) << "connect couldn't create socket " << cpp_strerror(rc) << dendl; + int e = errno; + lderr(msgr->cct) << "connect couldn't create socket " << cpp_strerror(e) << dendl; + rc = -e; goto fail; } diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 70233809b59f5..fa1aa01b4238a 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -4364,7 +4364,7 @@ int BlueStore::_open_path() return -EINVAL; } ceph_assert(path_fd < 0); - path_fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_DIRECTORY)); + path_fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_DIRECTORY|O_CLOEXEC)); if (path_fd < 0) { int r = -errno; derr << __func__ << " unable to open " << path << ": " << cpp_strerror(r) @@ -4393,7 +4393,7 @@ int BlueStore::_write_bdev_label(CephContext *cct, z.zero(); bl.append(std::move(z)); - int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_WRONLY)); + int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_WRONLY|O_CLOEXEC)); if (fd < 0) { fd = -errno; derr << __func__ << " failed to open " << path << ": " << cpp_strerror(fd) @@ -4420,7 +4420,7 @@ int BlueStore::_read_bdev_label(CephContext* cct, string path, bluestore_bdev_label_t *label) { dout(10) << __func__ << dendl; - int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY)); + int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY|O_CLOEXEC)); if (fd < 0) { fd = -errno; derr << __func__ << " failed to open " << path << ": " << cpp_strerror(fd) @@ -4743,7 +4743,7 @@ void BlueStore::_close_alloc() int BlueStore::_open_fsid(bool create) { ceph_assert(fsid_fd < 0); - int flags = O_RDWR; + int flags = O_RDWR|O_CLOEXEC; if (create) flags |= O_CREAT; fsid_fd = ::openat(path_fd, "fsid", flags, 0644); @@ -5474,7 +5474,7 @@ int BlueStore::_setup_block_symlink_or_file( dout(20) << __func__ << " name " << name << " path " << epath << " size " << size << " create=" << (int)create << dendl; int r = 0; - int flags = O_RDWR; + int flags = O_RDWR|O_CLOEXEC; if (create) flags |= O_CREAT; if (epath.length()) { diff --git a/src/os/bluestore/KernelDevice.cc b/src/os/bluestore/KernelDevice.cc index 97f3bd074cae3..f6ba2ce37d814 100644 --- a/src/os/bluestore/KernelDevice.cc +++ b/src/os/bluestore/KernelDevice.cc @@ -68,13 +68,13 @@ int KernelDevice::open(const string& p) int r = 0; dout(1) << __func__ << " path " << path << dendl; - fd_direct = ::open(path.c_str(), O_RDWR | O_DIRECT); + fd_direct = ::open(path.c_str(), O_RDWR | O_DIRECT | O_CLOEXEC); if (fd_direct < 0) { r = -errno; derr << __func__ << " open got: " << cpp_strerror(r) << dendl; return r; } - fd_buffered = ::open(path.c_str(), O_RDWR); + fd_buffered = ::open(path.c_str(), O_RDWR | O_CLOEXEC); if (fd_buffered < 0) { r = -errno; derr << __func__ << " open got: " << cpp_strerror(r) << dendl; diff --git a/src/os/bluestore/NVMEDevice.cc b/src/os/bluestore/NVMEDevice.cc index 563d3c7586c4e..b5288ea42e8d6 100644 --- a/src/os/bluestore/NVMEDevice.cc +++ b/src/os/bluestore/NVMEDevice.cc @@ -740,7 +740,7 @@ int NVMEDevice::open(const string& p) dout(1) << __func__ << " path " << p << dendl; string serial_number; - int fd = ::open(p.c_str(), O_RDONLY); + int fd = ::open(p.c_str(), O_RDONLY | O_CLOEXEC); if (fd < 0) { r = -errno; derr << __func__ << " unable to open " << p << ": " << cpp_strerror(r) diff --git a/src/os/bluestore/PMEMDevice.cc b/src/os/bluestore/PMEMDevice.cc index 81d880b85d834..a472751a3931a 100644 --- a/src/os/bluestore/PMEMDevice.cc +++ b/src/os/bluestore/PMEMDevice.cc @@ -61,7 +61,7 @@ int PMEMDevice::open(const string& p) int r = 0; dout(1) << __func__ << " path " << path << dendl; - fd = ::open(path.c_str(), O_RDWR); + fd = ::open(path.c_str(), O_RDWR | O_CLOEXEC); if (fd < 0) { r = -errno; derr << __func__ << " open got: " << cpp_strerror(r) << dendl; diff --git a/src/os/bluestore/bluestore_tool.cc b/src/os/bluestore/bluestore_tool.cc index b3209fbaf0d96..0c4ed2fcbae5a 100644 --- a/src/os/bluestore/bluestore_tool.cc +++ b/src/os/bluestore/bluestore_tool.cc @@ -372,7 +372,7 @@ int main(int argc, char **argv) v += "]\nkey = " + i->second; } v += "\n"; - int fd = ::open(p.c_str(), O_CREAT|O_TRUNC|O_WRONLY, 0600); + int fd = ::open(p.c_str(), O_CREAT|O_TRUNC|O_WRONLY|O_CLOEXEC, 0600); if (fd < 0) { cerr << "error writing " << p << ": " << cpp_strerror(errno) << std::endl; @@ -550,7 +550,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } string path = out_dir + "/" + dir + "/" + file; - int fd = ::open(path.c_str(), O_CREAT|O_WRONLY|O_TRUNC, 0644); + int fd = ::open(path.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC, 0644); if (fd < 0) { r = -errno; cerr << "open " << path << " failed: " << cpp_strerror(r) << std::endl; diff --git a/src/os/filestore/BtrfsFileStoreBackend.cc b/src/os/filestore/BtrfsFileStoreBackend.cc index 4f1c60db028f7..2ff2000d70916 100644 --- a/src/os/filestore/BtrfsFileStoreBackend.cc +++ b/src/os/filestore/BtrfsFileStoreBackend.cc @@ -69,7 +69,7 @@ int BtrfsFileStoreBackend::detect_features() // clone_range? if (m_filestore_btrfs_clone_range) { - int fd = ::openat(get_basedir_fd(), "clone_range_test", O_CREAT|O_WRONLY, 0600); + int fd = ::openat(get_basedir_fd(), "clone_range_test", O_CREAT|O_WRONLY|O_CLOEXEC, 0600); if (fd >= 0) { if (::unlinkat(get_basedir_fd(), "clone_range_test", 0) < 0) { r = -errno; @@ -108,7 +108,7 @@ int BtrfsFileStoreBackend::detect_features() r = -errno; dout(0) << "detect_feature: failed to create simple subvolume " << vol_args.name << ": " << cpp_strerror(r) << dendl; } - int srcfd = ::openat(get_basedir_fd(), vol_args.name, O_RDONLY); + int srcfd = ::openat(get_basedir_fd(), vol_args.name, O_RDONLY|O_CLOEXEC); if (srcfd < 0) { r = -errno; dout(0) << "detect_feature: failed to open " << vol_args.name << ": " << cpp_strerror(r) << dendl; @@ -445,7 +445,7 @@ int BtrfsFileStoreBackend::rollback_to(const string& name) snprintf(s, sizeof(s), "%s/%s", get_basedir_path().c_str(), name.c_str()); // roll back - vol_args.fd = ::open(s, O_RDONLY); + vol_args.fd = ::open(s, O_RDONLY|O_CLOEXEC); if (vol_args.fd < 0) { ret = -errno; dout(0) << "rollback_to: error opening '" << s << "': " << cpp_strerror(ret) << dendl; diff --git a/src/os/filestore/FileJournal.cc b/src/os/filestore/FileJournal.cc index 98bed0dc298f3..64a754569ae90 100644 --- a/src/os/filestore/FileJournal.cc +++ b/src/os/filestore/FileJournal.cc @@ -71,7 +71,7 @@ int FileJournal::_open(bool forwrite, bool create) << cpp_strerror(err) << dendl; } } - fd = TEMP_FAILURE_RETRY(::open(fn.c_str(), flags, 0644)); + fd = TEMP_FAILURE_RETRY(::open(fn.c_str(), flags|O_CLOEXEC, 0644)); if (fd < 0) { int err = errno; dout(2) << "FileJournal::_open unable to open journal " diff --git a/src/os/filestore/FileStore.cc b/src/os/filestore/FileStore.cc index 4040c7f006aa6..102eab53d5475 100644 --- a/src/os/filestore/FileStore.cc +++ b/src/os/filestore/FileStore.cc @@ -294,7 +294,7 @@ int FileStore::lfn_open(const coll_t& cid, goto fail; } - r = ::open((*path)->path(), flags, 0644); + r = ::open((*path)->path(), flags|O_CLOEXEC, 0644); if (r < 0) { r = -errno; dout(10) << "error opening file " << (*path)->path() << " with flags=" @@ -866,7 +866,7 @@ int FileStore::mkfs() uuid_d old_omap_fsid; dout(1) << "mkfs in " << basedir << dendl; - basedir_fd = ::open(basedir.c_str(), O_RDONLY); + basedir_fd = ::open(basedir.c_str(), O_RDONLY|O_CLOEXEC); if (basedir_fd < 0) { ret = -errno; derr << __FUNC__ << ": failed to open base dir " << basedir << ": " << cpp_strerror(ret) << dendl; @@ -875,7 +875,7 @@ int FileStore::mkfs() // open+lock fsid snprintf(fsid_fn, sizeof(fsid_fn), "%s/fsid", basedir.c_str()); - fsid_fd = ::open(fsid_fn, O_RDWR|O_CREAT, 0644); + fsid_fd = ::open(fsid_fn, O_RDWR|O_CREAT|O_CLOEXEC, 0644); if (fsid_fd < 0) { ret = -errno; derr << __FUNC__ << ": failed to open " << fsid_fn << ": " << cpp_strerror(ret) << dendl; @@ -990,7 +990,7 @@ int FileStore::mkfs() if (backend->can_checkpoint()) { // create snap_1 too - current_fd = ::open(current_fn.c_str(), O_RDONLY); + current_fd = ::open(current_fn.c_str(), O_RDONLY|O_CLOEXEC); ceph_assert(current_fd >= 0); char s[NAME_MAX]; snprintf(s, sizeof(s), COMMIT_SNAP_ITEM, 1ull); @@ -1015,7 +1015,7 @@ int FileStore::mkfs() int omap_fsid_fd; char omap_fsid_fn[PATH_MAX]; snprintf(omap_fsid_fn, sizeof(omap_fsid_fn), "%s/osd_uuid", omap_dir.c_str()); - omap_fsid_fd = ::open(omap_fsid_fn, O_RDWR|O_CREAT, 0644); + omap_fsid_fd = ::open(omap_fsid_fn, O_RDWR|O_CREAT|O_CLOEXEC, 0644); if (omap_fsid_fd < 0) { ret = -errno; derr << __FUNC__ << ": failed to open " << omap_fsid_fn << ": " << cpp_strerror(ret) << dendl; @@ -1091,7 +1091,7 @@ int FileStore::mkjournal() int ret; char fn[PATH_MAX]; snprintf(fn, sizeof(fn), "%s/fsid", basedir.c_str()); - int fd = ::open(fn, O_RDONLY, 0644); + int fd = ::open(fn, O_RDONLY|O_CLOEXEC, 0644); if (fd < 0) { int err = errno; derr << __FUNC__ << ": open error: " << cpp_strerror(err) << dendl; @@ -1173,7 +1173,7 @@ bool FileStore::test_mount_in_use() // verify fs isn't in use - fsid_fd = ::open(fn, O_RDWR, 0644); + fsid_fd = ::open(fn, O_RDWR|O_CLOEXEC, 0644); if (fsid_fd < 0) return 0; // no fsid, ok. bool inuse = lock_fsid() < 0; @@ -1188,7 +1188,7 @@ bool FileStore::is_rotational() if (backend) { rotational = backend->is_rotational(); } else { - int fd = ::open(basedir.c_str(), O_RDONLY); + int fd = ::open(basedir.c_str(), O_RDONLY|O_CLOEXEC); if (fd < 0) return true; struct statfs st; @@ -1212,7 +1212,7 @@ bool FileStore::is_journal_rotational() if (backend) { journal_rotational = backend->is_journal_rotational(); } else { - int fd = ::open(journalpath.c_str(), O_RDONLY); + int fd = ::open(journalpath.c_str(), O_RDONLY|O_CLOEXEC); if (fd < 0) return true; struct statfs st; @@ -1274,7 +1274,7 @@ int FileStore::_detect_fs() int x = rand(); int y = x+1; snprintf(fn, sizeof(fn), "%s/xattr_test", basedir.c_str()); - int tmpfd = ::open(fn, O_CREAT|O_WRONLY|O_TRUNC, 0700); + int tmpfd = ::open(fn, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC, 0700); if (tmpfd < 0) { int ret = -errno; derr << __FUNC__ << ": unable to create " << fn << ": " << cpp_strerror(ret) << dendl; @@ -1451,7 +1451,7 @@ int FileStore::upgrade() int FileStore::read_op_seq(uint64_t *seq) { - int op_fd = ::open(current_op_seq_fn.c_str(), O_CREAT|O_RDWR, 0644); + int op_fd = ::open(current_op_seq_fn.c_str(), O_CREAT|O_RDWR|O_CLOEXEC, 0644); if (op_fd < 0) { int r = -errno; ceph_assert(!m_filestore_fail_eio || r != -EIO); @@ -1507,7 +1507,7 @@ int FileStore::mount() // get fsid snprintf(buf, sizeof(buf), "%s/fsid", basedir.c_str()); - fsid_fd = ::open(buf, O_RDWR, 0644); + fsid_fd = ::open(buf, O_RDWR|O_CLOEXEC, 0644); if (fsid_fd < 0) { ret = -errno; derr << __FUNC__ << ": error opening '" << buf << "': " @@ -1570,7 +1570,7 @@ int FileStore::mount() } // open some dir handles - basedir_fd = ::open(basedir.c_str(), O_RDONLY); + basedir_fd = ::open(basedir.c_str(), O_RDONLY|O_CLOEXEC); if (basedir_fd < 0) { ret = -errno; derr << __FUNC__ << ": failed to open " << basedir << ": " @@ -1680,7 +1680,7 @@ int FileStore::mount() } initial_op_seq = 0; - current_fd = ::open(current_fn.c_str(), O_RDONLY); + current_fd = ::open(current_fn.c_str(), O_RDONLY|O_CLOEXEC); if (current_fd < 0) { ret = -errno; derr << __FUNC__ << ": error opening: " << current_fn << ": " << cpp_strerror(ret) << dendl; @@ -1731,7 +1731,7 @@ int FileStore::mount() } else { int omap_fsid_fd; // if osd_uuid exists, compares osd_uuid with fsid - omap_fsid_fd = ::open(omap_fsid_buf, O_RDONLY, 0644); + omap_fsid_fd = ::open(omap_fsid_buf, O_RDONLY|O_CLOEXEC, 0644); if (omap_fsid_fd < 0) { ret = -errno; derr << __FUNC__ << ": error opening '" << omap_fsid_buf << "': " @@ -2457,7 +2457,7 @@ void FileStore::_set_global_replay_guard(const coll_t& cid, char fn[PATH_MAX]; get_cdir(cid, fn, sizeof(fn)); - int fd = ::open(fn, O_RDONLY); + int fd = ::open(fn, O_RDONLY|O_CLOEXEC); if (fd < 0) { int err = errno; derr << __FUNC__ << ": " << cid << " error " << cpp_strerror(err) << dendl; @@ -2491,7 +2491,7 @@ int FileStore::_check_global_replay_guard(const coll_t& cid, { char fn[PATH_MAX]; get_cdir(cid, fn, sizeof(fn)); - int fd = ::open(fn, O_RDONLY); + int fd = ::open(fn, O_RDONLY|O_CLOEXEC); if (fd < 0) { dout(10) << __FUNC__ << ": " << cid << " dne" << dendl; return 1; // if collection does not exist, there is no guard, and we can replay. @@ -2523,7 +2523,7 @@ void FileStore::_set_replay_guard(const coll_t& cid, { char fn[PATH_MAX]; get_cdir(cid, fn, sizeof(fn)); - int fd = ::open(fn, O_RDONLY); + int fd = ::open(fn, O_RDONLY|O_CLOEXEC); if (fd < 0) { int err = errno; derr << __FUNC__ << ": " << cid << " error " << cpp_strerror(err) << dendl; @@ -2582,7 +2582,7 @@ void FileStore::_close_replay_guard(const coll_t& cid, { char fn[PATH_MAX]; get_cdir(cid, fn, sizeof(fn)); - int fd = ::open(fn, O_RDONLY); + int fd = ::open(fn, O_RDONLY|O_CLOEXEC); if (fd < 0) { int err = errno; derr << __FUNC__ << ": " << cid << " error " << cpp_strerror(err) << dendl; @@ -2655,7 +2655,7 @@ int FileStore::_check_replay_guard(const coll_t& cid, const SequencerPosition& s char fn[PATH_MAX]; get_cdir(cid, fn, sizeof(fn)); - int fd = ::open(fn, O_RDONLY); + int fd = ::open(fn, O_RDONLY|O_CLOEXEC); if (fd < 0) { dout(10) << __FUNC__ << ": " << cid << " dne" << dendl; return 1; // if collection does not exist, there is no guard, and we can replay. @@ -3895,10 +3895,10 @@ int FileStore::_do_copy_range(int from, int to, uint64_t srcoff, uint64_t len, u #ifdef CEPH_HAVE_SPLICE if (backend->has_splice()) { int pipefd[2]; - if (pipe(pipefd) < 0) { - r = -errno; - derr << " pipe " << " got " << cpp_strerror(r) << dendl; - return r; + if (pipe_cloexec(pipefd) < 0) { + int e = errno; + derr << " pipe " << " got " << cpp_strerror(e) << dendl; + return -e; } loff_t dstpos = dstoff; @@ -5028,7 +5028,7 @@ int FileStore::_collection_set_bits(const coll_t& c, int bits) char n[PATH_MAX]; int r; int32_t v = bits; - int fd = ::open(fn, O_RDONLY); + int fd = ::open(fn, O_RDONLY|O_CLOEXEC); if (fd < 0) { r = -errno; goto out; @@ -5049,7 +5049,7 @@ int FileStore::collection_bits(CollectionHandle& ch) int r; char n[PATH_MAX]; int32_t bits; - int fd = ::open(fn, O_RDONLY); + int fd = ::open(fn, O_RDONLY|O_CLOEXEC); if (fd < 0) { bits = r = -errno; goto out; diff --git a/src/os/filestore/GenericFileStoreBackend.cc b/src/os/filestore/GenericFileStoreBackend.cc index 02f45864fc7a1..0299567bc36c1 100644 --- a/src/os/filestore/GenericFileStoreBackend.cc +++ b/src/os/filestore/GenericFileStoreBackend.cc @@ -70,7 +70,7 @@ GenericFileStoreBackend::GenericFileStoreBackend(FileStore *fs): { // NOTE: the below won't work on btrfs; we'll assume rotational. string fn = get_basedir_path(); - int fd = ::open(fn.c_str(), O_RDONLY); + int fd = ::open(fn.c_str(), O_RDONLY|O_CLOEXEC); if (fd < 0) { return; } @@ -91,7 +91,7 @@ GenericFileStoreBackend::GenericFileStoreBackend(FileStore *fs): { // NOTE: the below won't work on btrfs; we'll assume rotational. string fn = get_journal_path(); - int fd = ::open(fn.c_str(), O_RDONLY); + int fd = ::open(fn.c_str(), O_RDONLY|O_CLOEXEC); if (fd < 0) { return; } @@ -115,7 +115,7 @@ int GenericFileStoreBackend::detect_features() char fn[PATH_MAX]; snprintf(fn, sizeof(fn), "%s/fiemap_test", get_basedir_path().c_str()); - int fd = ::open(fn, O_CREAT|O_RDWR|O_TRUNC, 0644); + int fd = ::open(fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0644); if (fd < 0) { fd = -errno; derr << "detect_features: unable to create " << fn << ": " << cpp_strerror(fd) << dendl; @@ -218,9 +218,10 @@ int GenericFileStoreBackend::detect_features() int pipefd[2]; loff_t off_in = 0; int r; - if ((r = pipe(pipefd)) < 0) - dout(0) << "detect_features: splice pipe met error " << cpp_strerror(errno) << dendl; - else { + if (pipe_cloexec(pipefd) < 0) { + int e = errno; + dout(0) << "detect_features: splice pipe met error " << cpp_strerror(e) << dendl; + } else { lseek(fd, 0, SEEK_SET); r = splice(fd, &off_in, pipefd[1], NULL, 10, 0); if (!(r < 0 && errno == EINVAL)) { diff --git a/src/os/filestore/LFNIndex.cc b/src/os/filestore/LFNIndex.cc index 9dfebeb951c3c..a35577877d0c4 100644 --- a/src/os/filestore/LFNIndex.cc +++ b/src/os/filestore/LFNIndex.cc @@ -169,7 +169,7 @@ int LFNIndex::collection_list_partial(const ghobject_t &start, int LFNIndex::fsync_dir(const vector &path) { maybe_inject_failure(); - int fd = ::open(get_full_path_subdir(path).c_str(), O_RDONLY); + int fd = ::open(get_full_path_subdir(path).c_str(), O_RDONLY|O_CLOEXEC); if (fd < 0) return -errno; FDCloser f(fd); @@ -897,7 +897,7 @@ int LFNIndex::lfn_unlink(const vector &path, } } string full_path = get_full_path(path, mangled_name); - int fd = ::open(full_path.c_str(), O_RDONLY); + int fd = ::open(full_path.c_str(), O_RDONLY|O_CLOEXEC); if (fd < 0) return -errno; FDCloser f(fd); diff --git a/src/os/kstore/KStore.cc b/src/os/kstore/KStore.cc index a915bd54654cc..616ca1b6a25ee 100644 --- a/src/os/kstore/KStore.cc +++ b/src/os/kstore/KStore.cc @@ -693,7 +693,7 @@ void KStore::_shutdown_logger() int KStore::_open_path() { ceph_assert(path_fd < 0); - path_fd = ::open(path.c_str(), O_DIRECTORY); + path_fd = ::open(path.c_str(), O_DIRECTORY|O_CLOEXEC); if (path_fd < 0) { int r = -errno; derr << __func__ << " unable to open " << path << ": " << cpp_strerror(r) diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index 0002e5054548e..b345f6691e993 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -2,6 +2,7 @@ // vim: ts=8 sw=2 smarttab #include "include/compat.h" +#include "common/errno.h" #include @@ -1043,21 +1044,19 @@ int RGWHTTPManager::set_request_state(RGWHTTPClient *client, RGWHTTPRequestSetSt int RGWHTTPManager::start() { - int r = pipe(thread_pipe); - if (r < 0) { - r = -errno; - ldout(cct, 0) << "ERROR: pipe() returned errno=" << r << dendl; - return r; + if (pipe_cloexec(thread_pipe) < 0) { + int e = errno; + ldout(cct, 0) << "ERROR: pipe(): " << cpp_strerror(e) << dendl; + return -e; } // enable non-blocking reads - r = ::fcntl(thread_pipe[0], F_SETFL, O_NONBLOCK); - if (r < 0) { - r = -errno; - ldout(cct, 0) << "ERROR: fcntl() returned errno=" << r << dendl; + if (::fcntl(thread_pipe[0], F_SETFL, O_NONBLOCK) < 0) { + int e = errno; + ldout(cct, 0) << "ERROR: fcntl(): " << cpp_strerror(e) << dendl; TEMP_FAILURE_RETRY(::close(thread_pipe[0])); TEMP_FAILURE_RETRY(::close(thread_pipe[1])); - return r; + return -e; } #ifdef HAVE_CURL_MULTI_WAIT diff --git a/src/test/objectstore/test_bluefs.cc b/src/test/objectstore/test_bluefs.cc index 28e67aa032e28..60f31efee9b4f 100644 --- a/src/test/objectstore/test_bluefs.cc +++ b/src/test/objectstore/test_bluefs.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "global/global_init.h" #include "common/ceph_argparse.h" @@ -33,8 +34,8 @@ string get_temp_bdev(uint64_t size) std::unique_ptr gen_buffer(uint64_t size) { std::unique_ptr buffer = std::make_unique(size); - boost::random::random_device rand; - rand.generate(buffer.get(), buffer.get() + size); + std::independent_bits_engine e; + std::generate(buffer.get(), buffer.get()+size, std::ref(e)); return buffer; } -- 2.39.5