diff --git a/examples/platforms/posix/flash.c b/examples/platforms/posix/flash.c index 681b428ca..2df47dff8 100644 --- a/examples/platforms/posix/flash.c +++ b/examples/platforms/posix/flash.c @@ -78,7 +78,7 @@ otError utilsFlashInit(void) create = true; } - sFlashFd = open(fileName, O_RDWR | O_CREAT, 0600); + sFlashFd = open(fileName, O_RDWR | O_CREAT | O_CLOEXEC, 0600); lseek(sFlashFd, 0, SEEK_SET); otEXPECT_ACTION(sFlashFd >= 0, error = OT_ERROR_FAILED); diff --git a/src/posix/platform/hdlc_interface.cpp b/src/posix/platform/hdlc_interface.cpp index a0b309c73..c6188f6a5 100644 --- a/src/posix/platform/hdlc_interface.cpp +++ b/src/posix/platform/hdlc_interface.cpp @@ -320,7 +320,7 @@ int HdlcInterface::OpenFile(const char *aFile, const char *aConfig) int fd = -1; int rval = 0; - fd = open(aFile, O_RDWR | O_NOCTTY | O_NONBLOCK); + fd = open(aFile, O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC); if (fd == -1) { perror("open uart failed"); @@ -480,8 +480,9 @@ exit: #if OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE int HdlcInterface::ForkPty(const char *aCommand, const char *aArguments) { - int fd = -1; - int pid = -1; + int fd = -1; + int pid = -1; + int rval = -1; { struct termios tios; @@ -490,54 +491,30 @@ int HdlcInterface::ForkPty(const char *aCommand, const char *aArguments) cfmakeraw(&tios); tios.c_cflag = CS8 | HUPCL | CREAD | CLOCAL; - pid = forkpty(&fd, NULL, &tios, NULL); - VerifyOrExit(pid >= 0); + VerifyOrExit((pid = forkpty(&fd, NULL, &tios, NULL)) != -1, perror("forkpty()")); } if (0 == pid) { - const int kMaxCommand = 255; - char cmd[kMaxCommand]; - int rval; - struct rlimit limit; - - rval = getrlimit(RLIMIT_NOFILE, &limit); - rval = setenv("SHELL", SOCKET_UTILS_DEFAULT_SHELL, 0); - - VerifyOrExit(rval == 0, perror("setenv failed")); - - // Close all file descriptors larger than STDERR_FILENO. - for (rlim_t i = (STDERR_FILENO + 1); i < limit.rlim_cur; i++) - { - close(static_cast(i)); - } + const int kMaxCommand = 255; + char cmd[kMaxCommand]; rval = snprintf(cmd, sizeof(cmd), "exec %s %s", aCommand, aArguments); VerifyOrExit(rval > 0 && static_cast(rval) < sizeof(cmd), - otLogCritPlat("NCP file and configuration is too long!")); + fprintf(stderr, "NCP file and configuration is too long!"); + rval = -1); - execl(getenv("SHELL"), getenv("SHELL"), "-c", cmd, NULL); - perror("open pty failed"); - exit(OT_EXIT_INVALID_ARGUMENTS); + VerifyOrExit((rval = execl(SOCKET_UTILS_DEFAULT_SHELL, SOCKET_UTILS_DEFAULT_SHELL, "-c", cmd, NULL)) != -1, + perror("execl(OT_RCP)")); } else { - int rval = fcntl(fd, F_GETFL); - - if (rval != -1) - { - rval = fcntl(fd, F_SETFL, rval | O_NONBLOCK); - } - - if (rval == -1) - { - perror("set nonblock failed"); - close(fd); - fd = -1; - } + VerifyOrExit((rval = fcntl(fd, F_GETFL)) != -1, perror("fcntl(F_GETFL)")); + VerifyOrExit((rval = fcntl(fd, F_SETFL, rval | O_NONBLOCK | O_CLOEXEC)) != -1, perror("fcntl(F_SETFL)")); } exit: + VerifyOrDie(rval == 0, OT_EXIT_FAILURE); return fd; } #endif // OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE diff --git a/src/posix/platform/logging.c b/src/posix/platform/logging.c index 3cfacf4fc..8e47132ed 100644 --- a/src/posix/platform/logging.c +++ b/src/posix/platform/logging.c @@ -46,7 +46,7 @@ void platformLoggingInit(const char *aName) #if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \ (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL) - openlog(aName, LOG_PID, LOG_USER); + openlog(aName, LOG_PID, LOG_DAEMON); setlogmask(setlogmask(0) & LOG_UPTO(LOG_DEBUG)); #else diff --git a/src/posix/platform/misc.c b/src/posix/platform/misc.c index 1b3245294..e0a67ca56 100644 --- a/src/posix/platform/misc.c +++ b/src/posix/platform/misc.c @@ -30,11 +30,14 @@ #include "platform-posix.h" #include +#include #include +#include #include #include +#include "code_utils.h" #include "openthread-system.h" #include "common/logging.hpp" @@ -123,3 +126,27 @@ void VerifyOrDie(bool aCondition, int aExitCode) exit(aExitCode); } } + +int SocketWithCloseExec(int aDomain, int aType, int aProtocol) +{ + int rval = 0; + int fd = -1; + +#ifdef __APPLE__ + otEXPECT_ACTION((fd = socket(aDomain, aType, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)")); + + otEXPECT_ACTION((rval = fcntl(fd, F_GETFD, 0)) != -1, perror("fcntl(F_GETFD)")); + otEXPECT_ACTION((rval = fcntl(fd, F_SETFD, rval | FD_CLOEXEC)) != -1, perror("fcntl(F_SETFD)")); +#else + otEXPECT_ACTION((fd = socket(aDomain, aType | SOCK_CLOEXEC, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)")); +#endif + +exit: + if (rval == -1 && fd != -1) + { + VerifyOrDie(close(fd) == 0, OT_EXIT_FAILURE); + fd = -1; + } + + return fd; +} diff --git a/src/posix/platform/netif.cpp b/src/posix/platform/netif.cpp index e5caebd49..a44772a9b 100644 --- a/src/posix/platform/netif.cpp +++ b/src/posix/platform/netif.cpp @@ -386,8 +386,8 @@ void platformNetifInit(otInstance *aInstance) { struct ifreq ifr; - sIpFd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP); - VerifyOrExit(sIpFd > 0); + sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP); + VerifyOrExit(sIpFd >= 0); sNetlinkFd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); VerifyOrExit(sNetlinkFd > 0); @@ -403,7 +403,7 @@ void platformNetifInit(otInstance *aInstance) VerifyOrExit(bind(sNetlinkFd, reinterpret_cast(&sa), sizeof(sa)) == 0); } - sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR); + sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC); VerifyOrExit(sTunFd > 0, otLogCritPlat("Unable to open tun device %s", OPENTHREAD_POSIX_TUN_DEVICE)); memset(&ifr, 0, sizeof(ifr)); diff --git a/src/posix/platform/platform-posix.h b/src/posix/platform/platform-posix.h index 7b9c30e81..f1526060f 100644 --- a/src/posix/platform/platform-posix.h +++ b/src/posix/platform/platform-posix.h @@ -399,6 +399,20 @@ void VerifyOrDie(bool aCondition, int aExitCode); */ void SuccessOrDie(otError aError); +/** + * This function creates a socket with SOCK_CLOEXEC flag set. + * + * @param[in] aDomain The communication domain. + * @param[in] aType The semantics of communication. + * @param[in] aProtocol The protocol to use. + * + * @returns The file descriptor of the created socket. + * + * @retval -1 Failed to create socket. + * + */ +int SocketWithCloseExec(int aDomain, int aType, int aProtocol); + #ifdef __cplusplus } #endif diff --git a/src/posix/platform/settings.cpp b/src/posix/platform/settings.cpp index 0abba6a4b..d8d78b629 100644 --- a/src/posix/platform/settings.cpp +++ b/src/posix/platform/settings.cpp @@ -77,7 +77,7 @@ static int swapOpen(void) int fd; getSettingsFileName(fileName, true); - fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 0600); + fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0600); VerifyOrDie(fd != -1); return fd; @@ -152,7 +152,7 @@ void otPlatSettingsInit(otInstance *aInstance) char fileName[kMaxFileNameSize]; getSettingsFileName(fileName, false); - sSettingsFd = open(fileName, O_RDWR | O_CREAT, 0600); + sSettingsFd = open(fileName, O_RDWR | O_CREAT | O_CLOEXEC, 0600); } VerifyOrDie(sSettingsFd != -1); diff --git a/src/posix/platform/sim.c b/src/posix/platform/sim.c index 61eedc1db..72fb9b3e5 100644 --- a/src/posix/platform/sim.c +++ b/src/posix/platform/sim.c @@ -84,7 +84,7 @@ void otSimInit(void) sockaddr.sin_port = htons(kBasePort + sPortOffset + sNodeId); sockaddr.sin_addr.s_addr = INADDR_ANY; - sSockFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + sSockFd = SocketWithCloseExec(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sSockFd == -1) { diff --git a/src/posix/platform/uart.c b/src/posix/platform/uart.c index 78942b509..a4d7678a2 100644 --- a/src/posix/platform/uart.c +++ b/src/posix/platform/uart.c @@ -60,17 +60,6 @@ static bool sEnabled = false; static const uint8_t *sWriteBuffer = NULL; static uint16_t sWriteLength = 0; -#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON -static void set_flag_cloexec(int a_fd) -{ - int ret = fcntl(a_fd, F_GETFD, 0); - VerifyOrDie(ret != -1, OT_EXIT_FAILURE); - ret |= FD_CLOEXEC; - ret = fcntl(a_fd, F_SETFD, ret); - VerifyOrDie(ret != -1, OT_EXIT_FAILURE); -} -#endif // OPENTHREAD_ENABLE_POSIX_APP_DAEMON - otError otPlatUartEnable(void) { otError error = OT_ERROR_NONE; @@ -78,17 +67,14 @@ otError otPlatUartEnable(void) struct sockaddr_un sockname; int ret; - sUartSocket = socket(AF_UNIX, SOCK_STREAM, 0); + sUartSocket = SocketWithCloseExec(AF_UNIX, SOCK_STREAM, 0); if (sUartSocket == -1) { - perror("socket"); exit(OT_EXIT_FAILURE); } - set_flag_cloexec(sUartSocket); - - sUartLock = open(OPENTHREAD_POSIX_APP_SOCKET_LOCK, O_CREAT | O_RDONLY, 0600); + sUartLock = open(OPENTHREAD_POSIX_APP_SOCKET_LOCK, O_CREAT | O_RDONLY | O_CLOEXEC, 0600); if (sUartLock == -1) { @@ -96,8 +82,6 @@ otError otPlatUartEnable(void) exit(OT_EXIT_FAILURE); } - set_flag_cloexec(sUartLock); - if (flock(sUartLock, LOCK_EX | LOCK_NB) == -1) { perror("flock"); @@ -290,7 +274,10 @@ void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, co } else if (rval <= 0) { - perror("UART read"); + if (rval != 0) + { + perror("read(UART)"); + } #if OPENTHREAD_ENABLE_POSIX_APP_DAEMON close(sSessionSocket); sSessionSocket = -1; diff --git a/src/posix/platform/udp.cpp b/src/posix/platform/udp.cpp index 0b42ac358..53abb9233 100644 --- a/src/posix/platform/udp.cpp +++ b/src/posix/platform/udp.cpp @@ -217,8 +217,8 @@ otError otPlatUdpSocket(otUdpSocket *aUdpSocket) assert(aUdpSocket->mHandle == NULL); - fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - VerifyOrExit(fd > 0, error = OT_ERROR_FAILED); + fd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + VerifyOrExit(fd >= 0, error = OT_ERROR_FAILED); aUdpSocket->mHandle = FdToHandle(fd); diff --git a/tools/spi-hdlc-adapter/spi-hdlc-adapter.c b/tools/spi-hdlc-adapter/spi-hdlc-adapter.c index 400c39ba1..0dcb34950 100644 --- a/tools/spi-hdlc-adapter/spi-hdlc-adapter.c +++ b/tools/spi-hdlc-adapter/spi-hdlc-adapter.c @@ -1138,7 +1138,7 @@ static bool setup_spi_dev(const char *path) int ret; sSpiDevPath = path; - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) { perror("open"); @@ -1212,7 +1212,7 @@ static bool setup_res_gpio(const char *path) goto bail; } - setup_fd = open(dir_path, O_WRONLY); + setup_fd = open(dir_path, O_WRONLY | O_CLOEXEC); if (setup_fd >= 0) { @@ -1223,7 +1223,7 @@ static bool setup_res_gpio(const char *path) } } - sResGpioValueFd = open(value_path, O_WRONLY); + sResGpioValueFd = open(value_path, O_WRONLY | O_CLOEXEC); bail: @@ -1308,7 +1308,7 @@ static bool setup_int_gpio(const char *path) goto bail; } - setup_fd = open(dir_path, O_WRONLY); + setup_fd = open(dir_path, O_WRONLY | O_CLOEXEC); if (setup_fd >= 0) { @@ -1322,7 +1322,7 @@ static bool setup_int_gpio(const char *path) close(setup_fd); } - setup_fd = open(edge_path, O_WRONLY); + setup_fd = open(edge_path, O_WRONLY | O_CLOEXEC); if (setup_fd >= 0) { @@ -1339,7 +1339,7 @@ static bool setup_int_gpio(const char *path) setup_fd = -1; } - sIntGpioValueFd = open(value_path, O_RDONLY); + sIntGpioValueFd = open(value_path, O_RDONLY | O_CLOEXEC); bail: